Drupal Development Discoveries - 5 Interesting Techniques and Insights (3 tips, 2 "A-ha!"s)
As we continue to develop custom Drupal content management websites for our clients, we continue to uncover new and interesting aspects of the Drupal development environment. Sometimes it is a new module, a new hook, a new technique for customizing Views, and other times it is an unrecognized functional by-product of a site's configuration, aka "WTF just happened" syndrome!. All of these discoveries have improved our development capabilities, whether through improved workflow or simply in achieving a better understanding of the internal workings of the Drupal CMS. Here are 5 examples I hope can solve a problem for you or lead you to a better approach for your project.
The "custom_url_rewrite_outbound" Function
<code>function custom_url_rewrite_outbound(&$path, &$options, $original_path)</code>
This method can be added to your settings.php file, and will be called by the theming layer for any link that is generated by the "l" function. This is important, as any hard coded links you include in your TPL files, modules or that are stored in a database, such as the body field of a node, will not be passed to this function. However, these are often of little concern, as I've found this function most useful when encountering links generated via the theme process by one or more modules. For example, needing to rewrite certain taxonomy term links to a custom page or search form, while leaving other terms and vocabularies alone. Utilizing this function can take the place of small, one-hook implementation modules that are simply rewriting a small subset of links, or to take the place of a document wide javascript DOM manipulation.
Views planning, CCK field sharing and generic views template file application and reuse
As with most Drupal development teams, we are heaviliy dependent on the Views module. With multiple sites now under our belts, we have developed a few techniques that have simplified the Views creation and management process.
- Share CCK fields whenver possible – a good example would be a URL field. Then the application of a field specific views tpl file (e.g. views-field—field-website.tpl.php) can make it easier to manage the various outputs for this field. Regex logic, modified target attributes and other HTML manipulations can be achieved "site wide." Keep in mind, this is an example of #1 above, where URLs controlled by these template files WILL NOT be passed to the custom_url_rewrite_outbound function.
- Planning – identify your CCK data, site display scenarios and forms, then build your views with as much common ground as possible. For our tourism and hospitality clients, we are often creating business listing searches throughout the site. Lodging, dining and shopping to name a few. By sharing CCK fields as described above, we are able to create one view which defines the fields, ordering, caching and other shared attributes of each search, then each view display definition contains an overridden set of filters. This keeps the number of views to a minimum, and encourages consistency throughout your site.
What happened to my exposed filter template? Where did my custom TPL code go? - Which theme generated that HTML code?
I am simply echoing myself here, but my guess many others have had similar exclamations! What I'm referring to are potential issues caused by running multiple themes on your site, espcially when combined with AJAX generated content. The short explanation is that the AJAX request triggers some other theme, not the one that generated the request. We ran into this recently when utilizing the flags module. Flags allows you to use AJAX to toggle a flags state, and provides a TPL file to control the HTML output for the two states. However, when used in the above configuration of multiple themes, the resulting HTML from the flag AJAX request will have used the default theme of the site. In our specific case, we were using the Theme Key module to support the theme switching on the site, and so an extra theme key rule was required to force flags to run through the intended theme.
Another example of this would be when submitting an AJAX driven exposed views filter form. Again, if you watch the GET request (using a utility such as Live Headers for Firefox) you will see the request is in the form "/views/ajax?filter_name=....", which again, is most likely handled to the default theme of your site. In this, case, however, the view in question is identified in the URL variable scope, not directly in the Drupal path, which theme key provides access to. Our solution for this scenario was to use a function to generate the desired TPL content, then invoked the function from each TPL file, one for each theme. This is not a clean approach, but at the time was the most efficient solution. There is probably a module that can provide the necessary logic. A quick search turned up Dynamic Theme, Theme Rules. Either of these could provide a solution. I couldn't find a specific module for changing the theme based on which view was being invoked.
Iterations of a views TPL file for a "grouped" style output
A few weeks ago I was working on a custom slideshow that utilized jQuery cycle plugin and a set of views TPL files, along with a grouped view output style. The goal was to display a list of upcoming events, each with a photo, description and link. Each event had multiple occurrence dates, and the goal was to show the event once, with the occurrence dates as a date span. I configured the view to group by the event id, then ordered by occurrence date. I then began to work in the views "style output" template (views-view-unformatted.tpl.php ). The $rows array available in the template file contains the generated HTML for each view row. What I discovered was that the template file was being invoked FOR EACH GROUP of rows. So, the length of the $rows array varied, where each event contained N rows for each occurrence. By parsing the $rows array, I was able to determine the first and last occurrence dates, customize some HTML, and then output only the row I needed. After "perfecting" the code and output, I was ready to deploy the new slideshow. However, as soon as I viewed the page as anonymous, my output was completely wrong! Some debugging soon uncovered the issue. The template file was only running once. The length of the $rows array in this case was the total number of rows in the query. Unable to determine the cause of this symptom at that time, I ended up creating a conditional statement to handle the two cases of "authenticated" and "anonymous" user. After revisiting the application, I believe I discovered the reason. The grouped by field (event id) was not accessible to the anonymous user role. The view permission was restricted to site editors. This would seem to be the cause, however I'm unsure as to whether this is an intended aspect of the templating system, or a bug of some sort. I posted a topic in the Views Developers Group forum, but have yet to receive any feedback.
Views filters – conditional filter based on user id or role, using hook_pre_execute
The other day I was configuring two CCK types, one that utilized a node reference field to create a relationship to the other. The scenario was to allow one role to create new nodes of type B, which would reference type A, but to only allow the user to select from nodes of type A that they owned. The apparent solution was to use the view option of the Node Reference field, and to filter the view using the ***CURRENT_USER*** value. This worked fine for users of role C (the restricted role defined above), however I needed the site admins to have access to ALL nodes of type A. As it stands, the views user filters provided out of the box do not allow for this type of granularity. So, this required a hook implementation to rewrite the SQL. By adding an OR statement after the current user clause, I was able to write the query logically as " give me all the nodes owned by the current user, OR give me all the nodes if the current user is not a member of role C. "
To satisfy you code junkies, here's what I came up with!
MY_CUSTOM_MODULE.module:
<code>
function MY_CUSTOM_MODULE_views_pre_execute(&$view){
if ($view->name == "nodes_for_user") {
// Get the info about our query
$altered_query = $view->build_info['query'];
$altered_query = str_replace("(users.uid = ***CURRENT_USER***)","(users.uid = ***CURRENT_USER*** OR (***CURRENT_USER*** IN (SELECT uid FROM users_roles WHERE rid <> 8 )) OR ***CURRENT_USER*** = 1)",$altered_query);
$view->build_info['query'] = $altered_query;
$view->build_info['count_query'] = $altered_query;
return true;
}
}//end hook_pre_execute
</code>
Hopefully one of the above topics saves you some time, provides some insight into a similar issue or further improves your knowledge of Drupal's architecture. Of course, if you instead decide you'd like to work with us to develop your new site or revamp your exisiting one, we'd be happy to oblige!
Recent Entries
- Workology 3.0 - An Adworkshop Jig Super-User Perspective
- Find Your Channel - Build Your Following
- The Power of Technology - and a Morning at Adworkshop Without It
- Custom Conditional Actions in Drupal 6
- Mandatory Timeline for Facebook Brand Pages - What To Do Next
- "Mobilize" Your Marketing Strategy With Mobile Landing Pages
- DrupalCon Denver 2012 - The Tangible Community
- User Centered Design (UCD)
- Will Google Soon Know You Better Than Your Best Friend?
- The Social Media Jungle - Are You King?
Comments
Nice
Hi nice information on Drupal, i am looking for this long time
Drupal Development
Drupal Core is the standard release of Drupal and contains the most basic features which are available in nearly all content management systems.Thanks for sharing more on Drupal Development on this blog
Drupal Development
Hi,
Sanman Technology is responsible for providing dedicated experts to Joomla Web Development, Drupal Development, PHP Web Development Company, Mobile Applications Development, Ecommerce Web Solutions technology based projects.
Thanks
Post new comment