Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough
Jan 23 2020
Jan 23

In the Drupal support world, working on Drupal 7 sites is a necessity. But switching between Drupal 7 and Drupal 8 development can be jarring, if only for the coding style.

Fortunately, I’ve got a solution that makes working in Drupal 7 more like working in Drupal 8. Use this three-part approach to have fun with Drupal 7 development:

  • Apply Xautoload to keep your PHP skills fresh, modern, and compatible with all frameworks and make your code more reusable and maintainable between projects. 
  • Use the Drupal Libraries API to use third-party libraries. 
  • Use the Composer template to push the boundaries of your programming design patterns. 

Applying Xautoload

Xautoload is simply a module that enables PSR-0/4 autoloading. Using Xautoload is as simple as downloading and enabling it. You can then start using use and namespace statements to write object-oriented programming (OOP) code.

For example:

xautoload.info

name = Xautoload Example
description = Example of using Xautoload to build a page
core = 7.x package = Midcamp Fun

dependencies[] = xautoload:xautoload

xautoload_example.module

<?php use Drupal\xautoload_example\SimpleObject; function xautoload_example_menu() { $items['xautoload_example'] = array( 'page callback' => 'xautoload_example_page_render', 'access callback' => TRUE, ); return $items; } function xautoload_example_page_render() { $obj = new SimpleObject(); return $obj->render(); } useDrupal\xautoload_example\SimpleObject;functionxautoload_example_menu(){  $items['xautoload_example']=array(    'page callback'=>'xautoload_example_page_render',    'access callback'=>TRUE,  return$items;functionxautoload_example_page_render(){  $obj=newSimpleObject();  return$obj->render();

src/SimpleObject.php

<?php namespace Drupal\xautoload_example; class SimpleObject { public function render() { return array( '#markup' => "<p>Hello World</p>", ); } } namespaceDrupal\xautoload_example;classSimpleObject{  publicfunctionrender(){    returnarray(      '#markup'=>"<p>Hello World</p>",    );

Enabling and running this code causes the URL /xautoload_example to spit out “Hello World”. 

You’re now ready to add in your own OOP!

Using Third-Party Libraries

Natively, Drupal 7 has a hard time autoloading third-party library files. But there are contributed modules (like Guzzle) out there that wrap third-party libraries. These modules wrap object-oriented libraries to provide a functional interface. Now that you have Xautoload in your repertoire, you can use its functionality to autoload libraries as well.

I’m going to show you how to use the Drupal Libraries API module with Xautoload to load a third-party library. You can find examples of all the different ways you can add a library in xautoload.api.php. I’ll demonstrate an easy example by using the php-loremipsum library:

1. Download your library and store it in sites/all/libraries. I named the folder php-loremipsum. 

2. Add a function implementing hook_libraries_info to your module by pulling in the namespace from Composer. This way, you don’t need to set up all the namespace rules that the library might contain.

function xautoload_example_libraries_info() { return array( 'php-loremipsum' => array( 'name' => 'PHP Lorem Ipsum', 'xautoload' => function ($adapter) { $adapter->composerJson('composer.json'); } ) ); } functionxautoload_example_libraries_info(){  returnarray(    'php-loremipsum'=>array(      'name'=>'PHP Lorem Ipsum',      'xautoload'=>function($adapter){        $adapter->composerJson('composer.json');      }

3. Change the page render function to use the php-loremipsum library to build content.

use joshtronic\LoremIpsum; function xautoload_example_page_render() { $library = libraries_load('php-loremipsum'); if ($library['loaded'] === FALSE) { throw new \Exception("php-loremipsum didn't load!"); } $lipsum = new LoremIpsum(); return array( '#markup' => $lipsum->paragraph('p'), ); } usejoshtronic\LoremIpsum;functionxautoload_example_page_render(){  $library=libraries_load('php-loremipsum');  if($library['loaded']===FALSE){    thrownew\Exception("php-loremipsum didn't load!");  $lipsum=newLoremIpsum();  returnarray(    '#markup'=>$lipsum->paragraph('p'),

Note that I needed  to tell the Libraries API to load the library, but I then have access to all the namespaces within the library. Keep in mind that the dependencies of some libraries are immense. You’ll very likely need to use Composer from within the library and commit it when you first start out. In such cases, you might need to make sure to include the Composer autoload.php file.

Another tip:  Abstract your libraries_load() functionality out in such a way that if the class you want already exists, you don’t call libraries_load() again. Doing so removes libraries as a hard dependency from your module and enables you to use Composer to load the library later on with no more work on your part. For example:

function xautoload_example_load_library() { if (!class_exists('\joshtronic\LoremIpsum', TRUE)) { if (!module_exists('libraries')) { throw new \Exception('Include php-loremipsum via composer or enable libraries.'); } $library = libraries_load('php-loremipsum'); if ($library['loaded'] === FALSE) { throw new \Exception("php-loremipsum didn't load!"); } } } functionxautoload_example_load_library(){  if(!class_exists('\joshtronic\LoremIpsum',TRUE)){    if(!module_exists('libraries')){      thrownew\Exception('Include php-loremipsum via composer or enable libraries.');    $library=libraries_load('php-loremipsum');    if($library['loaded']===FALSE){      thrownew\Exception("php-loremipsum didn't load!");

And with that, you’ve conquered the challenge of using third-party libraries!

Setting up a New Site with Composer

Speaking of Composer, you can use it to simplify the setup of a new Drupal 7 site. Just follow the instructions in the Readme for the Composer Template for Drupal Project. From the command line, run the following:

composer create-project drupal-composer/drupal-project:7.x-dev <YOUR SITE DIRECTORY> --no-interaction

This code gives you a basic site with a source repository (a repo that doesn’t commit contributed modules and libraries) to push up to your Git provider. (Note that migrating an existing site to Composer involves a few additional considerations and steps, so I won’t get into that now.)

If you’re generating a Pantheon site, check out the Pantheon-specific Drupal 7 Composer project. But wait: The instructions there advise you to use Terminus to create your site, and that approach attempts to do everything for you—including setting up the actual site. Instead, you can simply use composer create-project  to test your site in something like Lando. Make sure to run composer install if you copy down a repo.

From there, you need to enable the Composer Autoload module , which is automatically required in the composer.json you pulled in earlier. Then, add all your modules to the require portion of the file or use composer require drupal/module_name just as you would in Drupal 8.

You now have full access to all the  Packagist libraries and can use them in your modules. To use the previous example, you could remove php-loremipsum from sites/all/libraries, and instead run composer require joshtronic/php-loremipsum. The code would then run the same as before.

Have fun!

From here on out, it’s up to your imagination. Code and implement with ease, using OOP design patterns and reusable code. You just might find that this new world of possibilities for integrating new technologies with your existing Drupal 7 sites increases your productivity as well.

Jun 29 2016
Jun 29

This one tripped me up on a recent Drupal 8 project.

Easy to miss when you're working in a development oriented environment with things like JavaScript preprocessing turned off.

A JavaScript file was being added just fine with aggregation turned off, but not getting added with it turned on.

While working on a Drupal 8 client project we were using our module's .libraries.yml file to add a custom plugin for Jquery Validation. Our plugin was using the Moment.js date library to add strict date checking so we could check for overflows. The default date validation in that plugin treats dates like 55/55/5555 as valid - because they are cast to valid JavaScript dates by the browser. We needed to detect overflows and report an error.

It was working all fine locally, but when I sent a Pull request, it didn't work in the Pull request environment (we have per pull-request environments).

After some head scratching I found the issue.

My libraries.yml definition looked like this:

moment_date:
  version: VERSION
  js:
    js/moment_date: {}
  dependencies:
    - clientside_validation/jquery.validate
    - mymodule/moment
    - core/modernizr

If you picked it, I've missed the .js suffix on the file name.

Locally I was working with developer optimised settings, so I had a settings.local.php with the following

$config['system.performance']['js']['preprocess'] = FALSE;

i.e. I was disabling JavaScript aggregation so I could rapidly iterate, something you'd normally do.

Problem was on the Pull Request environment JavaScript aggregation is turned on (as it should be).

And mysteriously this made a difference.

My libraries.yml file was just plain wrong, it should have been

moment_date:
  version: VERSION
  js:
    js/moment_date.js: {}
  dependencies:
    - clientside_validation/jquery.validate
    - mymodule/moment
    - core/modernizr

But with JavaScript aggregation turned off, my webserver was adding the file, sending moment_date.js when moment_date was requested - silently hiding the bug from me.

A tricky one, but one worth sharing.

Drupal 8 libraries JavaScript

Theming Views in Drupal 8 – Custom Style Plugins

Mar 23 2016
Mar 23
Sep 04 2011
Sep 04

The AWS SDK for PHP Drupal integration project, that I maintain, provides releases that correspond to each release made by Amazon. Having releases that correspond to an upstream source is something that you see in Linux packaging systems and offers some interesting bonuses. In Linux distribution model individuals do not monitor upstream for changes, and packages are rebuilt and increment version regardless of changes to the packaging scripts themselves. Given that Drupal distributions mimic Linux distributions in many ways and even individual site builds I think the reasons behind making corresponding releases are interesting and worth consideration.

To clarify what releases corresponding to upstream releases means consider the following from the AWS SDK for PHP project page.

Since Drupal.org does not allow for three-part version numbers this project follows the AWS SDK for PHP 1.x development line and the release version mapping is as follows. The mapping shows the Drupal release to the Amazon release. Please ensure you are using a Drupal module and Amazon SDK pair that match the version number mapping. For example, use the 4.1 Drupal module with the 1.4.1 Amazon SDK.

  • 4.x -> 1.4.x
  • 3.x -> 1.3.x
  • 2.x -> 1.2.x

Making a release whenever upstream makes a release means that some releases may end up with little or no changes to the actual Drupal module. The AWS SDK module provides a Drush Make file that is updated each release to point to the matching upstream release, but that is the only change for some of the releases.

Making arbitrary releases may sound foolish at first, but consider some of the advantages.

  • Drupal site maintainers and distributions developers can receive update notifications from the standard Drupal core update system instead of having to monitor upstream for releases. Making it easier to watch for updates encourages keeping up-to-date with upstream changes which has implied benefits.
  • Any incompatibilities with a specific version of a third-party system or upstream library do not need to be kept track of since the integration project is always used with a specific upstream release.
  • New features or configuration options from an upstream source may be added immediately to the integration module without worry about incompatibility with older releases of the upstream source. Meaning if a configuration variable changes name or a new option is added it can be exposed through a Drupal UI without worry if people are using the appropriate upstream version (since they are always intended to work with a matching release).
  • When building a site or distribution using Drush Make specific versions of upstream libraries can be easily included using the corresponding Drupal project with a proper make file. If one wants AWS SDK 2.6 simply add projects[awssdk] = 2.6 instead of having to include the Drupal project and override any third party generic make script.
  • Handling of updates, when necessary, is much simplier since you always know the library version that was used with the previous release.

The general pattern that seems to emmerge is that upstream sources integrate better into Drupal workflow, tools, and infrastructure when matching releases are made.

It does not seem that any other (or few if they exist) third-party integrations or library integrations on drupal.org follow this workflow. Making corresponding releases may not be appropriate in all situations, but I think it warrants consideration and I am interested to hear thoughts on the subject.

Oct 15 2007
Oct 15

Schemes to add functionality to the web OPAC fall into four categories: web OPAC enhancements, web OPAC wrappers, web OPAC replacements, and integrated library system replacements. I’m outlining these four techniques in a report I’m editing for an OhioLINK strategic task force and a bit of a reality check on this categorization is desired, so if I’m missing anything big (conceptually or announcements of projects/products that fall into these categories), please let me know in the comments. Generally speaking, this list is ordered by cost/complexity to implement — from lowest to highest — as well as the ability to offer the described enhanced services from least likely to most likely.

Web OPAC enhancements are functions that are added to the existing web OPAC system. This most often entails additional product purchases from the automation vendor, such as the optional enhancements in WebPAC Pro for Millennium OPACs or content solutions in SirsiDynix. Enhancement can also be added through creative use of an existing web OPAC’s template functions, such as the method by which LibraryThing for Libraries can be added to OPAC displays.

Web OPAC wrappers use the existing web OPAC provided by the integrated library system as a source of information, but hide that information behind a completely new interface. The intervening system get that information from the integrated library system through a variety of mechanism. In some cases, it may be possible to use established protocols (such as Z39.50) or programming interfaces (such as an XML content server). In cases where such functionality is not available from the underlying integrated library system, a “screen-scraping HTML” technique may be required. 1

One example of such a wrapper is the work at Ann Arbor Public Library on SOPAC. Short for “Social OPAC,” SOPAC is “a set of social networking tools integrated into the AADL catalog [that] gives users the ability to rate, review, comment-on, and tag items.”2 It uses an open source content management system called Drupal as a structure through which the added functionality is provided. For example, when a user seeks the bibliographic information page for a catalog record, that request is made from the user’s browser to the Drupal software. The Drupal software in turn makes a request to the integrated library system for the bibliographic information it holds. The response from the ILS is parsed by the Drupal software for key information such as title, author, subjects, holdings, etc. This information is mixed with information stored in the Drupal database (ratings, tags, reviews, cover images, etc.) and a new web page is created and returned to the user’s browser.

Another example of a web OPAC wrapper is Scriblio (formerly called WPopac). Using the underlying framework of WordPress, Scriblio offers faceted browsing, tagging, and syndication feeds for the underlying Millennium WebOPAC. Scriblio is a project of Plymouth State University, supported in part by the Andrew W. Mellon Foundation. Both SOPAC and Scriblio are available under open source licenses.

Web OPAC replacements are new systems that completely replace the existing web OPAC. Unlike wrappers (which get their bibliographic data in real-time from the underlying web OPAC), these replacements operate on sets of records that are extracted from the ILS or come from another source. (In some cases, these replacements still rely on the underlying web OPAC as a source of item status information such as checked out status and due date.) The first notable OPAC replacement was at North Carolina State University when its library installed and configured the Endeca software to provide a faceted browse to the library catalog. By itself, an Endeca OPAC display does not enable tagging, annotation, or user aggregation services such as recommendation engines.  Other similar web OPAC replacements are Encore from Innovative Interfaces3, Primo from Ex Libris and Aquabrowser from Medialab Solutions. Miami University’s experiments with the open source Apache SOLR and the exported records from their Millennium system also fall into this category. Worldcat Local is also a form of web OPAC replacement noting that the source of bibliographic records is the OCLC Worldcat database rather than the local ILS.

ILS replacements offer the biggest opportunity for enhanced user services, particularly by adopting one of the open source solutions now available. At this time, neither of the open source solutions (Evergreen and Koha) offers more than faceted search and browsing. Unlike the commercial systems, however, the source code of the system can be modified to add these functions, and the modifications shared with other users of the same system.

[Update 20071015T1624 : Corrections made — and the text improved! — based on Betsy Graham’s comment. Thanks, Betsy!]

The text was modified to update a link from http://www.iii.com/mill/webopac.shtml to http://web.archive.org/web/20071015145500/http://iii.com/mill/webopac.shtml on January 20th, 2011.

The text was modified to update a link from http://www.iii.com/encore/main_index2.html to http://web.archive.org/web/20080328163000/http://www.iii.com/encore/main... on January 20th, 2011.

The text was modified to update a link from http://www.sirsidynix.com/Solutions/Products/portalsearch.php#content to http://web.archive.org/web/20071109170053/http://www.sirsidynix.com/Solu... on January 28th, 2011.

Footnotes

  1. Such a technique gets the information from the ILS using the existing web OPAC. Such schemes are generally fragile because changes to the underlying web OPAC can have detrimental affects on the content scraping process. []
  2. Blyberg, J. (2007). AADL.org Goes Social. blyberg.net. Retrieved October 12, 2007, from http://www.blyberg.net/2007/01/21/aadlorg-goes-social/ []
  3. As Betsy Graham, Vice President of Product Management at Innovative Interfaces, notes in the comments, the Encore will perform real-time queries to a Millennium ILS for bibliographic data, and in such cases the data extract is not needed. []
(This post was updated on 27-Jan-2011.)

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web