Drupal 7 Tips

I just started working with Drupal7, an open source content management system, for a new venture, and it is great stuff! However, it is sometimes hard to figure out how to accomplish things. Sometimes there are actually multiple ways of doing what you need. And the documentation can be very hard to find and/or follow. Especially since not all of the Drupal 6 extensions have been upgraded to the new version 7 functionality!

http://dev.nodeone.se has a lot of videos for helping you learn Drupal. Check them out.

But none of this has been enough for me to look elsewhere, so I decided to try to start tracking some of the tidbits of information that took me a while to find/figure out, in the hopes that it might save some time for others :).

So, here ya go- the first Aha Moment. Yeah, for you geeks out there, I know, I know- RTFM &#59;)….

  • Tokens- there is all sorts of old/useless information out there regarding tokens in Drupal 7. All I wanted to do was figure out the syntax. Simple, no? Well, it took me a while to figure out that all I needed to do was go to my own Drupal site, and click on the Help link in the Admin center. There is a link for token, and not only did it have a list of token syntax, it had the syntax for all the items that pertained to MY site! For instance, fields that I had defined for my custom content types. Brilliant! But, duh- it took me a while to figure that out!!
  • Tokens, seem to cause people a lot of grief, and it is no wonder since the documentation is so spotty. I was trying to add a token to a title, and FINALLY happened upon this link:  http://drupal.org/node/462654 . Here is the golden nugget of information, that I lifted from that post for your convenience. However, it is probably worth going back and reading through the original, as it gives some insight as to why tokens in titles, headers, footer etc were not being rushed into the core code. In any event, here I send off a great big thanks to patcon for his explanation of Attachments in Views. Look into them- they are very cool :)…”

Sure thing dude.

There are different types of view displays — block, page, attachment, feed, etc (more can be added by other modules). Each little tab on the left of the a specific view edit page corresponds to one of these view displays. You can add more or remove them, and they all sort of use the “Default” view display as a base (although you can overwrite).

So if you want a dynamic header:

  • Create a new view (which is a set of view displays with at minimum a “Default” view display).
  • Add a “Page” display and an “Attachment” display.
  • Configure your “page” display as you normally would, leaving the header blank. Set it as Table style if that’s what you want.
  • Now, work on the “Attachment” display. In the “Attachment settings” portion of the edit pane, you’ll be able to set it to attach to any “Page” display, positioned either below or above depending on your header/footer needs. (Override what you need to so that your changed don’t affect the “Page” or “default” view display.)
  • Still on the attachment display, set the “style” to “unformatted”.
  • Set the result limit to 1, so that only one row is returned. We only want one copy of the header/footer, right? (Slight aside: I’m working under the assumption that you only need data from one row in the header/footer, which is perhaps incorrect. Here’s the demonstration scenario: You’ve got the year in the exposed filter, and you’ve got multiple results from multiple nodes displayed in the main table, and you have another node type that has info on that year as a whole, of which only one exists per year. This would work if you wanted that info displayed in a dynamic header.)
  • Back on track: Add all the fields you need to the unformatted attachment display, and exclude them all from the view, so they’re hidden.
  • Add a “Global: Custom text” field, making sure that it’s the last field in the list and that you delete its label. Assuming you have Token module installed, you can now use tokens from all the other fields to generate what amounts to a dynamic header.

Phewf. Took longer than expected to explain, but hopefully you get the idea. I haven’t done this myself, but I can’t see why it wouldn’t work. If you need to header to disappear when values don’t exist, then instead of adding a “Global:Custom text” field, you can leave one field visible and simply override it with tokens and custom text (so that it become the header). That way, you can use the checkbox to “Hide field if empty”, and when that field has no value, it will hide the whole header. If that’s what you’re going for, I think there’s also a setting in the “Attachment settings” pane that you’d need to adjust, telling views to hide the attachment if nothing is returned (but maybe I’m mistaken).

Anyhow, hopefully this helps :)

” . This method worked like a charm, BTW!
  • Bartik Theme and Colors- there is a ton of information out there on themes, and setting up sub themes. Doing so wasn’t hard, but trying to get the colors on my site to look the way I wanted to, was difficult. The Bartik theme had enough to get me going, and it was easy enough to figure out how to create a sub theme and tweak things like regions, etc. I tried changing the colors in the cascading stylesheet, colors.css in my sub theme. However, the colors kept getting messed up. I finally figured out that I needed to set the sub theme back to the default color scheme, by going back to the original color.css, and then change the colors of JUST the items listed in the Settings under the  Appearance section in the Admin panel. Anything that I did not want colored, I took out of colors.css, but other than that I left that stylesheet ALONE!! Do not modify the colors in colors.css, or you are asking for trouble! Anything I wanted to color myself, I added into the CSS file for the sub theme itself, i.e. bartik_sub.css, where bartik_sub is what I named my sub theme. Lastly, I ran into issue where Internet Exploror 8 showed the tab colors in gray. As seems to be typical when trying to track down Drupal 7 information, there was a ton of noise out there about people running into the same sort of issue, and why Bartik wasn’t suppose to jump through hoops to cater to IE, blah, blah, blah. While I agree with them, in general, it is still frustrating trying to make something work, and someone is taking the high road. I was almost at the point of just putting a message stating that “This site is best viewed in Firefox/Chrome/Safari” when I spied a file called ie.css. I edited that stylesheet with the colors I wanted for the tabs, and lo and behold! Colored tabs and the Featured div, just the way I wanted them!! And as a side not, there was no interference from the color module code, shifting the colors on me in this stylesheet. I am still having a bit of trouble with the colorization in the Bartik theme for a few items, but I am going with it for now. It is good enough, until I can find another theme I would like to use. Hopefully something without the color module :).
So this week I am really hating on Drupal :( . I was just trying to finish up the last little bits of this site I am working on, and it has taken me HOURS to accomplish what I would think would be simple tasks.  Here are the sources of frustration, and hopefully some hints to help you if you are running into the same issues…
  • CKeditor to allow embedding media. Do I need the module Media and Embed Media and anything at all related to Media? Answer, no- not if you are using CKeditor, which for Drupal 7 seems to be about the only thing you really can use. If you download the CKeditor for Drupal from the CKeditor site, you get all these warnings about unlicensed software, even tho Drupal is Open Source, and the CKeditor module is supposed to be as well. So, the correct installation process is to install the CKeditor module from the Drupal.Org site (http://drupal.org/project/modules and serach for CKeditor). Then you need to get the CKeditor plugin from the CKeditor site, unzip it, and copy the contents into the sitesallmodulesckeditorckeditor folder where it says “Copy Here”. When you configure CKeditor on your Drupal site, make sure you click the checkbox to allow the media to be embedded. To do that, go to a profile (Full or Advanced are the default ones) , then to Editor Apperane, then to Plugin. Above the Plugins, you will see a couple of Toolbars. You can click on teh buttons in the very bottom one, which are the ones not in use, and move them to the toolbar that is being used just above it. So grab the embed media button from the “All”  toolbar, and move it to the “Used” toolbar. This embed button works with Youtube and Vimeo. I didn’t try any other ones.
  • Want to add users to a role, and then send an email to those users? Yeah, good luck with that one &#59;). This seemingly easy task took me HOURS to get going (altho I was also trying to work on a weekly newsletter task at the same time- more on that later). Here is where Drupal, in my mind, has a huge brain cramp! It should not be so hard to set up a task that adds a user to a role and then sends a page (for consistency’s sake) to that user. In fact, there are all sorts of pieces that should let you do this. But, alas, they do not all connect. I did finally get it to go, so you can skip to the chase below, but for all my trials and tribulations, I need this time to vent &#59;)
There are components under Configuration->Workflow->Rules where you can do just the sort of thing I was trying to do. Take a user as an input, take a URL as an input,  add a user to a role, fetch a page from a property, like the given URL, and send an emal.
  • Problem 1- fetching an entity from a property, that property being the URL, doesn’t work. At least I couldn’t get it to work, and other folks seemed to be having similar issues, and noone ever gave a straight answer as to whether it really should work. I think when I last left off, there might have been someone in Rules who acknowledged that it might be a problem. It was hard to follow the link trail and whether they blamed Commerce or Rules. I think it is Rules, since I don’t have Commerce. Anyway, if you try to use the fetched entity, it apparently is assuming it is returned as an array, but it isn’t and so it doesn’t work. So don’t go there.
  • Ok, so I did a fetch by ID instead. And that worked well enough. I hard coded the ID of a page for testing purposes, and got the page to be sent in the mail body (only as text since I haven’t set up Mime mail yet). Cool, now I can set this up as a View Bulk Operation (VBO) on a view that shows my list of users, and presto- Magic. Ha! Not so much.
  • Go ahead, create a view of users. Then try to hook it up to a Rules Component using Bulk Operations. You can’t do it. VBO doesn’t give you the option. It narrows the scope of the operations you can use to some other subset, not Rules Components. It took me a while to figure out where these are even coming from, but I finally found them under Configurations-> Actions. Ok, so let me set up an action to do this, Yeah, well maybe not. I can set up one action to Move a user to a role, and one to send an email, but I can’t combine the two, this way. As this task is going to be used by a not so technical user, I really didn’t want to do it that way, but that would have been my fall back plan.
  • I did get the Rules Component to work if I called into the View to get the list of users, and then looped thru the list adding them into the role, and then sending email. However, in case we needed to just perform this on a subset of the users shown in the view, this wasn’t ideal. If you are sure all the users pulled in a particular view are going to be acted upon, then you can use the action, “Load a List of Entity Objects from a VBO” to get the list. Then you can add a loop action, and add actions under the loop to do things using that list. NodeOne.com has a bunch of videos on Rules (and may even cover the VBO action, I forget), so check them out for more information.
  • So, finally what I decided to do, so that my non technical user can have a single step to perform, from a list of users in a view, was to create a flag on a user, that only the admins could see. In Configuration -> Actions, I set up a new action to Flag and Unflag that particular flag, and named the actions accordingly. In my View of Users, I added a Bulk operation, and chose those two new actions as the operations that could be run on the User. Then in Configuration->Workflow->Rules, I set up a Rule, rather than a free-standing component. Rules will be run in the event of some action taking place, like a piece of content being saved, or in my case a user being flagged (or unflagged). The actions I set up were as before, I fetched an entity by ID (I hard coded this as I could not figure out a way to send along the page ID easily from the View without my non-technical being confused as to what to do. Typing a URL would have been acceptable, but an ID not so much). Setting up different Rules related to different groups of users was ok for me since Rules allows cloning.
  • Note: here is the configuration I used to send the email. You would need to tweak the variables a bit depending on what you named things in the rule/component:

Dear [user-entered:field-firstname],

Thank you for becoming a Sponsor for Creative Clearinghouse!!  Included in this email are instructions for how to enter your Ad. You may also read the following instructions here: [entity-fetched:url] .


Update: Some of what I ran into in the previous tirade, may have been a mis-understanding on my part. I was finally able to achieve a measure of success with sending a list of Users (real users of the system) that are displayed within a View and send them an email. I needed to creat a Rules Component that took as an input parameter, a User, NOT a node, and then my Rule would show up in the Views page listing users. Our system uses pages to represent a subset of users, so I was getting confused when trying to use the same Rules component for both.

The other issue I am wrestling with, and here I feel like I am trying to bang a square peg in a round hole, is trying to send out a newsletter. Weekly. I have it set up for an RSS feed to go trhough Google, but that sends out the feed daily. I really would rather do it weekly, or monthly. In Drupal, there are Views to get the latest postings, no problem there. There are flags that let the users indicate that they are interested in subscribing to a newsletter. No problems there. There are Rules Components to grab that list of flagged users and send an email (via the VBO action as I talked about earlier). There is the ability to scheduled a Rules Component for sending in + 1 week. Perfect! So, where’s the issue? I can’t figure out how to get the rendered version of a VIEW to be placed in the body of an email. I thought well, maybe I will make a page and have a view block on that page that shows the listings for the week. Still no way to get that full rendered view. I am still pounding this square peg, so I will followup if I ever get it in the round hole &#59;)
Ha! I pounded that square peg hard enough, that I FINALLY got  it into the round hole!! I got a newsletter going! I needed a fix for the Views Module in order to get this working.  Here are (roughly) a list of the modules that I used:
  • Views
  • Views Bulk Operations
  • Flag
  • Rules
  • Date

I was trying to use a view that listed the new posts that were created within the last week.  Then I create a View of users that had flagged their interest in the Newsletter, and added a Views Bulk Operations to the view. Finally, I created a Rules component that used an action to create a list from a Views Bulk Operations list and then loop through that list to send an email. What I was trying to do was embed the view in the body of the email. Finally, as it turned out, I needed a patch to the Views module in order to do this. If you are trying to do the same thing, then you need to look at this note- <a href=”http://drupal.org/node/1471770″>http://drupal.org/node/1471770</a>- and apply the patch posted on May 25, 2012. After that I was able to use the following PHP code in an HTML email and a field on a node using the PHP format.

<?php echo views_embed_view(‘machine_name_of view’, $display_id = ‘machine_name_of_view_display_name’) ; ?>
Note that this PHP snippet will also work if you want to embed a view in a block on a page. You can use the Body block, and as long as you have enabled PHP to be used in a content block, then you can use that snippet in Drupal 7 (Drupal version 7.14, Views 7.x-3.3) to embed a view.
Also, if you are trying to embed formatted text (i.e. full HTML) and are using CKEditor, Mimemail and Rules to do so, you might need to use PHP to get at the formatted text. Otherwise, all the HTML seems to get stripped out and you are left with plain text. You can follow a post about this here- http://drupal.org/node/1468262
Tabs in Views are another thing that drive me crazy in Drupal. I think I have finally figured out the long and short of it. Basically, if you have two Views pages, and want to make them tabbed do the following:
  • Make both pages have a path setting that starts with the same parent path. For instance, if one tab is Tab1 and the is Tab2, set the path on one to be something like “mytabs/Tab1” and the other to be “mytabs/Tab2”.
  • Set one page to have a Menu settting of Normal and you can put it into any Menu on your site that you like.
  • Set the other page to have a menu setting of  “Default Menu Tab” and when you hit apply, choose “Already Exists”  for its Parent Menu Item.

Related Content by Author: I was trying to create a block of other content related bu author. I got as far as adding a relationship to the View, but it didn’t narrow down the results to the actual user who was the author of the current node. I knew I needed to enter a user id of the author I wanted to narrow down, as a contextual filter, but I couldn’t figure out a way to do this outside of panels. Here is the trick- Enter a User ID as a contextual filter for the block. Choose User ID from URL as a default value if none is entered and underneath there is a checkbox “Also look for a node and use the node author” option. That is the key! Click and you are good to go!

Good think I had started this post for me! I had to come back here to remember how to re-set up ckeditor after and upgrade! Yay me &amp;#59;&amp;#41;.

So the latest thing I had to do was tweak search. I need to restrict search by content type. Views seemed like the way to go, but I gotta tell ya- it wasn’t all that intuitive! I finally managed to figure out that I need to add Search Tems as a filter on the view, and then go over on the right and find the “expose filter as a block” setting and change that to yes. Now I had a block that should up in the admin page for Blocks that I could place into one of the areas on my theme, replacing the normal search block. The generated search block calls the search page I created in views, and it worked like a charm- almost! There is a bug (at least I consider it a bug) in the search results where the sort screws up the output when you search on a term with multiple words (liek an Instructors full name). There was a post about creating a custom module implementing hook_views_alter_query in order to fix it by un-setting the score variable in the query. The one with the code to use the unset was the one that worked for me. I had to tweak the theme layout css a little bit to shrink the slogan block and allow the new sort block to sit higher up on the page, and shrink the width of the submit button a tiny bit, but other than I was good to go. Of course, this took me HOURS!!!!!!!!!!!!!!! I like Drupal, but when easy things like this take such a long time, I really think about looking elsewhere!

I will continue to add to this post as I go along. Enjoy!

Shopping cart


No products in the cart.

Continue Shopping