Is that possible to do alink in CCK field also?

Thank you,

CommentFileSizeAuthor
#20 scan_CCK-144953-20.patch1.42 KBAnonymous (not verified)
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tic2000’s picture

Maybe, after I implement all the other features I want to implement. But for now I wouldn't count on it.

abx’s picture

I'll wait for that :)

NikLP’s picture

abx, have a look at what I've written here, and voice your support if you like.

http://drupal.org/node/144565

NikLP’s picture

abx, have a look at what I've written here, and voice your support if you like.

http://drupal.org/node/144565

d.sibaud’s picture

Version: 5.x-1.3-2 » 5.x-1.4-3

+1 subscription for this very useful feature, hope to see it soon ;-)

vstmusic’s picture

+1 for the 6.x version of alinks !

cssd’s picture

I have a solution for Drupal 6.x (which may be applicable to 5.x?) - I think... that allows any CCK field with a field type of 'text' to be included in the areas that are searched - to insert links into.

alinks.module modified to change the 'alinks_nodeapi' function as follows;

/**
* Implementation of hook_nodeapi().
*/
function alinks_nodeapi(&$node, $op, $teaser, $page) {
  
  switch ($op) {
    case 'view':
    	
      $node_types = in_array($node->type, variable_get('alinks_node_types', array()), TRUE);
      
      if ($node_types) {
        drupal_add_css(drupal_get_path('module', 'alinks').'/alinks.css');
        $words = alinks_get_strings();
       
        if ($words) {
        	
          $node->content['body']['#value'] = alinks_make_links($node->content['body']['#value'], $words);

/**
*  find CCK fields (prefix of 'field_') where format == 2 (text fields) and make links on the value of the field
*/
	    $cck_fields = get_object_vars($node);
		foreach (array_keys($cck_fields) as $cck_field){
		  if (substr($cck_field,0,6) == "field_" && $node->{$cck_field}[0]['format'] == 2){

	          $node->{$cck_field}[0]['value'] = alinks_make_links($node->{$cck_field}[0]['value'], $words);
		  }
		}

	    }
      }
      break;
  }
}

It is dependent upon the fieldnames being prefixed with 'field_' - which is the way with CCK as far as I can gather.

The only thing I am not sure about is whether the 'format' == 2 will always equate to 'text' field types or if this is dependent upon the installation/configuration of the CCK module.

Perhaps others can give feedback regarding this...?

Hope it is useful.

edgoss’s picture

Version: 5.x-1.4-3 » 6.x-1.0-rc1

Thanks for trying to implement a fix for this, but it doesn't work on my site yet.

This could be the 'format' == 2 issue you mentioned above. Having said that I did change the value from 1 - 7 and none of the changes worked. Would be nice to get this working as it would be a great money maker for my site!

Thanks

bramface’s picture

This patch worked for me. Thank you!

-Bram Moreinis
http://gamefacewebdesign.com

FrancoisL’s picture

Hi thanks for this patch,

It's globally works for me but I noticed something that seems to be a bug. When you have a link in the first words of a text, the text disappear. This is true for cck fields but not for basic body text.

Hope that can help :)

François

lape’s picture

When using the alinks_get_links() function for custom string replacements (e.g. CCK fields or node body output from a Views field view), be aware that alinks looks for text outside HTML tags:

// we get all the text that is not inside a html tag
// from the modified text
preg_match_all('/\>(.*?)\</', $body, $output);

So if there is pure text without tags, nothing is replaced. This can be fixed by wrapping some HTML tag around your text.

Bricks and Clicks Marketing’s picture

Can this be adapted for use with a product SKU in Ubercart? I have a need for it and can pay for the help. Thanks!

Bricks and Clicks Marketing’s picture

*bump*

Client is willing to pay for adapting this for the Ubercart SKU field. It shouldn't be too hard, no, if it's already been done for CCK fields?

endiku’s picture

'format' = 2 is the Input Format for the node in question. In a vanilla drupal that equates to the second format choice "Full HTML". So while 'format'=2 will work if the node is using full html it won't work on any other input choices. So not a good solution in the end. I figure the best thing to do is take the value from $node->{$cck_field}[0]['format'] and check it against the types of filters you wouldn't want competing with Alinks. Maybe there is a quicker approach to this.

I'm actually using Full HTML as my input choice so the CCK fix works great. Thanks!

Branndon’s picture

I'm also using full html as my input format, but am not seeing the alinks in the cck fields. I am using text field as the cck field type. I copied that code above and replaced the corresponding code in the alinks.module file, then cleared my cache, no luck. Anyone have pointers to get me going?

I've even changed this
['format'] == 2

to this

['format'] != 9

just to try various formats, and it didn't work.

Stephen Scholtz’s picture

Is the format value really that important? Even if it's a input format that doesn't support HTML or allow for anchor tags, you still want these anchors showing up in your content because...well, that's what the module is supposed to do, right? :)

However, the original coded posted in #7 was using the ['format'] check to make sure they were operating on text areas. ['format'] doesn't say "I'm a textarea", it's just a variable that happens to be present in a CCK text area datatype.

This works alright, but it's not a guarantee that you're dealing with a text area, and it also means this won't work on non-text area CCK data types (like a single line text field).

I think this is better...we use CCK's content_fields() function to load information about the field, and see if it's a text area, then operate on it.


/**
* Implementation of hook_nodeapi().
*/
function alinks_nodeapi(&$node, $op, $teaser, $page) {
  
    switch ($op) {
    case 'view':
    	
      $node_types = in_array($node->type, variable_get('alinks_node_types', array()), TRUE);
      
      if ($node_types) {
        drupal_add_css(drupal_get_path('module', 'alinks').'/alinks.css');
        $words = alinks_get_strings();

        if ($words) {
      	  $node->content['body']['#value'] = alinks_make_links($node->content['body']['#value'], $words);
	
          /*** New code ***/
          if (module_exists("content")) {
            // Turn the node into an array that we can loop over, as in the original
            $cck_fields = get_object_vars($node);
            foreach (array_keys($cck_fields) as $cck_field) {
              // Check if we're dealing with a CCK field...
              if (substr($cck_field,0,6) == "field_") {
                // Load data about the field
                $field_data = content_fields($cck_field);
                if ($field_data["type"] == "text" && $field_data["widget"]["type"] == "text_textarea") {
                  $node->{$cck_field}[0]['value'] = alinks_make_links($node->{$cck_field}[0]['value'], $words);
                }
              }
            }
          }
          /*** End new code ***/

        }
      }
      break;
  }
}


The above code will only operate on the text data type, and only on ones using the text area widget. If you wanted it to work on every text datatype, you'd remove the ["widget"]["type"] check.

I think for most users, that would satisfy most of the needs, so I dunno if there needs to be an admin panel where you would configure something here, like turning it on for single text fields or not. Thoughts?

I was using the following when I wrote the above:
Drupal 6.16
CCK 2.7
Alinks RC1

Branndon’s picture

Thanks for the code, I removed " && $field_data["widget"]["type"] == "text_textarea"" and it still didn't work for me. I don't have a textarea I have a text field. Anyway thanks for the help. I am using glossify until I get this working.

Stephen Scholtz’s picture

As for it not working with textfields, you're right, I forgot about #11 above. The function that does the replacing (alinks_make_links()) it looking for text that is contained inside of some HTML tags. Since CCK text fields have no HTML in them (generally), then the ALinks replacer code won't catch 'em.

A hacky solution might be to do this:

        if ($words) {
      	  $node->content['body']['#value'] = alinks_make_links($node->content['body']['#value'], $words);
	
          if (module_exists("content")) {
            // Turn the node into an array that we can loop over, as in the original
            $cck_fields = get_object_vars($node);
            foreach (array_keys($cck_fields) as $cck_field) {
              // Check if we're dealing with a CCK field...
              if (substr($cck_field,0,6) == "field_") {
                // Load data about the field
                $field_data = content_fields($cck_field);
                /*** Revised stuff ***/
                if ($field_data["type"] == "text") {
                  if ($field_data["widget"]["type"] == "text_textfield") {
                    // Wrap the plain textfield in a <span> so it's parsed by alinks_make_links() correctly
                    $node->{$cck_field}[0]['value'] = alinks_make_links("<span>" . $node->{$cck_field}[0]['value'] . "</span>", $words);
                  } else {
                    $node->{$cck_field}[0]['value'] = alinks_make_links($node->{$cck_field}[0]['value'], $words);
                  }
                }
                /*** Revised new stuff ***/
              }
            }
          }

        }

That will make the text in your text field qualify for replacement by Alinks. 'Course, the text is now wrapped in a tag, but hopefully that doesn't screw your theme/CSS up.

However, this solution breaks down depending on how you're themeing things.

  • If you're spitting out your text field with content_format(), then the output will have all the HTML in it escaped (ie. spit out as plain text). I think is probably 'cuz CCK's formatter is sanitizing the text field, running it through check_plain or something.
  • If you're just using $content, then the CCK fields will be unaffected by ALinks, regardless of what you do.
  • If you're using the new $field_fieldName_rendered variable, it too will be unaffected.

You'll have to use $node->field_fieldName[0]["value"], which I understand is bad practice. It seems clear that the makers of CCK were not expecting any HTML in their text fields, so maybe we shouldn't be creating code that effects those fields in that way? :P

---

Another thing I noticed is that while the above code will modify the individual CCK fields, it won't modify the occurrences of the CCK fields in the default node body (ie. the $content variable). So "out of the box", the above code will do nothing for users unless they're using a custom theme that is rendering individual CCK fields.

Thinking out loud: I'm wondering if ALinks should be doing its thing later on in the nodeapi chain of events? If I'm reading the hook_nodeapi documentation correctly, the "alter" operation is where text substitution and filtering should be done, and ALinks is basically a filter. (Glossify uses the "alter" operation to do its thing) Also, during the "alter" operation, CCK has had a chance to insert it's content into the $node->body (from which $content is built), so having ALinks do it's thing on $node->body during the alter operation will also replace the contents of the CCK fields. 'Course, it does this regardless of field type...this could screw up non-text field types like Location CCK, which isn't a "text" type but have text as its final output...so...bad idea I think?

I'm not sure what to recommend. If you use content_format() in your theme and you only want text areas affected by Alinks, then the above code will work fine. If you want your text fields affected as well, then you'll need to spit out those fields differently in the theme. If you want ALinks to work with CCK "out of the box" with any generic theme, we don't have a solution right now.

I looked through the Glossify issue cue and seems like there's a similar conversation going on there too.

Which ever way the module developer (chinajason?) decides, I suspect that some kind of admin panel will be required to manage which CCK fields should be affected by ALinks, and some recommendations/guidelines put in place for themers if they want to use this module, plus some tricky code that will do its thing on the $content/$node->body and only effect the CCK fields specified (look into the simplehtmldom API module that Glossify uses?). Either that or ALinks needs to be repurposed into an input filter instead of something that operates on the node object.

Ugh, I have a headache. :P

PS - BTW, does Glossify do what you want it to do? When I tried it out, it looked like you had to create a node that had titles that were the same as the keywords you wanted linked. So if I wanted "home" to be a keyword link, I'd have to create a node called "home". And if I wanted that link to go to another page, I'd have to create a CCK field on that new node, and enter the URL I want it to go to. Seems like a lot of overhead, and tough to manage, compared to ALinks. Made sense for a glossary application, but not much sense for a blog, where the title (ex. "10 things to look for when buying a home") is often different than the keyword you want to be a link (ex. "house"). Unless I missed something, ALinks is more light-weight and easier to manage.

PPS - there was also an error in my original code in #16, which I edited. It shouldn't have been module_exists("cck"), but module_exists("content") instead.

Stephen Scholtz’s picture

K, just did a little more thinking about this 'cuz it's bugging me.

If CCK installed...

  1. During the "View" operation, alter CCK fields ($node->field_fieldName["value"]). Optionally only alter the ones specified by an admin panel. This will add ALinks which content_format() can use in the template files. $node->content['body']['#value'] is parsed and ALinks added.
  2. During the "Alter" operation, parse $node->body and add in ALinks. Body will already have ALinks applied (see above). Optionally only apply ALinks to the CCK fields specified (requires careful HTML parsing of CCK's generated HTML code for the fields, as well as counting up of any ALinks already added in step 1)

To think about: figure out how $field_fieldName_rendered variables are generated so they can be modified by ALinks as well? Or instead, implement ALinks as an input filter, and is only used on text areas.

If CCK not installed, the module just does what it's already doing.

Anonymous’s picture

FileSize
1.42 KB

Code in #18 in patch format.

Anonymous’s picture

Status: Active » Needs review
Greg Boggs’s picture

Issue summary: View changes
Greg Boggs’s picture

I just tried this on simplytest.me with #20 and a cck text field and it did not work.

Greg Boggs’s picture

Status: Needs review » Needs work
FrancoisL’s picture

Hello,

I saw that patches are for Drupal 6. Is anyone tired this on Drupal 7? I tried on my side but it broke the web site.

Greg Boggs’s picture

The work for this feature in D7 has been continued here: https://www.drupal.org/node/2493601