"Node nid: title" is a bit mysterious for the random people viewing the page imo.

It'd be nice if there was a configurable way to change that; either something like linktext, and/or a global setting ie variable_get("linodef_title_node_$format","Node @nid : @title").

Comments

hefox’s picture

StatusFileSize
new2.8 KB

Patch attached

Adds a setting to filter settings

Using token module if exists to process the link title.

Defiently needs work. Added in format into a function to keep track of it due to it not existing as a parameter to any function, making adding it in a bit ugly.

Roi Danton’s picture

Status: Active » Needs work

In the next Linodef version you may set HTML attributes like title: #560042: Add option "attributes" to allow html attributes in embedded tags

However being able to alter the title for simple [#nid] tags would be useful. The approach using a variable and the token module seems fine. But the addition of the variable should happen in _linodef_find_nodesnfields() (linodef-filter.inc) where the hard coded title is added (line 264). Furthermore the patch of #1 violates a Drupal rule: using a variable for the first parameter of t(). This will cause problems with potx.

When this feature is RTBC adding a separate customizable title for terms and views might also be sufficient.

hefox’s picture

I'm on vacation ATM so don't have time (pay 4 internet hotel ftl) to repatch (which should be against dev instead, considering #560042 will effect it), however I'm confused about the second paragraph.

I think it's due to some part of the patch that I really disliked; I encountered a problem in that the filter id was never passed to the underlining functions, and would cause a lot of editing of function definations, etc., and not knowing if this feature would be desirable, reallly didn't feel like doing it at that stage. So I made a function to store the current filter id. That is why there's some extra code at the top; however, the change was done at around line 264 in that function I believe?

So before re-patch-making, I'd like your opinion on the the above issue (or, if it's been changed in dev, then that'd be nice).

Custimizable titles for terms and views sounds useful to me :).

Roi Danton’s picture

You are correct. Your patch already changes the title at the correct place. I'm sorry, I misread it yesterday.

So as you said in #3, passing $format to the filter process functions (e.g. _linodef_find_nodesnfields($nid, $options = array(), $format)) is the way of choice and linodef_filter_format() you dislike won't be needed then (actually this feature is desirable :) ).

/me wondering why I used _linodef_filter_process($text, $format) in hook_filter but didn't use the $format parameter in linodef-filter.inc. With your patch this is fixed also. :)

It would be nice if you could change this part in your code and patch it against rc3 as before.

Btw, instead of t() str_replace() or similar should be used:

However tempting it is, custom data from user input or other non-code sources should not be passed through t(). [...] Instead, translation of these data can be done through the locale system, either directly or through helper functions provided by contributed modules.

I haven't worked with the locale module yet, so I have no experience how to handle translations for admin settings textfields. However the translation of the title is secondary.

hefox’s picture

Making patches in stages;

This is against a verison with #560042: Add option "attributes" to allow html attributes in embedded tags already applied.

Below patches are only adding format to the functions.

I added as the second function argument due to it being basically required (though added it as option into the function definitions because hook_filter does).

Haven't tested much; doing step by step.

Next step is to actually re-do the patch part

Patch may have issues patching; using git and haven't made a patch before using it :(.

hefox’s picture

Version: 6.x-1.0-rc3 » 6.x-1.x-dev
StatusFileSize
new6.5 KB

Against 1.x-dev, with first http://drupal.org/node/560042#comment-2217452 (Had some issue apply the patch for that, some error about ending unexpectivally, but manually fixed it I think), then Combination patch from above applied.

Adds the settings to the filter configuration form, adds title text default to node, terms, and view links.

Anyhow, back to coughing up a storm :(.

Roi Danton’s picture

Thanks for your contribution, the patches themselves are working fine!
Unfortunately there are some glitches with token_replace(). It aborts the calling function (e.g. _linodef_find_nodesnfields()) and causing _linodef_filter_process to run again in certain/unknown circumstances. That is confusing since token_replace() doesn't load the input filter of the $node object. Also the tokens ([nid] etc) aren't replaced then. I'm still tracking down the problem, maybe the fault lies at Linodef. My code for debugging:

function _linodef_filter_process(&$body, $format = -1) {
	print('_linodef_filter_process has been called with format ' . $format . '<br />');
//
//_linodef_find_nodesnfields
				$attributes = array('title' => variable_get("linodef_node_title_$format", LINODEF_NODE_TITLE_FORMAT), 'class' => $class);
				print('Title node <b>' . $node->nid . '</b> in format <b>' . $format . '</b>: raw: <b>' . $attributes['title'] . '</b>'); // Debug
				if (module_exists('token')) {
					$attributes['title'] = token_replace($attributes['title'], 'node', $node);
				} else {
					$attributes['title'] = str_ireplace(array('[title]', '[nid]'), array($node->title, $node->nid), $attributes['title']);
				}
				print(' replaced: <b>' . $attributes['title'] . '</b><br />'); // Debug

The output (node with two textfields using Linodef tags):

_linodef_filter_process has been called with format 2
Title node 78 in format 2: raw: FULL Node [type]: [title] replaced: FULL Node artikel: Cui Gilvus Voco Adipiscing
// Here unexpected behavior starts. The second print function of the debug code above is not called (replaced:).
// So why calls token_replace() _linodef_filter_process() again? Tokens aren't replaced either now. This might help
// to track down the reason.
Title node 101 in format 2: raw: FULL Node [type]: [title]_linodef_filter_process has been called with format 2
Title node 78 in format 2: raw: FULL Node [type]: [title] replaced: FULL Node [type]: [title]
Title node 101 in format 2: raw: FULL Node [type]: [title] replaced: FULL Node [type]: [title]
_linodef_filter_process has been called with format 2
Title node 78 in format 2: raw: FULL Node [type]: [title] replaced: FULL Node [type]: [title]
Title node 101 in format 2: raw: FULL Node [type]: [title] replaced: FULL Node [type]: [title]
// Now the second print function is executed.
replaced: FULL Node artikel: Cui Gilvus Voco Adipiscing
// Now the code works as expected.
Title node 101 in format 2: raw: FULL Node [type]: [title] replaced: FULL Node artikel: Cui Gilvus Voco Adipiscing
_linodef_filter_process has been called with format 2
Title node 78 in format 2: raw: FULL Node [type]: [title] replaced: FULL Node artikel: Cui Gilvus Voco Adipiscing
Title node 101 in format 2: raw: FULL Node [type]: [title] replaced: FULL Node artikel: Cui Gilvus Voco Adipiscing

When removing token_replace() the output is as expected.

hefox’s picture

Weird; about how often does it occur? It could be due to some other module provided tokens?

I'll try to recreate, but it wasn't occuring when I was testing on a very clean install of drupal (no CCK fields, etc.).

(Hopefully it can be resolved; I love the thought of using cck field token for link title, etc. :>.)

Roi Danton’s picture

This problem appears always for me (EDIT: when using fields, see below). It is likely due to some other module, since the problem occurs when module_invoke_all('token_values', $type, $object, $options) in token_get_values() is executed. node_token_values() is fine, so I've checked the token_values hooks other modules are using. For that I modified module_invoke_all to print the used modules:

  foreach (module_implements($hook) as $module) {
    $function = $module .'_'. $hook;
		if ($hook == 'token_values') {
			print($module . '<br />');
		}

Correct output in my test installation:

Title node 78 in format 2: raw: FULL Node [type]: [title]book
comment
node
taxonomy
user
content
number
text
computed_field
filefield
pathauto
token
replaced: FULL Node artikel: Cui Gilvus Voco Adipiscing

Buggy output:

Title node 101 in format 2: raw: FULL Node [type]: [title]book
comment
node
taxonomy
user
content
_linodef_filter_process has been called with format 2
Title node 78 in format 2: raw: FULL Node [type]: [title] replaced: FULL Node [type]: [title]
Title node 101 in format 2: raw: FULL Node [type]: [title] replaced: FULL Node [type]: [title]
_linodef_filter_process has been called with format 2
Title node 78 in format 2: raw: FULL Node [type]: [title] replaced: FULL Node [type]: [title]
Title node 101 in format 2: raw: FULL Node [type]: [title] replaced: FULL Node [type]: [title]
number
text
computed_field
filefield
pathauto
token
replaced: FULL Node artikel: Cui Gilvus Voco Adipiscing

So the calling of content_token_values() causes the bug, more precisely the line content_view($node);. I've written a bug report in CCK issue queue: #651236: content_view in content_token_values shouldn't load hook_filter

Roi Danton’s picture

Though problem in #9 isn't resolved I'd like to comment the patch:
Since token doesn't support [view] I've changed it to [viewname] which is replaced by the view title in _linodef_find_view().

			// Get the view display title, required for option content and link formatting below.
			$view_title = $view->get_title() ? $view->get_title() : t('view %viewname', array('%viewname' => $view->name));
//...
			elseif ($options['content'] == 'title') {
				// Show view display title.
				$output = $view_title;
			}
//...
				$attributes = array('title' => variable_get("linodef_view_title_$format", LINODEF_VIEW_TITLE_FORMAT), 'class' => 'linodef linodef_view linodef_view_' . $view_title);
				$attributes['title'] = str_ireplace('[viewname]', $view_title, $attributes['title']);
				if (module_exists('token')) {
				  $attributes['title'] = token_replace($attributes['title']);
				}

Therefore the definition of the constants has changed slightly:

// Default link titles.
define("LINODEF_NODE_TITLE_FORMAT", t('Node') . ' [nid]: [title]');
define("LINODEF_TERM_TITLE_FORMAT", t('Shows a teaser list of nodes using term !term', array('!term' => '[cat-raw]')));
define("LINODEF_VIEW_TITLE_FORMAT", t('Show !view', array('!view' => '[viewname]')));

(providing a patch for these changes is awkard since I implemented #619166: "Override" option does not support apostrophe and other changes for the new taglists module in my local dev install - and manual editing of patches causes line bugs as you mentioned in #6 - it's about time to finish taglists and commit all this stuff so providing patches is easier for everyone :/ )

hefox’s picture

A random idea about viewname, it might be best to do an implementation of hook_token_values that provides a view name


function linodef_token_values($type, $object = NULL) {
   $values  = array();
   switch($type) {
     case 'view': 
         $values['viewname']  =$object->get_title() ? $object->get_title() : t('view %viewname', array('%viewname' => $object->name));
   }
   return $values;
}

To be consistent.

Hm, going to NY drupal camp saturday, but when I get the time I'll look into more; I think the way to fix it is to figure out why calling hook_filter in hook_filter prevents it from working. http://api.drupal.org/api/function/check_markup Perhaps it has to do with the cacheing or such. Hm

hefox’s picture

Oh, that's interesting; I can't reproduce it!

I added a formatted text field, creates 2 nodes with formatted text that uses linodef; changed node title to be the formatted text token so I know it's being called; I even have it linking to itself, which somehow does not cause an infinite loop.

Here's one of the test nodes http://dev.foxinbox.org/content/dfvdfg-dfvdfg-dfvdfg-dfvdfg-dfvdfg-dfvdf... (what, me copy and pasting? never!).

Roi Danton’s picture

Oh, that's interesting; I can't reproduce it!

Could you insert the print() functions used in comment #7 in your code, please? So I can see the output at your copy & paste site. ;) However the filter result is as expected (also on my test site) so the user won't actually see this multiple calling of hook_filter. Though it can cause a duplicate appearance of Linedef info/warning/error messages. I'm not sure since the behavior of hook_filter used by cck token values seems to be different (or it is caused due to the execution inside a filter as you said). This would be nice to know.
EDIT: Nevermind, the recursion check for content_view() in token_get_values() seems to be the reason for the different behavior of token_replace in hook_filter called by CCK.

I even have it linking to itself, which somehow does not cause an infinite loop.

Linodef removes its own tags when embedding fields with Linodef tags. See this comment. Later I've introduced linodef_removetags() in main module file.

Roi Danton’s picture

Indeed, Linodef messages are duplicated when using token_replace with fields since the complete filter process is run again. Therefore I hesitate to use token_replace() as a default method for title substitution (it will also cause a serious performance hit when using many filters or Linodef tags). Avoiding the duplication as in token_get_values() (with static $running) doesn't seem to work since the filter has to run multiple times when having several nodes on a page. Also the filter doesn't know what function calls it. What a pity! Maybe you have an idea?

hefox’s picture

Therefore I hesitate to use token_replace() as a default method for title substitution

When looking into tokens a bit more, I was actually thinking the same thing.

I think what is most ideal would be to have checkboxes to enable tokens support on filters. Ie, instead of the three defaults, it'd be 3 defaults + 3 checkboxes for each, and tokens will only be run if they're enabled to run, with the default just being the 'simple' replacements ([nid], [title], category, etc.).

So nodenfields will look like this

                if (module_exists('token')  && !empty(variable_get("linodef_node_token_enable_$format", 0))) {
                    $attributes['title'] = token_replace($attributes['title'], 'node', $node);
                } else {
                    $attributes['title'] = str_ireplace(array('[title]', '[nid]'), array($node->title, $node->nid), $attributes['title']);
                }

Only reason I didn't bring it up earleir because I don't really want to re-roll the patches again (Random lazyness, dealing with revisions numbers, sigh!) and would prefer to provide a patch after the current ones are commited, :<.

Avoiding the duplication as in token_get_values() (with static $running) doesn't seem to work since the filter has to run multiple times when having several nodes on a page. Also the filter doesn't know what function calls it

hm, $running won't work.. lemme play

					$buildmode = (arg(0) == 'node' && is_numeric(arg(1))) ? 'full' : 'teaser';
					define("LINODEF_BUILDMODE", $buildmode);

					module_load_include('inc', 'linodef', '/includes/linodef-filter');
					return _linodef_filter_process($text, $format);
      static $running;
    if (empty($running)) {
      $running = 1 ; 
					$buildmode = (arg(0) == 'node' && is_numeric(arg(1))) ? 'full' : 'teaser'; // not sure how you're using this, but this is going to have issues for full node views, but alas, not much can be done about that
					define("LINODEF_BUILDMODE", $buildmode);

					module_load_include('inc', 'linodef', '/includes/linodef-filter');
					$text = _linodef_filter_process($text, $format);
     $running = 0;
     return $text; 
    } else {
     // do the remove tags from input instead of any replacements, the remove function then return $text;
   }

The issue is that it needs to run the filter correctly on formatted text fields, correct?
Perhaps, though I'd hate to do it, running function ><

functiong linodef_running($in_running = NULL) {
   static $running;
   if (isset($in_running)) $running = $in_running; 
   return $running;
}

    if (!linodef_running()) {
      linodef_running(1);
					$buildmode = (arg(0) == 'node' && is_numeric(arg(1))) ? 'full' : 'teaser'; // not sure how you're using this, but this is going to have issues for full node views, but alas, not much can be done about that
					define("LINODEF_BUILDMODE", $buildmode);

					module_load_include('inc', 'linodef', '/includes/linodef-filter');
					$text = _linodef_filter_process($text, $format);
     linodef_running(0);
     return $text; 
    } else {
     // do the remove tags from input instead of any replacements, the remove function then return $text;
   }

and then where textfields are processed unset the running then reset after, but that seems complicated..

ooorr, put running around the token calls themselves.


static $running
if (module_exists('token') && empty($running)) {
   $running = 1;
	  $attributes['title'] = token_replace($attributes['title'], 'node', $node);
   $running = 0; 
} else {
  //yadda
}

if ($running) {
  // str_replace anything with [%] as potentially a unfulfilled token
}

And warn people that there is some limitation to token usage due to the potentional for recursion

Roi Danton’s picture

I'll be off for the weekend and the plane doesn't wait so just a short reply.

Thanks for the testing of the running variant. This make things complicated while it does not provide help: It should avoid problems with textfields with input filters - but we have to unset the running var as you proposed when using these textfields - otherwise token_replace would have no effect either.

But besides making token_replace() optional and warn the admin (in form description) about its flaws we could use the objects (node/term/view) we already have at hand and provide own token-like replacements (without token module). I.e. expanding $attributes['title'] = str_ireplace(array('[title]', '[nid]'), array($node->title, $node->nid), $attributes['title']); to all the object properties that are available. I don't know if this would fulfill your needs as token does?

Btw, thanks for updating your dev site. The output is the same as at my test installation. That I wanted to ensure. :)

hefox’s picture

I suspect manually doing tokens will get more complex then needed. For example, I'd be likely wanting to use a teaser field (not the one created by drupal manually, a cck text field)

What do you think about combing the last 2 and the first of number 15?

functiong linodef_token_running($in_running = NULL) {
   static $running;
   if (isset($in_running)) $running = $in_running;
   return $running;
}


static $running
if (module_exists('token') &&  !empty(variable_get("linodef_node_token_enable_$format", 0)) {
   if (linodef_token_running()) { // arround term, node, and view token_replaces. 
       preg_replace('\[.*]\','',$attributes['title']);
   } else {
       linodef_token_running(1);
      $attributes['title'] = token_replace($attributes['title'], 'node', $node);
       linodef_token_running(0);
   }
} else {
  //yadda
}

Roi Danton’s picture

Component: Code (general) » Filter

I've committed your proposals and added a few tokens usable without the tokens module. Just the usage of static $running is lacking completely. I'd like if you could provide a patch against the updated dev release.

@#11: Linodef shouldn't add tokens related to other modules (views).

hefox’s picture

StatusFileSize
new2.31 KB

cool =)

Here's the patch as said in #17,
here's it with the test statements: http://dev.foxinbox.org/content/dfvdfg-dfvdfg-dfvdfg-dfvdfg-dfvdfg-dfvdf...
alterntly, output of the test statements

_linodef_filter_process has been called with format 1
Title node 3 in format 1: raw: Node [nid]: [title]_linodef_filter_process has been called with format 1
Title node 2 in format 1: raw: Node [nid]: [title] replaced: Node :
replaced: Node 3: dfsvdf
Title node 4 in format 1: raw: Node [nid]: [title]_linodef_filter_process has been called with format 1
Title node 3 in format 1: raw: Node [nid]: [title] replaced: Node :
replaced: Node 4: dfvdfg dfvdfg dfvdfg dfvdfg dfvdfg dfvdfg dfvdfg dfvdfg dfvdfg dfvdfg dfvdfg dfvdfg dfvdfg
_linodef_filter_process has been called with format 1
Title node 3 in format 1: raw: Node [nid]: [title] replaced: Node 3: dfsvdf

Also corrects a small copy and paste bug token_replace($attributes['title'], 'node', $node); was being used for terms :P.

Roi Danton’s picture

Status: Needs work » Needs review
StatusFileSize
new8.16 KB

I've edited your patch from #19 so it also prevents duplicated messages and the static running could be used for other processes, too (if needed in future). Please review for copy & paste accidents. ;)

Additionally to take those 'title' and 'class' attributes in consideration that are defined by option 'attributes' I've made a few minor changes that are not related directly to this issue (but clutter the patch, sorry).

@#15:

$buildmode = (arg(0) == 'node' && is_numeric(arg(1))) ? 'full' : 'teaser'; "not sure how you're using this, but this is going to have issues for full node views, but alas, not much can be done about that"

This is used when processing the options 'content' and 'formatter'. Actually you are right and I'd like to have a better solution for Drupal6 that heeds views/panels but don't know of it yet.

Roi Danton’s picture

Status: Needs review » Fixed

Committed to D6 branch. Thx for your contribution!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.