i'm trying to use the "output this field as a link" feature in 2.3, but the generated links are getting escaped and appended to the current page's url, so they don't work.

e.g. if i manually type in the anchor and markup (without using the output-as-link feature),

http://example.com/community/blog/21

i get a working link, but if i try to do the equivalent using this feature, the link is broken:

http://example.com/community/blog/%3Cp%3E%3Ca%20href%3D%22/community/blo...’s%20Blog%3C/a%3E%3C/p%3E

the first output is from the uid field, the second is from the "nothing" field (general text) -- they're both toward the bottom here:

<?php
$view = new view;
$view->name = 'author';
$view->description = 'Author info for the current node.';
$view->tag = '';
$view->view_php = '';
$view->base_table = 'users';
$view->is_cacheable = FALSE;
$view->api_version = 2;
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
$handler = $view->new_display('default', 'Defaults', 'default');
$handler->override_option('fields', array(
  'picture' => array(
    'label' => '',
    'exclude' => 0,
    'id' => 'picture',
    'table' => 'users',
    'field' => 'picture',
    'relationship' => 'none',
  ),
  'name' => array(
    'label' => 'Name',
    'link_to_user' => 1,
    'exclude' => 0,
    'id' => 'name',
    'table' => 'users',
    'field' => 'name',
    'relationship' => 'none',
  ),
  'value' => array(
    'label' => 'Location',
    'exclude' => 0,
    'id' => 'value',
    'table' => 'profile_values_profile_location',
    'field' => 'value',
    'relationship' => 'none',
  ),
  'uid' => array(
    'label' => 'Uid',
    'link_to_user' => 0,
    'exclude' => 1,
    'id' => 'uid',
    'table' => 'users',
    'field' => 'uid',
    'relationship' => 'none',
  ),
));
$handler->override_option('arguments', array(
  'uid' => array(
    'default_action' => 'default',
    'style_plugin' => 'default_summary',
    'style_options' => array(),
    'wildcard' => 'all',
    'wildcard_substitution' => 'All',
    'title' => '',
    'default_argument_type' => 'user',
    'default_argument' => '',
    'validate_type' => 'none',
    'validate_fail' => 'not found',
    'break_phrase' => 0,
    'not' => 0,
    'id' => 'uid',
    'table' => 'users',
    'field' => 'uid',
    'relationship' => 'none',
    'default_options_div_prefix' => '',
    'default_argument_user' => 1,
    'default_argument_fixed' => '',
    'default_argument_php' => '',
    'validate_argument_node_type' => array(
      'blog' => 0,
      'image' => 0,
      'forum' => 0,
      'article' => 0,
      'coverage' => 0,
      'event' => 0,
      'glossary' => 0,
      'page' => 0,
      'project_blog' => 0,
      'release' => 0,
    ),
    'validate_argument_node_access' => 0,
    'validate_argument_nid_type' => 'nid',
    'validate_argument_vocabulary' => array(
      '5' => 0,
      '7' => 0,
      '1' => 0,
      '2' => 0,
      '6' => 0,
    ),
    'validate_argument_type' => 'tid',
    'validate_argument_node_flag_name' => '*relationship*',
    'validate_argument_node_flag_test' => 'flaggable',
    'validate_argument_node_flag_id_type' => 'id',
    'validate_argument_user_flag_name' => '*relationship*',
    'validate_argument_user_flag_test' => 'flaggable',
    'validate_argument_user_flag_id_type' => 'id',
    'validate_argument_php' => '',
  ),
));
$handler->override_option('filters', array(
  'uid' => array(
    'operator' => 'not in',
    'value' => array(
      '0' => '1',
    ),
    'group' => '0',
    'exposed' => FALSE,
    'expose' => array(
      'operator' => FALSE,
      'label' => '',
    ),
    'id' => 'uid',
    'table' => 'users',
    'field' => 'uid',
    'relationship' => 'none',
  ),
));
$handler->override_option('access', array(
  'type' => 'none',
));
$handler->override_option('title', 'Author Info');
$handler->override_option('footer_format', '4');
$handler->override_option('footer_empty', 0);
$handler = $view->new_display('block', 'Post info', 'block_1');
$handler->override_option('block_description', 'Author Info');
$handler->override_option('block_caching', -1);
$handler = $view->new_display('block', 'Profile', 'block_2');
$handler->override_option('fields', array(
  'name' => array(
    'label' => '',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'html' => 0,
    ),
    'link_to_user' => 0,
    'overwrite_anonymous' => 0,
    'anonymous_text' => '',
    'exclude' => 1,
    'id' => 'name',
    'table' => 'users',
    'field' => 'name',
    'override' => array(
      'button' => 'Use default',
    ),
    'relationship' => 'none',
  ),
  'picture' => array(
    'label' => '',
    'exclude' => 0,
    'id' => 'picture',
    'table' => 'users',
    'field' => 'picture',
    'relationship' => 'none',
  ),
  'uid' => array(
    'label' => '',
    'alter' => array(
      'alter_text' => 1,
      'text' => '<p><a href="/community/blog/[uid]">[name]’s Blog</a></p>',
      'make_link' => 0,
      'path' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'html' => 0,
    ),
    'link_to_user' => 0,
    'exclude' => 0,
    'id' => 'uid',
    'table' => 'users',
    'field' => 'uid',
    'relationship' => 'none',
    'override' => array(
      'button' => 'Use default',
    ),
  ),
  'nothing' => array(
    'label' => '',
    'alter' => array(
      'text' => '[name]’s Blog',
      'make_link' => 1,
      'path' => 'community/blog/[uid]',
      'alt' => '',
      'prefix' => '<p>',
      'suffix' => '</p>',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'html' => 0,
    ),
    'exclude' => 0,
    'id' => 'nothing',
    'table' => 'views',
    'field' => 'nothing',
    'override' => array(
      'button' => 'Use default',
    ),
    'relationship' => 'none',
  ),
));
$handler->override_option('title', '');
$handler->override_option('distinct', 1);
$handler->override_option('block_description', '');
$handler->override_option('block_caching', -1);
?>

Comments

merlinofchaos’s picture

You should try using the 'make link' setting instead.

merlinofchaos’s picture

Oh wait, misread. Sorry, my eyes are tired. Trying again.

deshilachado’s picture

See a similar issue here: #375774: "Output this field as a link" adds markup in the link

Could you try if it works with absoulte links instead of relative links?
http://example.com/community/blog/[uid]
instead of
community/blog/[uid] ?
I'm not too sure about it, but it should be easy to test out, so you can write what happened.

As far as I know, the link will be produced in
funtion render_as_link in line 455 of views/handlers/views_handler_field.inc
This function sends the path to l() in line 487

deshilachado’s picture

just a guess:
you could try to alter the line
'html' => 0,
to
'html' => 1,
and then re-import the view
(i believe this is altered in the render_as_link function anyway)

jdlind38’s picture

subscribing

markabur’s picture

not sure what happened but for the life of me i can't reproduce this any more. if it happens again i'll troubleshoot a bit better and then post back.

fission6’s picture

I did some research into the problem last night since I myself was facing it. I do not have the views module code on hand but I observed that when a token (replacement pattern) was used in both the "Link" field as well as the "Text" field for the Custom Text Field Type that the link would not encounter the issue described in this tickets. This could explain why mark12b eventually got around his issue unknowing.

I reviewed the code and indeed get_token() (some method like that) is called for 'arguments' and then later for 'fields' if !isset($tokens). So when I have the scenario described above and the token I want to use in my 'Link' field has been populated from the get_token() from the argument in advanced_render() the issue is naturally avoided.

Therefore somewhere in the code for rendering 'fields' when display link is on, is looping through the tokens and most likely adding l($token) and then returning this string to the view_handler_field.

Sorry if this is a choppy explanation, I currently do not have access to the bits of code from view_handler_field, etc...

deshilachado’s picture

Well then, if I understood you right, it might also help to rearrange the fields?

tamanna-freelancer’s picture

I found the solution.
For your problem,mark12b first u have selected the title which is markb's blog and then u used this title through custom text field to be a display text.
When u first used the title,I think it is linked to its node.If you untick that option this problem will be gone.
Hope I have been able to explain wht I was trying to say.

http://www.itvidya.com

markabur’s picture

Category: bug » feature

yes, that's it -- one of the fields i was using as a token replacement (nid) had "link this field to its node" set.

not sure i would call this a bug anymore, though i can imagine it's a situation that could be coded around (when a field is used as a token replacement, don't link it to its field, regardless of its "link this field to its node" setting). so, "feature request"?

fission6’s picture

I added a strip tag for the path string as a reasonable fix for this issue within the view_handler_field.inc:

function render_as_link($text, $tokens) {
    // $path will be run through check_url() by l() so we do not need to
    // sanitize it ourselves.
      
    $path = $this->options['alter']['path'];
    
    $path = strtr($path, $tokens);

    // Make all tokens non-links
    // Strip out HTML in Tokens
    $path = strip_tags($path);

    $alt = $this->options['alter']['alt'];
    $alt = strtr($alt, $tokens);

    $value = '';

    if (!empty($this->options['alter']['prefix'])) {
      $value .= filter_xss_admin($this->options['alter']['prefix']);
    }

    $options = array(
      'html' => 'true',
    );

    if ($alt) {
      $options['attributes']['title'] = $alt;
      $options['attributes']['alt'] = $alt;
    }

    // These can only be set internally at this time.
    if (isset($this->options['alter']['query'])) {
      $options['query'] = $this->options['alter']['query'];
    }
    if (isset($this->options['alter']['fragment'])) {
      $options['fragment'] = $this->options['alter']['fragment'];
    }

    $value .= l($text, $path, $options);

    if (!empty($this->options['alter']['suffix'])) {
      $value .= filter_xss_admin($this->options['alter']['suffix']);
    }

    return $value;
  }

Edit: added PHP tags to make more readable.

kobee’s picture

Ok, now it works. Thanks.

Can it will be added in the next release?

dawehner’s picture

Status: Active » Needs work

@fission6 could you please create a patch
if you need introductions search for cvs in the handbooks

merlinofchaos’s picture

Status: Needs work » Fixed

The strip tags was easy so I put that in while working on another part of this code.

Thanks!

margaridacarvalho’s picture

Does the strip tags work for cck custom text field (output as link) too?
I'm having a similar problem (posted here: http://drupal.org/node/428720), when i add a global field (custom text), output this field as a link and in link path I use a replacement pattern such as [field_filename_fid], it outputs a link but it goes to an 404 page not found error page.
I think that I have a problem like the one in this post or i'm using the replacement patterns wrong...can someone help me?

Coornail’s picture

Status: Fixed » Active

I'm building a gallery. There are 2 node types:
One view renders the gallery by ?nid=xxx at the end of the url.
The other view Shows the first image of the gallery. I was tried to link the preview image to the gallery render view, that's how I got here.

I tried the code above, but it didn't helped. As I debugged I figured that the url() function returns badly formatted url to the l() function.

I couldn't figure out a solution yet, but I haven't given up.

thekevinday’s picture

StatusFileSize
new5.32 KB

For the record, I was needing this to be fixed so I could use this: http://drupal.org/project/prepopulate

The problem is the l() function within render_as_link() function.

This line:
$value .= l($text, $path, $options);

Inside the function l() (http://api.drupal.org/api/function/l/6), there is the following function call:

    return '<a href="'. check_url(url($path, $options)) .'"'. drupal_attributes($options['attributes']) .'>'. ($options['html'] ? $text : check_plain($text)) .'</a>'

or more specifically:

   check_url(url($path, $options))

The url() function (http://api.drupal.org/api/function/url/6) inside of l() is where the trail continues:

  $path = drupal_urlencode($prefix . $path);

Looking at: http://api.drupal.org/api/function/drupal_urlencode/6
I can see that the following function is used: http://us.php.net/rawurlencode

This rawurlencode() php function is the cause of this problem.

My workaround solution was to copy & create internal versions of l() and url() so that the code $path = drupal_urlencode($prefix . $path); can be removed.
My supplied patch is supplied as a work-around for those who cannot wait for the proper fix and as a proof of concept.

Summing this up, the l() function apparently cannot be used for a url because of the rawurlencode() function as it seems to break valid urls.

kassissieh’s picture

When I updated to Views 6.x-2.5, it stopped adding paragraph tags to the taxonomy term description I am using in a rewrite link setting. Many thanks for this improvement! However, Views still appends %0A (newline) to the end of each term, breaking the link.

Link Path: athletics/schedules/[description]

Result: athletics/schedules/Boys%20Varsity%20Soccer%0A

Tim Chan’s picture

RE: #17
Thank you, your patch works for me.

Frico’s picture

Thanks, that solved the problem for me :)

merlinofchaos’s picture

Status: Active » Closed (duplicate)

I think http://drupal.org/node/482162 might address the same problem with a cleaner patch.

snorkers’s picture

Category: feature » bug

I've just come across a problem, which looks related to this thread, using Views 2.x DEV (05 Jun 2009).
When using a token replacement to generate a URL (eg a URL field to turn a Node title into a hyperlink), my URL effectively goes from an absolute to non-existent relative address, with an escaped LF either side of the URL that I was hoping for. eg, I want the URL to my node title to link to http://www.cnn.com, but what actually gets generated for the node title URL is http://example.com/%0A%20%20http%3A/%252Fwww.cnn.com/%0A%0A. Bit of an escape-fest all round.

Haven't been able to run the patch yet at #17.

Tried the patch at discussed at #21. Error still present.

snorkers’s picture

Version: 6.x-2.3 » 6.x-2.x-dev

Forgot to say... tried an archived site of my current project which uses View 2.x DEV (Apr 22) and the problem is not there, so this has only crept back in in the past 2 weeks I think.

alienzed’s picture

is there a definitive fix for this? or is it really multiple issues all wrapped up in one?

alienzed’s picture

Maybe unrelated, maybe not. I JUST noticed after weeks of randomly having this problem that turning THEME DEVELOPER, part of the devel package, on and off, also makes a similar problem with the basepath being appended appear and disappear.

So if you are experiencing this problem, make sure you don't have theme developper enabled.

elmiguel’s picture

subscribing

rhaft’s picture

Wow - just spent a lot of time tracking down why an image where I specified to output as a link resulted in malformed paths. At first I thought it was just extra %0A and space values, but I eventually discovered that the Devel module was generating a span around the field value! So, if you are experiencing link problems in Views, make sure that Devel is off before spending a lot of time debugging the Views code!

kid_baco’s picture

Thanks for posting this! Luckily I only wasted an hour before finding this comment. Turned of Devel and works fine.

pineray’s picture

When the path contains spaces (e.g. filename), rendered link doesn't work.
Character entity reference '%20' for a space in the path is altered into '0'.
Perhaps it is caused by replacement token '%2'.

biteuljiouce’s picture

@alienzed
many thanks :)
got a similar pb and turning off "Theme developer" made it work.

i'm using :
output this field as a link with a replacement patterns
and got strange '%0A ' in the URL
http://dev.mysite.com/%0A sites/default/files/myfolder/myanim.swf

with
Views 6.x-2.10
Theme developer 6.x-1.x-dev
Drupal 6.16

digidev’s picture

Title: output this field as a link is unnecessarily escaped » Solved

@alienized:
Thanks, this did the trick for me! Already the second time Theme Developer is doing this to me :(

markabur’s picture

Title: Solved » "Output this field as a link" is unnecessarily escaped

Let's keep a descriptive issue title on this, even if it is figured out.