Drupal: Invoke blocks and views from code

While Panels is great for controlling the layout of drupal pages, there are times when you can’t use the module to theme a page.  For uncached content, it does introduce some performance overhead into the drupal request change.  It can also be tedious to migrate changes from one environment to the other if you don’t export pages and variants to version control.

When you’re working in the stock theme layer, the following functions can come in handy.

Render a Block

/**
   * Convenience function to easily call a block from a module
   * @param string module name
   * @param string delta
   * @return array block
   */
  public function invoke_block($module, $delta) {
    if ('block' == $module) {
      global $theme_key;

      // the block_block view is pretty useless
      $block = db_fetch_object(db_query("SELECT b.*, bl.title, bl.*
                   FROM {boxes} b
                   INNER JOIN {blocks} bl ON (bl.module='block'
                       AND bl.delta=b.bid AND bl.theme='%s')
                   WHERE b.bid = %d", $theme_key, $delta));
     $data['subject'] = $block->title;
     $data['content'] = check_markup($block->body, $block->format, FALSE);

      if ('n/a' !== $data['content']) {
        return ($object) $data;
      }
    } else {
      if (module_exists($module)) {
        $block =  module_invoke($module, 'block', 'view', $delta);
        $block['delta'] = $delta;
        $block['module'] = $module;
        return (object) $block;
      }
      else {
        trigger_error("Module $module is not enabled.", E_USER_ERROR);
      }
    }
  }

To show block with delta 1 defined by module foo:

$block = invoke_block('foo', 1);
$output = theme('block', $block);

Render a View

/**
   * Convenience function to easily get the output of a view
   * A note about the display id, this is NOT the identifier
   * that you can set in the Views UI. To see the display id, look
   * at the theme information for the display.  For blocks it will
   * be something like block_1 or block_X where X is a number.
   * If the display_id doesn't match then Views automatically
   * uses the default display which can make themeing a pain.
   * modeled on view_embed_view().
   *
   * @param string view name
   * @param string display name (see theme info for the display name)
   * @param array additional options
   * @return string
   */
  static public function invoke_view($name, $display_id = 'default') {
    $args = func_get_args();
    array_shift($args); // remove $name

    if (count($args)) {
      array_shift($args); // remove $display_id
    }

    $view = views_get_view($name);
    if (!$view) {
      trigger_error('Unknown view invoked: ' . $name, E_USER_WARNING);
      return;
    }

    // validate the $display_id is valid
    // generate an error to prevent wasted time debugging.
    $defined = array_keys($view->display);

    if (!in_array($display_id, $defined)) {
      trigger_error('In view "' . $name . '" unknown display invoked "'
                  . $display_id . '"', E_USER_WARNING);

      // lets not render, chances are we don't want
      // the default display if we invoke a specific view
      return;
    }

    // if a view is empty, dont return anything
    $r = $view->preview($display_id, $args);
    if (false !== strpos($r, '
‘)) { return $r; } else { return null; } }

To render display page_1 from view foo. You can even pass arguments to the view.

$output = invoke_view('foo', 'display1');
$output2 = invoke_view('foo', 'display1', 2010, 111); // with args!

Feature module example to bundle WYSIWYG Configuration

This is a concise example showing how you can use the Features module to bundle configurations in Drupal into a module.  It's great to see the Drupal community moving towards using code to capture, reuse, and deploy configuration settings.  It's been the biggest pain point in working with Drupal for me.

One of the things Drupal core does not do well at all is provide an easy way to switch on a WYSIWYG editor. There is no editor out of the box and setting it up requires some custom configuration of several Drupal core settings, installing and configuring several contributed modules, and also installing one or more external libraries, like the TinyMCE library.

WYSIWYG as a Feature 

TekX – Introduction to Testing with Selenium

Arne Blankerts – part of thePHP.cc, premium PHP consulting and training.

  • Selenium is a java based portable testing framework.
    • Seleniumm RC runs any browser supported by the framework, firefox, opera, etc
      • Can operate/execute ANY browser available on the host machine
      • On Linux, have to tweak how process is shutdown.
    • Selenium IDE – extension for Firefox to Create and Edit Tests.  Can record clicks instead of writign code.
  • Where to use it?
    • Acceptance/Integration Tests – test behaviors in the browser.
    • Compatibility Tests – test that new functions work across browsers/versions
    • Monitoring – you can record behavior and trigger events.
      • Can test that, for example, your registration form actually works not just makes the page available.
    • Test case recording for Bugreports.
      • Provide more detailed, reproduceable bug reports.
    • Development – automate filling out forms during development.
  • Selenium does not replace unit testing or other forms of testing.
  • Useful RC options
    • -port alternate listening port
    • -log save console output to logfile
    • -debug more trace output
    • -timeout seconds to wait before giving up on a test
    • -html run a single standalone test
  • Selenium Tests
    • Written in browser independent JavaScript based DSL
    • Same test can run on any OS with Java runtime and many browsers
      • Firefox 2+, Internet Explorer 6+, Opera 8+, Webkit from Safari 2+
    • Can write tests using PHP as well.
    • Can test for presence of elements – seems to use XPath to select elements, but you can use other notations.
    • Pretty powerful selectors for finding elements.

Talk derailed a bigt by technical difficulties, but provided a good introduction into selenium.

Day 2 Keynote – 10 Developer Trends

Today's keynote is about trends that developers across platforms and languages will face.  None of these should be big surprise if you keep up to date and "read the internet".  Presented by the VP of Technology at dzone.com.

  • The Rise of Agile and Lean
    • Majority of developers report using Agile, but it means different things to different people – i.e. using Scrum, User Stories, etc.
    • Agile is a hot topic at DZone, so there's an audience looking for help and information on using it.
    • Noticed a rise in consultants and software claiming to help implement Agile.
    • People with small teams/enterpreneurs are the ones practicing agile.  Hasn't broken into "the Enterprise".
    • But, does Agile lead to better software?  Do more frequent releases mean we hit schedules, are more secure,  and solve user problems?
      • More frequent releases DO cut down on having to explain stuff to clients, because you can show them stuff.
  • Switch to Standards based Browsers
    • Chrome has had tremendous growth, particularly with technical audience.
    • Windows developers are switching quickly to IE8.
    • Overall developer population is still largely on Microsoft.  But those developers don't go to conferences?
  • Everyone needs to know Ajax/Javascript
    • Back end developers need to understand the user interface too.
    • Should learn at least on framework such as jQuery or Prototype
    • Understand how ajax works, and its data transports like JSON, XML.
  • Focus on Security
    • Vulnerabilities get more and more media coverage.
    • Are there more security holes or are attackers getting smarter.
      • XSS, SQL Injection, weak passwords, etc…
    • Can't assume your framework takes care of all security.
    • Give equal time to security audits of your code.  Think about security when you're developing.
  • Rich User Interfaces
    • Users expect much more dynamic interfaces, even if they prefer style over substance.
    • Lots of options for RIA – Flash, Silverlight, Flex, Ajax, HTML5
    • Must RIAs run outside the browser?
      • it can run on the desktop – what opportunities does this create?
    • Benefits of RIA vs. normal website?
  • Mobile and other UI Form Factors
    • Can't presume that everyone has a mouse.  Link targets will have to get larger, more touch friendly.
    • Different platforms have touch interfaces that behave differently.
    • Supporting multiple platforms will be a point of pain.
    • But users expect application to just work.
  • Death of Relational Databases
    • Can mean different things to different people.
    • Data store that is focused on horizontal scaling, massive data, and lookups based on primary keys.
    • Large Web 2.0 sites are moving to NoSQL – Digg, Twitter, Reddit
    • But relational databases are not going away any time soon.
      • Most developers are fie on RDMS.  Few need to Scale at this level or deal with massive data storage.
      • Not all queries convert easily.
    • NoSQL data stores very common on the cloud  – App Engine, Amazon SimpleDB
  • Distributed Version Control
    • Many choices emerged – Git, Mercurial, Baazar
    • Git seems to have most momentum
    • Adoption driven by Open Source
    • Does anyone still use CVS?
    • Subversion still big, driven by tool support.  Its entrenched in the enterprise because the IDE's have good support built in.
    • Distributed VCS encourages outside participation.
  • Cloud Computing
    • What does the term really mean?
      • non-root access on someone else's hosting platform (ie my blog is on wordpress.com)
      • or virtual servers with root access that can be easily replicated.
    • Lot of "Cloud" platforms – App Engine, Azure, VMForce, hosting companies, etc…
    • Hand-in-hand with NoSQL
    • Most apps don't need that kind of scalability
      • Complex systems require more management and automation.
    • Is it worth rewriting our application to run in the cloud.
  • Rise of Interpreted Languages
    • Ruby, Python, Clojure, Scala, Groovy
    • New languages to solve new problems
      • Better support for the cloud
      • Take advantage of multiple cores and parallel processing.
      • Often early takers of NoSQL
    • Is the JVM empowering language developers?

Habari Project impressions

I have to admit that i jumped over to using Habari for my blog mainly based on how well designed and obejct oriented the underlying API seemed from the documentation. Coming from looking at Drupal code all day, which is painfully NOT Object Oriented, yes with capitals, the code is more readable and, so far, less mysterious.

Don’t believe me? Go read the instructions for Creating a Content Type. Like Drupal, it depends on function name conventions for some hooks, but beyond that everything else is nicely encapsulated in a proper class.

But I haven’t developed my own plugins yet, although I have an idea for one. My main impressions are from installing it and using it.

The installation itself is very straightforward, at least on par with WordPress. If, like me, you find yourself installing it multiple times, one can Predefine configuration settings and not have to manually enter them each time.

The admin interface is elegant and useful, certainly less cluttered than Drupal’s admin pages. A simple pull down menu in the top left corner of the page lets you add posts, configure plugins, and access other admin functions.

The plugin system is in a state of flux, due to a change in how plugins are defined/discovered by the system between versions 0.6 and 0.7. This means a lot of plugins are available for the former, but maybe not the latter. It’s also difficult to track down a solid list of plugins, so I’ve been using http://svn.habariproject.org/habari/trunk/htdocs/user/plugins with svn:externals to install and update plugins.

The new "Bytes in the Margin"

Its time to relaunch my blog as Bytes in the Margin. I like the new name, which is not an anagram of my own name. I was inspired by all the notebooks I have from school and work meetings, which are decorated with pen and pencil doodles in the margin.

While the title is new, the content won’t really change, and I’ve left the Feedburner feed at RecordAsIAm still enabled, so hopefully I don’t lose any subscribers.

This also gives me a chance to check out a new blogging/content management platform – Habari Project, which, from looking at the code, looks like a very nicely designed PHP blogging framework. Given that my major point of reference is Drupal, that may not be saying much. If you’re particularly geek, learn Why Habari? or look at how they’ve implemented Plugins

Getting XDebug workign on Mac OSX

Having a good debugger and error reporting can mean the difference between spending an hour hunting down the line of code causing bug and killing it quickly. For PHP, xdebug is my preferred debugger (are there others?),.  Thanks to this link on debuggable.com, I was able to find a precompiled binary for OS X. Setting up Xdebug on Mac OS X (or Win32 / Linux) » Debuggable Ltd

Anyway, one of the biggest obstacles when getting started with Xdebug
was that I had a hard time finding good instructions on how to set it
up on Mac OS X (I finally got rid of windows, yeah !). The only good
resource I found was stored in Googles cache (wasn’t live anymore) and
had instructions on how to manually build xdebug from source. However,
I didn’t have a lot of time back then and compiling would have involved
setting up all kinds of additional tools. This was the point when I
vaguely remembered that the Komodo IDE
was using xdebug. So I did some more research and sure enough, the good
folks over at ActivateState actually provide their Xdebug binaries as
stand-alone downloads for all major platforms.

HOWTO: Use VirtualBox to setup an Internet Explorer testing machine

There are a lot of cases where having one computer just isn’t enough. If you’re a web developer or webmaster, you’ll want to view your website in more than one browser. If you’re a PHP programmer, you may be itching to check out the new 5.3 release and test your web applications on it. Using virtualization, you can set up self-contained instances of any Operating System configured to your heart’s content on your computer.

There are a lot of virtualization environments out there. VirtualBox is an Open Source virtualization solution from Sun. I particularly like that it runs not only in Linux, but also on Mac OS X and windows. In this post I’ll show you how to set up VirtualBox with disk images supplied by Microsoft for testing Internet Explorer compatibility in OS X. The instructions are based on this article for setting up VirtualBox in Ubuntu.

Download supporting files and utilities

To get each environment setup, you’ll need a few files and tools installed to get everything working.

1. Install RAR

Download the RAR Utility for Mac OS X, as of this writing its labeled RAR 3.90 beta 3 for Mac OS X. The download file is a .tar.gz file. In OS X terminal you can use tar -xvzf rarosx-3.9.b3.tar.gz to extract the files. Next, you’ll want to copy the extracted files to /usr/local/bin/ or anywhere else that is in your $PATH.

2. Install Burn

We’ll need to create an .ISO file for the networking drivers expected by the Windows images. Burn 2.3u is a free and straightforward tool for burning disks or creating disk images. Simply download it and drag it into your Applications folder.

3. Download PCNET Drivers and create ISO file

Since we’ll want our virtual Windows machines to get on the Internet, you’ll need to download the correct drivers from AMD. Download the ZIP file labeled NDIS5 Driver dated August 2004 and unzip them somewhere. Launch the Burn application and drag the PCNET files from where you extracted them into the Burn app. To create the ISO file, select "Save Image" from the File menu. Save the ISO file somewhere where you’ll remember it, as you’ll need it later.

4. Install VirtualBox

Head on over to the VirtualBox downloads page and download the binary for OS X hosts. Double click on the disk image (dmg) file to mount it, and double click on VirtualBox.mpkg to run the installer. Once installed, VirtalBox will be in your Applications folder.

Setup Windows XP Images in VirtualBox

If you’ve made it this far, you should have VirtualBox installed and all the tools for setting up a Windows XP or Vista image. Repeat this part for each XP Image you want to install, MS provides a number of images combining XP/VISTA with IE6/IE7/or IE8.

5. Download a Windows Image.

Select an image to download from the Internet Explorer Application Compatibility VPC Image page. These images are fairly large, the smalles is 465MB.

6. Extract the .vhd file from the image

Microsoft’s VPC images are mean to be used with their own VirtualPC technology. Luckily, VirtualBox can read VirtualPC’s .VHD files. Use rar to extract the files from the .exe or .rar file you download, as follows.

unrar e IE6-XPSP3.exe

7. Create a new VirtualBox machine

Now that you have the disk image, launch VirtualBox and create a new machine. Make sure you select Windows XP as the Guest OS, and give it enough memory to run well. This depends a lot on how much memory your Host OS has, you can get away with 256MB but I like to give them 512MB if possible. When it asks you

When the new machine wizard prompts you for the hard disk image to use, select the .vhd file extracted in step 6.

8. Launch the new machine and install Guest Additions and network drivers

If you have your new machine setup, click on the green start arrow to boot it. You should see the Windows boot sequence and eventually you’ll get to the Windows desktop. You’ll get prompted a hundred times to install new hardware and connect to Windows update, but just hit cancel until Windows stops trying to be helpful.

First, install the Guest Additions which provide a more seamless transition between Host and Guest OS by clicking on "Install Guest Additions" in the Devices menu

Next, mount the ISO image created in step 3 as a CD. Click on Devices, then Mount CD/DVD-ROM and CD/DVD-ROM Image. Selct the ISO image and then you should see its contents in the virtual CD-ROM drive.

Finally update the network drivers to get the network card working. Select My Computer, click on View System Information, Go to System > Devices, Click on Hardware tab, then Device Manager button. Select ethernet device under Network Adapters and then right click, select Update Drivers, say no to Windows Update, then click Next. Windows should find and install drivers from the CD.

Gotchas and where to go from here.

At this point you should have a working virtual machine with network access. You can repeat steps 5-8 for other Windows images to have one or more environment for testing each version of Internet Explorer. If you do install other Windows images, be aware that the supplied MS Images may all have the same disk UUID, in which case VirtualBox refuses to add them to the Media list. Use VBoxManage to clone the disk image and generate a new UUID. You’ll have to remove the conflicting disk from the list first, and to remove it the virtual machine must be powered off. From the command line, the following will clone a drive:

VBoxManage clonehd XP SP3 with IE7 2009-Apr.vhd IE7_XPSP3.vhd XP_SP3_IE7.vhd

If you’re setting up IE testing environments, I highly recommend that you install the MS IE Developer toolbar too. It’s very helpful in diagnosing Internet Explorer behaviors.

Now that you have VirtualBox running, you’re not limited to Windows images. You can also setup your Linux distribution of choice in a VirtualBox machine. You could setup a copy of your LAMP environment for testing and expirementation.

Tip: Disable Drupal performance settings

On development, testing, and staging site you normally don’t want Drupal’s caching, and javascript/css aggregation features enabled.  Drop the following into your sites settings.php file to override these settings.

<ol><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1"><span class="co1">// disable performance caching</span></div></li><li class="li1"><div class="de1"><span class="re0">$conf</span><span class="br0">[</span><span class="st_h">'cache'</span><span class="br0">]</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span></div></li><li class="li1"><div class="de1"><span class="re0">$conf</span><span class="br0">[</span><span class="st_h">'block_cache'</span><span class="br0">]</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span></div></li><li class="li2"><div class="de2"><span class="re0">$conf</span><span class="br0">[</span><span class="st_h">'preprocess_css'</span><span class="br0">]</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span></div></li><li class="li1"><div class="de1"><span class="re0">$conf</span><span class="br0">[</span><span class="st_h">'preprocess_js'</span><span class="br0">]</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span></div></li></ol>