Drupal

Managing Drupal Views, the proper way

Tags: 

One of the most powerful and most useful modules on Drupal is Views. With one screen you can build custom pages & blocks based around your content, select the exact fields you need, add filters and arguments, and relatively easily customize the display, and that's just scratching the surface. In fact, Views is so flexible that I've built sites which have 90% of their architecture based solely around taxonomies and Views.

The main trick to making using Views manageable is to save them out as files and load them through a module. It sounds really easy, and it is really, but there's a few steps to it.

The first step is to have a per-site module specially for holding these kinds of things, a general bucket for your random chaos.

200905262332.jpg

The second step is to go to each View in turn and export it to a file in your new module's directory. To do that, go to your site's Views list page and for each of the custom ones you've built or modified, click the Export link next to it to bring you to a page with the view's code listed out:

200905262336.jpg  

What you need to do next is save this text out to a file. By default all of the text is selected, but you're not ready for that yet. You first need to create the file to store the text. I like to use the following filename structure:

view.[viewname].inc

This both groups all views together and makes them easy to identify at a quick glance. Going by this, the above view would be saved with the filename:

view.taxonomy_term.inc

Now, just copy all of the code from the Export page into the newly created file. Simple, huh? Well, there's a little gotcha - you need to add "<?php" to the top of the file otherwise the next steps won't work right, e.g.:

200905262341.jpg

Well, we're not done yet, we still have to tell the site that there are views in this new module. This involves two further steps..

The first part is to tell the system that this module uses the Views API by adding some lines to your module:

200905262343.jpg

The last part is to load the views into the system. To do this you must add another file to your module directory named:

[modulename].views_default.inc

Then add the following to the file:

200905262346.jpg

And now you're done!

Well, almost. Your site is still going to load the view that's already in your database rather than the one in your module. To fix this just go back to the main Views list page, find the view you just exported and click the "Revert" link to revert it from the database-stored version to what was in your file; don't be afraid when it says "Are you sure you want to revert the view?" because yes, that's what you want to do. So do it.

And now you really are done. Enjoy. And make sure you save it into your site's SVN server promptly.

Learning Exercise:

To make more of this, and to test your PHP skills, try changing funkychicken_views_default_views() to automatically load all files named 'view.[something].inc' instead of having to manually list each one.

Make a special module for each Drupal site

Tags: 

One thing I've learned from my Drupal development time is that every site should have a new module created for it to house all of the small custom functions and things you'll use. Common things I've added to these per-site modules include:

  • Default views (more on those later),
  • Odd string modifications, e.g. shortening a node summary to fit a certain amount of space,
  • Hacks to modify forms in unusual ways, e.g. pre-assign taxonomy terms to simplify the editorial process,

I've found it much easier to manage these in one single module than e.g. hacking blocks with funky PHP code, etc, and you also gain the benefit of having it all in code, so you can track changes in a code versioning system like svn or git.

Bonus Tip

One final tidbit on this is to create a module "package" for all of the modules you create, i.e. add the following line to your mymodule.info file:

package = My Stuff

Now when you view the module admin page they'll all be grouped together, making them easier to find.

Posting to Drupal through XMPRPC / BlogAPI

Tags: 

When I migrated my blog from Wordpress to Drupal one key thing I still wanted to do was be able to use ecto to post messages from my laptop rather than through the web interface - it can be just easier at times. Thankfully Drupal has a plugin/module built in which does this for you, the BlogAPI module. So I activate the module then try to connect using ecto only to be greeted with the lovely message:

The response from the server did not contain valid data.

This was frustrating, it should just work, right? Thankfully ecto has a console feature which displays all communications with the server, and I was able to see it submit:

<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>blogger.getUsersBlogs</methodName>
<params>
        <param>
                <value><string>ignore</string></value>
        </param>
        <param>
                <value><string>Damien</string></value>
        </param>
        <param>
                <value><string>*****************</string></value>
        </param>
</params>
</methodCall>

This is a normal Blogger API call to find out what blogs a given user (me) has permission to write on at a given blog installation, and should have returned some valid data. Here's what came back:

<?xml version="1.0"?>

<methodResponse>
  <params>
  <param>
    <value><array><data>
</data></array></value>
  </param>
  </params>
</methodResponse>

Obviously this isn't quite right.. I dug through the code, adding print and print_r statements where I thought they might help, until I came to blogapi.module line 937 which says:

$available_types = array_keys(array_filter(variable_get('blogapi_node_types', array('blog' => 1))));

This is supposed to grab the blogapi_node_types system variable which stores a list of the Drupal content types you told it were allowed to be written to using the BlogAPI.. and I had set them, right?

200904201148.jpg

No, as it turned out I hadn't, though I thought I had.

Once I went to /admin/settings/blogapi I was able to mark a few content types to be editable, hit save, go back to ecto and finally see what I wanted:

200904201147.jpg

Success!


Ok, so next problem.. I wrote the above, including the two pasted images, hit Publish but started getting the following error:

<?xml version="1.0"?>
<methodResponse>
  <fault>
  <value>
   <struct>
   <member>
   <name>faultCode</name>
   <value><int>1</int></value>
   </member>
   <member>
   <name>faultString</name>
   <value><string>It is not possible to upload the file, because it exceeded the maximum filesize of 0 bytes.</string></value>
   </member>
   </struct>
  </value>
  </fault>
</methodResponse>

Obviously a problem persisted.

I cranked open the files and inserted some extra code that made it say::

<?xml version="1.0"?>
<methodResponse>
  <fault>
  <value>
   <struct>
   <member>
   <name>faultCode</name>
   <value><int>1</int></value>
   </member>
   <member>
   <name>faultString</name>
   <value><string>It is not possible to upload the file, because it exceeded the maximum filesize of 0 bytes and your file was 12.04 KB.</string></value>
   </member>
   </struct>
  </value>
  </fault>
</methodResponse>

From this you can see that it was getting the file, but it was basically saying that my account was not set up to accept attachments, which was not true as I was the administrator and could do everything, right?

I went back to the BlogAPI settings page, ensured that the file settings looked correct..

200904201211.jpg

.. scratched my head. Then I went to look at the permissions.. as it turned out I had not enabled "administer content with blog api" for my user group.

200904201212.jpg

Doh. I enabled that permission, saved it, and now when I went back to the BlogAPI settings page there was a new item waiting for me:

200904201210.jpg

I expanded that, set the same 1MB and 5MB... and saved..

Et voila! That did the trick, I can now post embedded images too!

menu_link_save doesn't like aliases (drupal)

Tags: 

A quick tip.. while working on an install profile in Drupal I discovered that the menu_link_save() function requires an internal URL, e.g. "node/123" instead of "my-cool-page". Once I tracked down the issue I was able to very easily create lots of menu items as needed, but it wasn't entirely obvious this was needed. I was using install_profile_api to create the menu items and figured it was going to make things easier for the end user, but alas no, so I threw together a quick patch to save others the headache, and wasted hours of development time.

Pages

Subscribe to Drupal