Be careful with Views Custom Field
I was tearing my hair out over mysterious bugs in my recent Drupal project. Our complex views pages, which used Views custom field extensively, were constantly breaking. The php field output could break when new CCK field was added to some node type, or some value was selected in views exposed filters.
The code of my phpfields was very simple, something like this:
<?php
if ($data->field_node_status_value > 2) {
echo l("Some action", 'test/url');
}
?>I’ve spent several hours debugging the problem. When examining views generated sql queries, I noticed that field alias of 1 specific field can be different under certain conditions. So, instead of $data->field_node_status_value it could be $data->field_delivery_node_status_value. This information helped me to find related issue thread: http://drupal.org/node/701798
It was so surprising to know that you can’t rely on $data variable when using php field! Views renames field names all the time (when new field was added to views output, when new field was added to CCK node type, when exposed filter is active, etc, etc), and you simply can’t use this raw data! (And that is the intended behavior of Views, merlinofchaos says: http://drupal.org/node/361756 )
I’ve solved the problem by moving all my PHP code from views custom field to views templates, located in my theme:
<?php
$status = $row->{$view->field['field_node_status_value']->field_alias};
if ($status > 2) {
echo l("Some action", 'test/url');
}
?>I think this problem should be highlighted with yellow background on Views Custom Field module page, but it’s not even mentioned there.
Anton Sidashin
I'm a web developer specializing in PHP and Javascript, and Drupal, of course. I'm building Drupal projects since 2005, and I was working as full-time senior engineer in CS-Cart for a while, building revolutionary e-commerce software. In my free time, I enjoy playing soccer, building my body in gym, and playing guitar.
Drupal.org ID: restyler
Comments
Hello anton,
thanks for a great tip.
However it is bad practice to put functions such as l etc, inside tpls.
You should put them, on preprocess functions.
Thanks,
apanag
Hey!
That’s an interesting point. Personally I think that using preprocess functions just for l() inside it is not a nice idea. Some simple presentation-related PHP code in templates is a good thing and it works for our team, where front-end developers are used to have some flexibility in styling. But I totally agree that php code bigger than 3 lines should be located in preprocess functions, or in separate module with _theme hook implementation.
Just a suggestion but would computed fields help with this?
The short answer is “yes, but not for all cases”.
The problem with computed fields, that are rendered every time when node is displayed, is that they can’t be used with views (as far as I remember). Computed fields that can be used in views have to be generated and saved in db during node save event. That will work for this specific case, but I think it’s not so elegant to save that data in db. Just think what will happen if you need to display period (5 days - $node->created) to user, in views field. This data certainly can’t be cached!
I have seen this behavior before and I ended up using an if-else statement to check for 2 different aliases. It felt like a hack to do it that way so I was happy to read this post and see that there is a more reliable alternative. Thanks for sharing this with the community!
Hello anton,
Great tips, thanks, I also always found this view bad behaviour :), but we can avoid this by not using the same custom field for different content types, try to use unique field for every content types, not just avoiding this view bad behaviour :), it will also speed up drupal auto query from view, you can feel it when you deal with a big data
Post new comment