text:
Upgrade Your Drupal Skills
We trained 1,000+ Drupal Developers over the last decade.See Advanced Courses NAH, I know Enough
With over 200 new features, Drupal 8 is officially here! Drupal is one of the world's favorite open source content management platform.. and it just got even better. Here are some of the ways that Drupal 8 will benefit various groups of people.
- Configuration management – In prior versions of Drupal, most of the configuration was stored in the database. The problem with this is that it is very difficult to keep track of versions of the configuration when it changes. The only way to get configuration out of the database was to use a combination of modules such as strongarm and features to export things from the database into code. This was often time-consuming and error prone. Now with Drupal 8, configuration management is built-in so that carrying over configuration from development to production is a breeze.
- Web services – Drupal 8 can now be used as a data source to output content as structured data such as XML or JSON. This means that Drupal 8 can strictly be used as a back-end while the front-end could be developed completely separate with a framework such as AngularJS or Ember. In other words "Headless Drupal" capabilities are now built-in instead of requiring various addon modules and lots of custom development.
Content Editors:
- Bundled WYSIWYG editor – Drupal 8 is the first version of Drupal to come with a bundled WYSIWYG editor. Previously it was possible to add one of many different editors into Drupal but the setup was often time consuming and confusing. Additionally there were so many choices that some users felt lost about which one to choose. Over time CKEditor has become the most popular WYSIWYG editor for Drupal and now it is included out of the box.
- In place editing – In addition to having CKEditor bundled in with Drupal 8, the Spark initiative is taking WYSIWYG concept a step further with true in place editing. This would give editors the ability to change content, menus, etc. directly from the front-end view of the site without having to navigate to an admin page on the back end. More info about the Spark initiative can be found here: http://buytaert.net/spark-update-in-line-editing-in-drupal
End Users:
- Mobile First – Previous versions of Drupal allowed developers to create responsive themes. However some modules were not 100% compatible with responsive layouts. Now with Drupal 8 all themes are mobile first which means that all community modules will be compatible with responsive layouts. Additionally the default Drupal admin theme will be mobile friendly which should improve the experience for editors who want to author content from mobile devices.
Accessibility and Languages – Drupal 8 now has extensive support for accessibility standards including the adoption of many WAI-ARIA practices. This will make content structures easier to understand for people with disabilities. In addition to the accessibility improvements Drupal 8 now has multi-lingual support included. Drupal 8 has the capability to reach more users than any previous version of Drupal.
In previous articles (here and here), we have seen a method to add custom views and data in MyModule.
With Drupal 8 there is a very easy and practical way to add this custom view as a configuration that will be installed with the module.
1) extract the configuration data
Navigate to "/admin/config/development/configuration/single/export".
On this page, select configuration type 'view' and configuration name 'My module list' that was created earlier.
2) create configuration install file
You will obtain from the above export a list of configuration data that you can copy and paste into a file called for instance "views.view.mymodule-list.yml";
Simply place this file into the install folder :
Upon installation of the module, the view will be automatically created.
We hope this demonstration is helpful to you. You can view as well another demo in our custom module address book , part of EK management tools that use the same technique.
If you have comments or want to add techniques to improve views of custom data, feel free to do so.
The Panels and Panelizer modules have opened up a whole world of options for layouts in Drupal, but too often the usage and features of these powerful tools get confused. My goal with this post is to explore some of the capabilities the Panels module has to offer before ever getting into the realm of using Panelizer.
At a high level, the goals of each of these modules break down into the following:
- Panels: Create custom pages with configurable layouts and components.
- Panelizer: Configure Panels layouts and content on a per instance basis for various entities.
Often, I see both modules added and used when Panelizer isn't needed at all. What's the problem with that? Introducing Panelizer when it isn't needed complicates the final solution and can lead to unnecessary headaches later in configuration management, content maintenance, and system complexity.
Panels and Panel Variants
Before the introduction of Panelizer, site-builders got by just fine with Panels alone. This original solution is still valid and just as flexible as it ever was. The secret in doing this lies in understanding how variants work and knowing how to configure them.
Default Layout for All Nodes
Once Drupal finds a Panels page in charge of rendering the page request, Panels proceeds through the page's variants checking the defined selection rules on each. Starting from the first variant, Panels evaluates each set of selection rules until one passes. As soon as a variant's selection rules pass successfully, that variant is used and the rest below it are ignored. This is why it's important to pay attention to the order in which you define your variants to ensure you place less strict selection rules later in the sequence.
Using this to your advantage, a good common practice is to define a default variant for your Panels page to ensure there is a baseline that all requests can use. To do this, you'll need to define a new variant with no selection rules, so the tests always pass, and place it last in the series of variants. Since the selection rules on this variant will always pass, be aware that any variants placed below it will never be evaluated or used.
Custom Layouts per Content Type
Once you have a generic default in place to handle the majority of content items for your Panels page, you can start to tackle the pages that might have more specific or unique requirements. You can do this by creating a new variant above your default and define selection rules to limit its use to only the scenarios you're targeting.
A common use case for this is the changing layout for content based on content types. To build this out, you need to edit the default node_view Panels page and add a new variant. If this page variant is intended to handle all nodes of this type, I'll typically name it with the name of the content type so it's clear. The next step is to configure the selection rules by adding the "Node: Bundle" rule and select the content type we're building for. Once you save the new variant, any detail pages for that content type should render using the new configuration.
Building on this, a single page can be expanded to handle any number of variants using any combination of selection rules necessary. It's common to see a variant added for each content type in this way. Examples of further customizations that are possible include:
• A specific layout for a section of the site matching a specific URL pattern
• Separate layouts based on the value of a field on the entity
• Alternate views of a page if the user doesn't have access to it
• Separate views of a page based on the user's role
Thanks to CTools, these selection rules are also pluggable. This means if you can't find the right combination of selection rules to enforce the limitation you need, it's easy to write a new plug-in to add your specific rule.
Avoiding Too Many Variants
Using the existing selection rules allows for a great deal of flexibility. Adding in custom plugins further improves your options to define any number of increasingly specific variants.
It is possible to take this too far, however. The cost of creating a new variant is that your layouts and content configurations are now forked further. Any common changes across them now have to be maintained in independent variants to maintain continuity.
Visibility Rules
It's important to also remember the other features Panels offers, including visibility rules. Visibility rules are configured on a per-pane basis inside a specific variant's layouts. These rules offer the same conditions available in variant-level selection rules. Since they're configured on individual panes, however, you can focus on the component-level differences between pages. A common use case for this is to use the same node variant for multiple content types with similar layouts and configure the unique panes with visibility rules to limit which pages they show on.
To elaborate on this, here's an example. Assuming a default node variant with a two-column layout, we can define the common elements that all nodes will have, such as the page title, rendered content, and maybe a sidebar menu. If we then add the requirement that all article nodes include a list of similar articles in the sidebar, we can accomodate this by placing the correct pane in the sidebar and adding the visibility rule "Node: Bundle". We'll then configure it to use the current node being viewed and limit it to show only when that node is in the "Article" bundle. Now, whenever a node is displayed, it will show the common panes, but the block for similar articles will only show in the sidebar if we're viewing a article node.
Choosing the Right Approach
Once you get to the level of creating panel variants or visibility rules just for single pages, it's usually time to ask if you're using the right tool. When you've gotten to the point where individual page instances need to be different, you've come to the impasse of determining the best approach.
If it's only a handful of pages that are each unique, then the most straightforward solution may be to create independent Panels pages for each of these.
If instead, individual instances of the same type need different layouts or configurations, then it may be time to install Panelizer to allow instance-specific overrides.
Previous Post
A Data Dive on Domestic Violence
Next Post
Forum One Pledges Support for White House Climate Data Initiative
Why are my messages (errors, status, etc.) not showing up on my panel override of a node add/edit page?
I wrestled with this problem for longer than I should have, all because I couldn't find this simple Drupal post.
Essentially, I was adding the "Messages" block to the panel content of my node/edit page that I was overriding. Thus, no matter what I did, that message area would never render.
My finding is that
drupal_get_message is a unique function. Once you call it, all messages are cleared from it, so calling it again essentially will be too late to see any messages that might have been there.
page.tpl.php calls this function, and Panels never gets a chance to try to get the messages that might be waiting to be displayed.
As a result, adding the following as a module or theme pre-process hook will keep the page from calling messages (replacing "MyThemeOrModule" with the appropriate name, of course):
function MyThemeOrModule_preprocess_page(&$variables) { // This disables message-printing on a content type edit page so panels can print it if (isset($variables['page']['content']['system_main']['content']['form_id']['#id'])) { if ($variables['page']['content']['system_main']['content']['form_id']['#id'] == 'edit-MyContentTypeName-node-form') { $variables['show_messages'] = FALSE; } } }
Be sure to replace "MyContentTypeName" with the machine name of your content type. If you have doubts, look at the value in
$variables['page']['content']['system_main']['content']['form_id']['#id'] while looking at the content type's edit page. We add this IF statement to make sure we disable page-level messages on this edit form and not on the entire site.
$variables['show_messages'] = FALSE; is what actually disables the messages from being displayed at the page level so Panels has a chance to display them instead.
Messages. Displayed.
Previous Post
DrupalCon Amsterdam, Day 4: Our Kung fu is more powerful than yours!
Next Post
DrupalCon Amsterdam: Done and Deployed
With Drupal 8 looming on the horizon, everyone is talking about doing their part to contribute. In my own case – wanting to get involved but being new to Drupal development – I wasn't really sure where to start.
Through a Drupal DC meetup, I was introduced to the Drupal Ladder. Following the Drupal Core Ladder, I got a practice Drupal environment set up, got familiar with the issue queue, and tested some patches! Of course, all the issues and patches written and tested for the LEARN portion of the ladder only affect the sandbox version of D8 used in the tutorials, but it gives you a great idea of what to expect.
After working through the Ladder, I felt ready to attend some Drupal code sprints. However, one of the biggest problems new people have at code sprints is setting up their Drupal environment. As a newbie, I found the quickest way to set up a test environment on my Mac was through the Acquia Dev Desktop. This is a stack built specifically for Drupal (it's pre-loaded with Apache, MySQL, PHP, etc.), so no downloads other than Drupal itself should be necessary. For this tutorial, we'll be using Acquia Dev Desktop 2 Beta.
Note: although I am using the Mac version, the Windows instructions should be the same.
Installing Acquia Dev Desktop 2 Beta
From the downloads page, click on Mac / Win Download within the, "Get the Acquia Dev Desktop 2 Beta" box at the top of the page. Locate your download file and double click the file to launch the installer.
- Click Next on the initial screen. The following screen will give you an overview of what is included in the Dev Desktop package: Apache, MySQL, PHP, etc. Review these and click Next.
- Review the license agreement, click Yes if you accept the terms, and then click Next.
- Make note of this next screen. This lets you choose the install locations of your stack and Sites folder. I would recommend leaving these as the default selections.
- The next screen displays the port settings that will be used by Dev Desktop. Do not change these. Simply make note of them and click Next.
- Review your information, then click Next, then Next again to begin the installation.
- Once the installation has completed, click on Finish. If the program pops up, minimize it. We must first download a copy of Drupal 8.
Downloading and Setting Up Your Drupal 8 Environment
After installing Dev Desktop, we can now get our Drupal 8 environment running:
- Download your desired version of Drupal 8 (use Drupal 8.0.x-dev if you are going to help test and develop D8) by clicking on the .tar file for Mac or .zip for PC in the Download column. Be sure to extract the tar/zip folder if your system does not automatically do it!
- You can place the files inside your Sites folder, or simply leave it where it downloaded. It is advisable to change the name of the directory from "drupalx.x-x.x" to something simpler (e.g. drupal8, drupaltest, d8dev, etc.).
- Bring back up Acquia Dev Desktop, or launch it. Click on Start with an existing Drupal site located on my computer.
- For Local codebase folder, select the Drupal root folder you just downloaded and click on Open. You can leave Local site name as is, or change it up.
- Drupal 8 requires at least PHP 5.4, so select the PHP version 5.4 your Dev Desktop came with.
- For Database, select Create a new database. You can leave New database name as is, or alter as you like.
- Click OK, and your site will be imported into Dev Desktop.
- Select your site from the left, if it is not already selected. At the top of Dev Desktop, click on your Local site URL and it will come up in your default browser.
- On initial launch, your site should go to /install.php. If not, manually enter /install.php to the end of your site URL (e.g. http://drupal8.local:8083/install.php). Select your language, and click on Save and continue.
- Leave Standard selected as your installation profile. Click Save and continue.
- The database info should transfer and auto-fill into the fields, but just in case, enter the following info:
- Database name: name you created during the import (New database name)
- Database username: drupaluser or root
- Leave the password blank
- Under the Advanced Options: Host: 127.0.0.1 & Port number: 33067
Click on Save and continue once the information has been filled out.
Drupal will now install your site. Once finished, enter whatever you'd like for the site name, email, and user configuration, and your Drupal site should be up and running! Be sure to remember the username and password for the account you created, as this is your main administrator account (user 1).
That's All, Folks
Installing Acquia Dev Desktop is fairly quick simple if you follow these steps. Don't let not having a dev environment stop you from participating in Drupal 8 code sprints, as there are plenty of other AMP stacks available to install, making sure you're comfortable with one goes a long way. With my development environment setup all that's left to do now is to actually write a patch… Maybe I'll take care of that during Forum One's next code sprint!
Want to participate in our next Drupal code sprint in DC? Send us an email and we'll keep you in the loop!
Previous Post
Infographics: Tips for Getting Started
Next Post
Live In-browser Sass Editing Using Compass
How to Build a Drupal 8 Module
In the previous article on Drupal 8 module development, we've looked at creating block types and forms. We've seen that blocks are now reusable and how everything we need to do for defining block types happens in one single class. Similarly, form generation functions are also grouped under one class with specific methods performing tasks similar to what we are used to in Drupal 7.
In this tutorial, I will continue where we left off. I will illustrate how we can turn our
DemoForm into a form used to store a value through the Drupal 8 configuration system. Following that, we will talk a bit about the service container and dependency injection by way of illustration.
Don't forget that you can check out this repository if you want to get all the code we write in this tutorial series.
When we first defined our
DemoForm, we extended the FormBase class which is the simplest implementation of the FormInterface. However, Drupal 8 also comes with a ConfigFormBase that provides some additional functionality which makes it very easy to interact with the configuration system.
What we will do now is transform
DemoForm into one which will be used to store the email address the user enters. The first thing we should do is replace the extended class with
ConfigFormBase (and of course use it):
use Drupal\Core\Form\ConfigFormBase; class DemoForm extends ConfigFormBase {
Before we move on to changing other things in the form, let's understand a bit how simple configuration works in Drupal 8. I say simple because there are also configuration entities that are more complex and that we will not cover today. As it stands now, configuration provided by modules (core or contrib) is stored in YAML files. On enabling a module, this data gets imported into the database (for better performance while working with it). Through the UI we can change this configuration which is then easily exportable to YAML files for deployment across different sites.
A module can provide default configuration in a YAML file located in the
config/install folder in the module root directory. The convention for naming this file is to prefix it with the name of the module. So let's create one called
demo.settings.yml. Inside this file, let's paste the following:
demo: email_address: [email protected]
This is a nested structure (like an associative array in PHP). Under the key
demo, we have another key|value pair. And usually to access these nested values we use a dot(
.). In our case
Once we have this file in place, an important thing you need to remember is that this file gets imported only when the module is installed. So go ahead and reinstall it. And now we can turn back to our form and go through the methods that need adapting one by one.
This is how the
buildForm() method should look like now:
public function buildForm(array $form, array &$form_state) { $form = parent::buildForm($form, $form_state); $config = $this->config('demo.settings'); $form['email'] = array( '#type' => 'email', '#title' => $this->t('Your .com email address.'), '#default_value' => $config->get('demo.email_address') ); return $form; }
First of all, as opposed to
FormBase, the
ConfigFormBase class implements this method as well in order to add elements to the form array (a submit button). So we can use what the parent did before adding our own elements.
Now for the configuration part. Drupal 8 provides a Config object that we can use to interact with the configuration. Some classes already have it available through dependency injection.
ConfigFormBase is one such class.
As you can see, we are using the config() method of the parent class to retrieve a
Config object populated with our
demo.settings simple configuration. Then, for the
#default_value of the email form element, we use the get() method of the
Config object to retrieve the value of the email address.
Next, we only need to change the submit handler because the
validateForm() method can stay the same for now:
public function submitForm(array &$form, array &$form_state) { $config = $this->config('demo.settings'); $config->set('demo.email_address', $form_state['values']['email']); $config->save(); return parent::submitForm($form, $form_state); }
In this method we first retrieve the
Config object for our configuration (like we did before). Then, we use its set() method to change the value of the
email_address to the value the user submitted. Then we use the save() method to save the configuration. Lastly, we extend the parent submit handler because it does contain some functionality (in this case it sets a Drupal message to the screen).
And that's pretty much it. You can clear the cache and try it out. By submitting a new email address, you are storing it in the configuration. The module
demo.settings.yml file won't change of course, but you can go and export the
demo.settings configuration and import it into another site.
The service container and dependency injection
The next thing we are going to look at is the service container. The idea behind services is to split functionality into reusable components. Therefore a service is a PHP class that performs some global operations and that is registered with the service container in order to be accessed.
Dependency injection is the way through which we pass objects to other objects in order to ensure decoupling. Each service needs to deal with one thing and if it needs another service, the latter can be injected into the former. But we'll see how in a minute.
Going forward, we will create a very simple service and register it with the container. It will only have one real method that returns a simple value. Then, we will inject that service as a dependency to our
DemoController and make use of the value provided by the service.
In order to register a service, we need to create a
demo.services.yml file located in the root of our module, with the following contents:
services: demo.demo_service: class: Drupal\demo\DemoService
The file naming convention is
The first line creates an array of services. The second line defines the first service (called
demo_service, prefixed by the module name). The third line specifies the class that will be instantiated for this service. It follows to create the
DemoService.php class file in the
src/ folder of our module. This is what my service does (nothing really, it's just to illustrate how to use it):
<?php /** * @file * Contains Drupal\demo\DemoService. */ namespace Drupal\demo; class DemoService { protected $demo_value; public function __construct() { $this->demo_value = 'Upchuk'; } public function getDemoValue() { return $this->demo_value; } }
No need to explain anything here as it's very basic. Next, let's turn to our
DemoController and use this service. There are two ways we can do this: accessing the container globally through the
\Drupal class or use dependency injection to pass an object of this class to our controller. Best practice says we should do it the second way, so that's what we'll do. But sometimes you will need to access a service globally. For that, you can do something like this:
$service = \Drupal::service('demo.demo_service');
And now
$service is an object of the class
DemoService we just created. But let's see how to inject our service in the
DemoController class as a dependency. I will explain first what needs to be done, then you'll see the entire controller with all the changes made to it.
First, we need access to the service container. With controllers, this is really easy. We can extend the ControllerBase class which gives us that in addition to some other helpers. Alternatively, our Controller can implement the ContainerInjectionInterface that also gives us access to the container. But we'll stick to
ControllerBase so we'll need to use that class.
Next, we need to also use the Symfony 2 ContainerInterface as a requirement of the
create() method that instantiates another object of our controller class and passes to it the services we want.
Finally, we'll need a constructor to get the passed service objects (the ones that
create() returns) and assign them to properties for later use. The order in which the objects are returned by the
create() method needs to be reflected in the order they are passed to the constructor.
So let's see our revised
<?php /** * @file * Contains \Drupal\demo\Controller\DemoController. */ namespace Drupal\demo\Controller; use Drupal\Core\Controller\ControllerBase; use Symfony\Component\DependencyInjection\ContainerInterface; /** * DemoController. */ class DemoController extends ControllerBase { protected $demoService; /** * Class constructor. */ public function __construct($demoService) { $this->demoService = $demoService; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('demo.demo_service') ); } /** * Generates an example page. */ public function demo() { return array( '#markup' => t('Hello @value!', array('@value' => $this->demoService->getDemoValue())), ); } }
As you can see, all the steps are there. The
create() method creates a new instance of our controller class passing to it our service retrieved from the container. And in the end, an instance of the
DemoService class gets stored in the
$demoService property, and we can use it to call its
getDemoValue() method. And this value is then used in the Hello message. Clear your cache and give it a try. Go to the
demo/ path and you should see
Hello Upchuk! printed on the page.
I'm sure you can see the power of the service container as we can now write decoupled functionality and pass it where it's needed. I did not show you how, but you can also declare dependencies when you register services. This means that when Drupal instantiates a service object, it will do so for all its dependencies as well, and pass them to its constructor. You can read more about how to do that on this documentation page.
In this article we've looked at a lot of cool stuff. We've seen how the configuration system manages simple configuration and what we have available form-wise for this. I do encourage you to explore how the
ConfigFormBase is implemented and what you have available if you extend it. Additionally, you should play around in the UI with importing/exporting configuration between sites. This will be a great improvement for the deployment process from now on.
Then, we looked at services, what they are and how they work. A great way of maintaining reusable and decoupled pieces of functionality accessible from anywhere. And I do hope the concept of dependency injection is no longer so scary (if it was for you). It is basically the equivalent of passing parameters to procedural functions, but done using constructor methods (or setters), under the hood, by Symfony and its great service container.
This week, I'll describe a particularly challenging component I had to deal with: inoffensive-sounding menu items. Should be easy, right? Well, it wasn't.
I won't get into the basics of creating multilingual menu items here. There is good documentation on how to get that set up using the i18n submodule i18n_menu. To provide a context for this post, I'll just mention that we are manually creating menu items, through the admin UI. We have two types of menu items:
- Ones that should appear in both languages, localized, and pointing to the same place. Those are created with the language set to "Language neutral".
- Ones that should only appear in a specific language. We set that language explicitly on the menu item's form.
Internally, the i18n_menu modifies the core menu_links and menu_custom tables by adding, among others, a language attribute to save the above info. In addition, the module creates a new text group called menu to save menu translations. In this group, each translation is identified by a menu name and mlid to refer back to the original menu item.
The first problem occurred even before we introduced Features into the mix. The decision to use the mlid as part of the translation identifier means that, across site stages and instances, menu items should have the same database primary key in order to be correctly translated. This design decision introduced a lot of instability in our configurations, for example preventing us from creating new menu items on the fly, for testing or customization purposes. In essence, we would have needed to stick to an install profile approach to manage the site configuration - which is a desirable goal in itself, but one we didn't pursue. In the mean time, our menu item string translations were only reliably showing on the machine where translation occurred, but not elsewhere. This clearly had to be fixed.
We found the module Entity menu links to solve one half of this problem. This module creates a uuid for each menu item, ensuring that uuid remains unchanged throughout the lifetime of the menu item. This module also modifies the core menu_links table by adding to it a uuid attribute.
Still, the string translations were being saved with the mlid. How to convince i18n_menu to use the uuid instead? That's where we had to write some code. The i18n architecture uses the concept of i18n objects that correspond to Drupal site components. We used the following code to override the i18n object info for menu items to use the uuid as a key:
/** * Implements hook_i18n_object_info_alter(). */ function checkdesk_core_i18n_object_info_alter(&$info) { // Use UUID field to identify menu_link. $info['menu_link']['key'] = 'uuid'; $info['menu_link']['load callback'] = 'checkdesk_core_i18n_menu_link_uuid_load'; } /** * Callback to load menu_link by UUID. */ function checkdesk_core_i18n_menu_link_uuid_load($uuid) { if (!empty($uuid)) { $query = db_select('menu_links', 'ml'); $query->leftJoin('menu_router', 'm', 'm.path = ml.router_path'); $query->fields('ml'); // Weight should be taken from {menu_links}, not {menu_router}. $query->addField('ml', 'weight', 'link_weight'); $query->fields('m'); $query->condition('ml.uuid', $uuid); if ($item = $query->execute()->fetchAssoc()) { $item['weight'] = $item['link_weight']; _menu_link_translate($item); return $item; } } return FALSE; }
Unfortunately, the strings were still showing up with the mlid on the translation interface. After many a WTF incantation, we found that i18n_menu was not honouring the i18n object key attribute while creating the string identifiers. We submitted a patch to fix this.
At this point, we had successfully modified the indexing mechanism of i18n_menu to use uuids, as shown below. Our testing with manual .po files revealed that regardless of mlid differences, menu item translations were being successfully moved from one instance to another.
Now menu item translations were made reliable across instances, but they still weren't being saved in a feature. The core Features module does support menu items, but it does not export the additional attributes we introduced above, namely language and uuid. We also need to export customized because i18n will not translate menu items that are not marked as customized.
We submitted a simple patch to Features that allows a
hook_query_TAG_alter to extend the relevant query and return extra fields to be exported. Our implementation of this hook looks like this:
/** * Implements hook_query_TAG_alter() for `features_menu_link`. */ function checkdesk_core_query_features_menu_link_alter($query) { // Add missing attributes for translation. $query->fields('menu_links', array('uuid', 'language', 'customized')); }
After this change, the exported menu links look like this (note the last 3 attributes on each entry):
/** * @file * checkdesk_core_feature.features.menu_links.inc */ /** * Implements hook_menu_default_menu_links(). */ function checkdesk_core_feature_menu_default_menu_links() { $menu_links = array(); // Exported menu link: main-menu:node/add/discussion $menu_links['main-menu:node/add/discussion'] = array( 'menu_name' => 'main-menu', 'link_path' => 'node/add/discussion', 'router_path' => 'node/add/discussion', 'link_title' => 'Create story', 'options' => array( 'attributes' => array( 'title' => '', ), 'alter' => TRUE, ), 'module' => 'menu', 'hidden' => '0', 'external' => '0', 'has_children' => '0', 'expanded' => '0', 'weight' => '-47', 'uuid' => 'edc54df9-4aa8-bf84-dd89-ca0a351af23b', 'language' => 'und', 'customized' => '1', ); // Exported menu link: main-menu:node/add/media $menu_links['main-menu:node/add/media'] = array( 'menu_name' => 'main-menu', 'link_path' => 'node/add/media', 'router_path' => 'node/add/media', 'link_title' => 'Submit report', 'options' => array( 'attributes' => array( 'title' => '', ), 'alter' => TRUE, ), 'module' => 'menu', 'hidden' => '0', 'external' => '0', 'has_children' => '0', 'expanded' => '0', 'weight' => '-49', 'uuid' => '0bc3af5d-28a8-c864-bd93-f17d8bea2366', 'language' => 'und', 'customized' => '1', ); ... }
With these patches, we were able to reliably persist multilingual menu links using Features. The menu item translations are saved in the translations component of the feature, as described in part 1 of this series. They look like this:
/** * @file * checkdesk_core_feature.features.translations.inc */ /** * Implements hook_translations_defaults(). */ function checkdesk_core_feature_translations_defaults() { $translations = array(); $translations['ar:menu']['a6b48d33d248c146aa8193cb6f618651'] = array( 'source' => 'Create story', 'context' => 'item:edc54df9-4aa8-bf84-dd89-ca0a351af23b:title', 'location' => 'menu:item:edc54df9-4aa8-bf84-dd89-ca0a351af23b:title', 'translation' => 'أنشئ خبر', 'plid' => '0', 'plural' => '0', ); $translations['ar:menu']['8578b45ff528c4333ef4034b3ca1fe07'] = array( 'source' => 'Submit report', 'context' => 'item:0bc3af5d-28a8-c864-bd93-f17d8bea2366:title', 'location' => 'menu:item:0bc3af5d-28a8-c864-bd93-f17d8bea2366:title', 'translation' => 'أضف تقرير', 'plid' => '0', 'plural' => '0', ); ... }
Now I need your help to review and support (and possibly enhance) the patches submitted to i18n and Features. Please visit them here:
As you know, the more people show interest in a patch, the more likely it will go in quickly. Your help is appreciated!
Next time, I'll describe other components of the multilingual puzzle: taxonomy terms, static pages, etc.
In my role as development team leader, I am responsible for the application architecture that allows other team members to focus on building functionality with minimum friction and rework. As such, one of my biggest tasks is to ensure that new features and configurations can be reliably deployed to the various stages: development, testing and production.
My current project is an Arabic/English application built on Drupal 7, that is deployed in multisite fashion to several partners. I use Features as a base configuration management system, and a number of extension modules to help me manage specific site components. The need to manage the configuration of multilingual components makes the task more complex, and in this series of posts I hope to describe a full recipe that's allowing our distributed team to commit code without overwriting existing settings.
Here are some of the main architectural components on the site:
- Menus and menu links
- Taxonomies
- Static pages
- Content types
- Views
- Rules
- Heartbeat messages
All these components need to be shown in multiple languages, with the help of the Internationalization module and friends.
Although our application can be delivered in multiple languages, we do all our development on the English UI. When we switched the default language to Arabic, we found that all our menus, taxonomies, and field translations were no longer showing. And for good reason: Drupal does not store the source language of strings in its database, so i18n has to guess the source language - and by default, it considers the site's default language to be the source. Fortunately, you can explicitly specify the source language via the variable
i18n_string_source_language. We decided to hard-code the value of this variable in settings.php like so:
// settings.php // Hardcode i18n_string_source_language to prevent nasty surprises. $conf['i18n_string_source_language'] = 'en'; // Load per-site configurations. require 'settings.local.php';
The last line is just a directive that allows us to version-control settings.php for global configurations and loads settings.local.php for instance-specific settings such as database connection.
Because we're deploying across 3 stages, with several instances at each stage, we cannot afford to manually import .po files each time we create or modify a translation. In order to keep the UI translation workflow sane, we designated a specific stage as the recipient of all translation work, allowing the configuration manager (yours truly) to solve the problem of automating the deployment of these translations to other stages and instances. To this end, I wrote a Features plugin called Features Translations that persists the selected translations within a feature, as shown in the screenshot below:
A file called feature_name.features.translations.inc gets exported to the feature, looking like this:
/** * @file * checkdesk_core_feature.features.translations.inc */ /** * Implements hook_translations_defaults(). */ function checkdesk_core_feature_translations_defaults() { $translations = array(); $translations['ar:default'][] = array( 'source' => 'The optional description of the taxonomy vocabulary.', 'context' => '', 'location' => '', 'translation' => 'الوصف الاختياري لمعجم الوسوم.', 'plid' => '0', 'plural' => '0', ); $translations['ar:default'][] = array( 'source' => 'You are not authorized to access this page.', 'context' => '', 'location' => '', 'translation' => 'غير مسموح لك بالوصول إلى هذه الصفحة.', 'plid' => '0', 'plural' => '0', ); $translations['ar:default'][] = array( 'source' => 'Function', 'context' => '', 'location' => '', 'translation' => 'الوظيفة', 'plid' => '0', 'plural' => '0', ); [...] return $translations; }
In the next part, I'll discuss our handling of multilingual menu items, which took a considerable amount of effort and patches to Features and i18n!
Well, February is always a short month, but this year it seemed like it passed in just a couple of weeks… and now it's already March and I'm only finally getting around to putting the final touches on this posting for the January "Modules of the Month". How did that happen? Well, I won't try to bore you or make excuses. It's just been one of those months. I'm going to try to keep up my current momentum and evaluate and write up my favorites from February now… hopefully finishing that in the next week or so. If it's not done by the 15th, it won't be done till April since I'll be taking off for my first trip to India in the middle of this month.
But I'm not here to write about myself. This is about some modules which I found might be worthy of notice… specifically those released in January 2013. It's interesting to see the evolution of a Drupal version and what kinds of modules are being released these days. Almost no modules are being released for Drupal 6 and Drupal 8's developer API is still far enough from maturity that there are very few modules being released for it, so almost all the focus is on Drupal 7. Almost anything really critical has already been done, so most modules now fit into areas of workflow improvement, integration of third-party libraries, developer tools, and addressing the needs of an increasingly mobile audience (responsive design). There are a lot of new modules for image display, for keeping a closer eye on site administration issues, creating better e-shops, deploying content from one site to another, and managing caching, among other trends. It's clear that Drupal 7 is a mature product serving the needs of an extremely diverse community and it's exciting to see all the new ways that, each month, developers encounter new needs and find inventive ways to further extend on the feature-set. So read on to see what new and fun stuff we got in January… (and I promise to try to get February's review done in the next week or so).*/ Access denied backtrace
How many times have you had to try to sort out access issues on a Drupal site? Sometimes this can be a pain, but the module, by Eduardo Garcia of Anexus IT, promises to help put an end to this senseless suffering; it helps track down the exact point at which a particular role is denied access for a particular node or path. Perhaps the screenshot here is a bit contrived; the only reason the basic "authenticated user" cannot create a new node of type "Article" is that they don't have the appropriate permission checked. In a more complex site with lots of custom content and custom user-access code, this could be very useful. (My primary work is on a team where the access model for all content types and users would require a full article to explain.)
Status: There is a stable release available for Drupal 7.Advanced help dialog
The module, by Dan Polant of Commerce Guys, allows developers to extend the popular Advanced Help module. By implementing the provided hook, you can add a link to the "Help" region of specific paths; the link opens a modal box with the relevant "advanced help" content. Nice.
Status: There is a development release available for Drupal 7.Anonymous Redirect
The module, from Michael Strelan of Glo Digital, redirects anonymous users to another domain, but visitors can still reach
/user or
/user/login to authenticate. After logging in, users have normal access. This can easily be configured to limit access to a staging server and redirect users to your production site, the most typical use case for the module.
Status: There is a development release available for Drupal 7.Boost Custom Expire Rules
The module, authored by Zyxware Technologies, allows setting different expiry times for content cached with Boost. Complex rules can be configured to fine-tune how long various content on your site is cached. Older nodes can have a longer cache lifetime, for instance. Rules can be configured for the URL path, node type, age, etc. This definitely looks like a must-have for sites which use Boost, especially if they actively add new content on a regular basis and retain older content.
Status: There are stable releases available for both Drupal 6 and Drupal 7.Block Up Down
The module, coded by Pol Dell'Aiera of Trasys, is dead simple. Just activate it and you get three new contextual links on blocks so you don't need to go into the block administration page just to disable a block or move it up or down within a region. I think this is great, since probably most of the time I go into the block administration page, which can take a while to load on a complex site with a lot of blocks and regions, moving one block up or down (or disabling a block) is all I really want to do, so allowing administrators to manage this from within the front-end is a really sweet feature.
Status: There is a stable release available for Drupal 7.CKEditor Link File
The CKEditor Link File module, created by Devin Carlson, integrates (and requires) the CKEditor Link and File entity modules so that editors on your site can easily add links to existing files on your site. This definitely looks useful for sites which use CKEditor.
Status: There is a stable release available for Drupal 7.Combined Termref
The module, written by Girish Nair, allows you to address up to three different vocabularies with one term-reference field; obviously only one vocabulary in the group can take "free tagging". If new terms are added, they go into the first of the vocabularies selected for the Combined Termref field. There can be good reasons that you need different vocabularies, but the purpose can stay behind the scenes; content creation can be simpler by allowing entry with a single field. I think this looks cool.
Status: There is a beta release available for Drupal 7.Commerce Cart Message
The module, authored by Aidan Lister, provides an option to add rules for displaying messages on your Drupal Commerce cart. This definitely looks useful.
Status: There is a stable release available for Drupal 7.Views Contextual Range Filter
The module, written by Rik de Boer of flink, provides a Views plugin that allows you to filter views based on a range of values for any field where this might make sense. For instance, you might want to filter by price range, age range, etc. This kind of search is a pretty common use case, so I suspect this will become quite popular.
Status: There is a stable release available for Drupal 7.Creative commons field
The module, by Ben Scott, defines a field type for attaching Creative Commons licence types, so you can add CC licences to files or any entity type. There are other modules which can add a CC license, but they only work with nodes; files are likely a most common use case. Cool!
Status: There is a stable release available for Drupal 7.Entity Extras
Categories: Utility
The module, coded by Dave Hall, provides extra utility functions to extend the Entity API module. The idea is to share useful functions here and improve on them before proposing them for inclusion in Entity API or Drupal core. If you aren't a developer, you'll probably only enable this if another module requires it, but if you write your own modules which use the Entity API, this is probably worth taking a look at.
Status: There is an alpha release available for Drupal 7.Facebook Album Fetcher
The module, written by Kaushal Kishore of OSSCube, allows you to import your Facebook albums and photo galleries. You can also import the images from your friends' accounts, too, but be sure you ask your friends if it's okay. Personally, I only allow friends to view my Facebook account, so people like me might be annoyed if the images they shared on Facebook were pulled into a public-facing album without their consent. That said, companies with a Facebook presence might like to pull the images from their Facebook galleries into a gallery on their main website, and I'm sure there are many other good use cases for this module.
Status: There is a stable release available for Drupal 7.Field Collection Deploy
The module, created by Robert Castelo of Code Positive, provides a way to deploy content from the Field Collection fields from one site to another. It extends (and requires) Features, Field Collection (of course), UUID, Node Export, and Entity API. Getting this to work is clearly non-trivial, but if you need this functionality, you'll be happy to find this module.
Status: There is a beta release available for Drupal 7.File Entity Preview
Categories: Media
The module, contributed by Graham Bates of Catch Digital, provides a widget for file fields with previews of uploaded files, as configured with File Entity. It otherwise works like the "core" File widget.
Status: There is a stable release available for Drupal 7.Graphviz
The module, written by Clemens Tolboom, renders a Graphviz text file for further processing; it hooks into Graph API to provide Views integration and can output an image file using the Graphviz Filter.
Status: There is a development release available for Drupal 7.Graph Phyz
is another graph-related module contributed by Clemens Tolboom. It renders an interactive graph using Graph API. Pretty cool, if your site calls for this, and I can think of at least one project where this might have saved some custom coding.
Status: There is a development release available for Drupal 7.Hide PHP Fatal Error
The module, by B-Prod of MaPS System, redirects users to a configurable error page whenever a fatal error is thrown in PHP. Of course the error is also logged into the watchdog so you can work on eliminating the error for the next user. Nice.
Status: There is a stable release available for Drupal 7.Hierarchical taxonomy
The module, by Marcus Deglos of Techito, is a developer module (you won't need this, as a non-coder unless another module requires it) which provides a simple
hierarchical_taxonomy_get_tree() function which renders an array of a vocabulary's hierarchical structure. This should probably be in "core".
Status: There is a development release available for Drupal 7.Image Zoomer
The module, contributed by Tuan, integrates two image zoom-related JQuery plugins; Power Zoomer and Featured Zoomer and the developer of this module is adding support for other modules which provide image zooming. This could be cool for online "catalog" images or for commercial photography sites who want to provide a closer look at an image without making it too simple for users to download a higher-resolution version.
Status: There is a stable release available for Drupal 7.Image Focus Crop
The module, contributed by Nguyễn Hải Nam of Open Web Solutions, helps find the focal center of an image you are scaling and cropping and includes advanced facial recognition algorithms. This looks interesting.
Status: There is a stable release available for Drupal 7.Image formatter link to image style
The module, developed by Manuel García, provides an additional formatter for the core image field so that you can create, for instance, a "thumbnail" which links to a larger, watermarked version of the image. This seems like a common enough need that this kind of functionality should probably be added to core. Until then, there's this.
Status: There is a stable release available for Drupal 7.jQuery UI Slider Field
The module, developed by Sina Salek integrates the jQuery UI Slider plugin so you can easily allow users of your site to utilize a graphical slider to quickly enter an integer value in a field. This looks handy, especially for users accessing your site without a normal keyboard.
Status: There is an alpha release available for Drupal 7.Juicebox HTML5 Responsive Image Galleries
The module, written by Ryan Jacobs integrates the beautiful Juicebox HTML5 responsive gallery library into your Drupal site. There's a lot to this module; probably enough to have a whole article dedicated to ways you can use it, but it definitely looks nice if you want to provide image galleries that render well on a wide range of devices. Like many other such modules that integrate third-party code, it requires Libraries and adding the Juicebox code to your
sites/all/libraries directory. We should note that there are both Lite (free) and Pro (commercial) versions of Juicebox (you'll need to decide which is more appropriate for your use case) and the maintainers of this module are not affiliated with the developers of Juicebox, itself. This module will work to integrate either version of Juicebox.
Status: There is a beta release available for Drupal 7.Lazy Entity
The module, written by James I. Armes of AllPlayers.com, allows field values for Drupal entities to be lazy-loaded rather than loaded at the time the entity loads, so can provide a boost to performance and memory usage. This module is for developers, so will not be useful to you unless you are a coder who needs to lazy-load fields. Otherwise you would only enable this module if another module requires it.
Status: There is a development release available for Drupal 7.Linked Data Tools
The module, by Chris Skene of PreviousNext, is a developer module to help retrieve, cache, and work with linked data sources. It depends on EasyRDF and X Autoload and Guzzle is also recommended.
Status: There is an alpha release available for Drupal 7.Library attach
The module, written by Dave Reid of Palantir.net, adds a Library reference field type so that libraries can be attached to individual entities when rendered, thus saving your site from loading lots of unnecessary Javascript for every page. It also adds an option to the Views UI so allows adding libraries for specific Views displays. This is a great idea!
Status: There is an RC release available for Drupal 7.Lorempixel
The module, written by Fredric Bergström of Wunderkraut, provides "dummy images" which it fetches from the very slick lorempixel.com web service. Oh, and the module can also be used to get the placeholder images added to content by Devel generate.
Status: There is a development release available for Drupal 7.MD WordCloud
The module, written by Neo Khuat, creates a block with a "cloud" of terms from a taxonomy. You'll need to download and add some Javascript files to the module's "js" folder. So you don't need to save and replace the Javascript files, it might be better to symlink them to a directory in
Status: There is a stable release available for Drupal 7.Multisite wizard
The module, written by Alex Posidelov, helps simplify the process of converting a single site Drupal installation to multisite. A lot of the work is done for you with just one click of a button and it helps lead the administrator through the rest of the requirements. It depends on the Backup and Migrate module.
Status: There is a stable release available for Drupal 7.Notify 404
, by teknic of Appnovation Technologies, provides a means to send notification emails to a site administrator when a configurable volume or frequency of 404 (page not found) errors have occurred.
Status: There is a stable release available for Drupal 7.Photobox
The module, developed by Andrew Berezovsky of Axel Springer Russia, adds an Image field formatter for viewing images in a Photobox image gallery. You'll need to use the jQuery Update module since Photobox requires jQuery 1.8. This does look nice.
Status: There is a development release available for Drupal 7.RecommenderGhost
The module, coded by hhhc, integrates the free recommender services hosted by RecommenderGhost. It makes it easy to display recommendations for "other visitors bought…", etc. This is much simpler than installing and integrating a separate server.
Status: There is a stable release available for Drupal 7.Reference helper
Categories: Fields
The module, created by Kevin Miller of Cal State Monterey Bay, is a helper module for displaying recent or most relevant entities under an entity reference field and was a winner of the Module Off challenge. It definitely sounds useful.
Status: There is a development release available for Drupal 7.Regcheck
The module, produced by Tobias Haugen of Wunderkraut, adds a hidden checkbox to your site's registration form; if checked, the registration process is aborted. "Robot" users tend to check the box, so it can be a simple way to eliminate at least some of the unwanted registrations used for spamming your site or other nefarious purposes. There are other modules which help with protecting forms like this, but a wide variety of spam prevention methods are useful for keeping a step ahead of the bot coders.
Status: There are stable releases available for both Drupal 6 and Drupal 7.Simple hierarchical select
The module, written by Stefan Borchert of undpaul, defines a new form widget for hierarchical taxonomy fields so you can simply navigate the structure of the taxonomy and select a term.
Status: There is a stable release available for Drupal 7.Site Disclaimer
The module, by Ilya I, can add "Terms of Use", "Privacy policy" or other agreements to the registration form. Visitors who want to register on your site need to agree to the terms of the "disclaimer" in order to register.
Status: There is a stable stable release available for Drupal 7.Tablesorter
The module, coded by Shoaib Rehman Mirza of Xululabs, integrates the tablesorter jQuery plugin so that any standard HTML table with
THEAD and
TBODY tags can be turned into a sortable table without even requiring a page refresh. Of course it's not helpful if the data is paginated, but for normal tables with all the data on one page, this could be useful. Of course you need to download the Javascript libraries and install them in your sites/all/libraries directory, and of course that means this depends on Libraries API.
Status: There is a stable release available for Drupal 7.Taxonomy Protect
The module, contributed by Jay Beaton allows administrators to select certain taxonomy vocabularies and prevent them from being deleted. That way, even if some users who need to be able to administer taxonomies don't fully understand the system, they won't make the mistake of deleting a critical vocabulary.
Status: There is a stable release available for Drupal 7.Topbar Messages
The module, created by Mark Koester of Int3c.com: International Cross-Cultural Consulting, allows you to add a message in the top of your Drupal pages. The message can be dismissed with a click on a "close" link and can include links and other formatting. There are other such modules, but this one might be the best fit for your use case. It does look useful.
Status: There is a development release available for Drupal 7.Views Ajax Fade
The module, authored by Thomas Lattimore of Classic Graphics, is a Views plugin which allows you to add a fade in/out effect for Ajax-enabled Views displays. This would be nice for some use cases.
Status: There is a stable release available for Drupal 7.Webform Countdown
Categories: Content
The module, by Andrew Lindsay provides a textarea component for Drupal webforms which includes a configurable, Twitter-style dynamic word or character count to limit the length of submissions. Of course it requires the Webformmodule and Libraries module (as well as the word-and-character-counter.js in
Status: There is a beta release available for Drupal 7.Webform Postal Code
Categories: Content
The module, is another Webform-enhancing module contributed by Andrew Lindsay. It adds strong, configurable postal code validation which can even be set to handle multiple countries simultaneously. In addition to the obvious dependency on Webform, this also requires the Postal Code Validation module.
Status: There is a beta release available for Drupal 7.
Closing out the year 2012 with a bang, December brought us quite a number of new modules which look promising enough to cover; a few that I'm covering this time are far from ready or even only at the "concept" stage and normally would not be included, but they seemed particularly interesting or unique, and I want to see how they develop. Anyway, this month there were quite a few modules released for mobile support/responsive content. There were also several search-related modules, anti-spam modules, a couple of novelty modules, some interesting commerce-related releases, a number of Features package modules customized for various special-purpose distributions, lots of new "Third-party Integration" modules, theme enhancements, and more… I only wish I had more time so I could actually try out more of them, but there are several I do plan to get back to.
As usual, this post is sorted alphabetically and only covers modules which had their first release, or at least a new project created, in December. Selection for the Modules of the Month is a completely arbitrary process, but normally excludes common or niche items like a new payment method for Commerce that provides connections for a payment system used in, e.g. Romania. We also don't normally include commercial service integration modules (unless the service looks really cool and is reasonably priced).
Anyway, it seems like only last week that I was putting the final touches on the November "Modules of the Month" story… oh wait, it was only last week: nine days ago, as I write this. Well I promised to try to get December's published in early January, so I pushed some days around to make this happen. Let's take a look at the modules, then, shall we? …*/ Activation Code
The module, brought to us by prolific über-contributor Bryan Ollendyke of Penn State University, provides a fieldable "activation_code" entity type with a number of fields for an ID, creation timestamp, redemption timestamp, username, etc. It's used by the Course Information System distribution as another method for authorizing access to online course materials, etc, but for those who don't need the module on their site, it could still provide a useful example for how to build a fieldable entity.
Status: There is a development release available for Drupal 7.Apachesolr Link
Categories: Search
The module, produced by Michael Prasuhn of Shomeya, enables indexing a Link field's "target", along with the entity it is attached to, in the Apache Solr search index. It might be obvious, but this module depends on Link and Apache Solr Search Integration; the Apache Solr Attachments module will also be useful if some of the links you wish to index are to PDF files or other "non-plain-text" results which you wish to index.
Status: There is a development release available for Drupal 7.Are You A Human PlayThru
The module, written by Chris Keller of Commercial Progression, provides a more simple, fun, and intuitive means for a user to prove they are human than typical CAPTCHA options. It uses game mechanics which a user interacts with rather than having users try to interpret text in graphics. CAPTCHA fields can be frustratingly and tedious, so it's nice to see people are working on interesting alternatives. Cool! I often skip over commercial third-party integration modules, but this seems interesting enough not to pass up, and they do provide free options which might be adequate for many sites.
Status: There is a beta release available for Drupal 7.Backstretch Formatter
Status: There is a development release available for Drupal 7.Badbot
Status: There is a stable release available for Drupal 7.BetterTip
The module, produced by Shoaib Rehman Mirza of Xululabs, is a lightweight jQuery plugin for clean, HTML5-valid tooltips which can provide a richer user experience than default tooltip text.
Status: There is a stable release available for Drupal 7 (and the project page includes a pledge to provide a Drupal 6 version).Breakpoint Panels
Status: There is a stable release available for Drupal 7.Christmas Lights
The module, created by Andrew Podlubnyj, is, depending on your use case, of course, probably just a novelty module, but one that might be fun to enable in the right season. It adds decorative "Christmas lights" for you and your users to enjoy.
Status: There is a stable release available for Drupal 7.CKEditor for WYSIWYG Module
When Nathan Haug of Lullabot-fame releases a new module, it's always GoodStuff™, so it's no surprise that there are already hundreds of sites using the after just one month. It provides a WYSIWYG editor (surprise, surprise!) using the CKEditor library (surprise, again!). This project aims to combine some of the best of the Wysiwyg-module integration with CKEditor with the best of the standalone CKEditor-integration module, with support for the Drupal Image and Drupal Image captioning plugins, compatibility with other WYSIWYG editors integrated through the Wysiwyg module, and no inline styles inserted into HTML… among other nice features either already implemented or in the "roadmap". It requires the Wysiwyg module and is incompatible with the normal CKEditor integration module (which must be completely removed before using this module).
Status: There is a development release available for Drupal 7.Coins wallet
The module, authored by ssm2017 Binder, is a Bitcoin wallet system to be used with a devcoin-compatible daemon. This module is a complete rewrite for Drupal 7 of the never-released original Drupal 6 version discussed here and uses the bitcoin-php library. While I confess that I'm a bit leery of how this all works, I'm also fascinated by the idea of alternative currencies which aren't controlled and manipulated by bankers and other "white collar criminals", so while the optimist in me is curious to see how this works, the pessimist in me worries that between human greed and governmental attempts to rein this in, well… interesting work, in any case.
Status: There is a stable release available for Drupal 7.Collapsible fieldset memory
Status: There are alpha releases available for both Drupal 6 and Drupal 7.Commerce Check
Status: There is an alpha release available for Drupal 7.Commerce Message
The module, produced by Bojan Živanović of Commerce Guys, provides Commerce-specific Message integration, including some default message settings for common order states, such as "order paid", "product added to cart", "order confirmation", etc. It looks like a pretty well-thought-out module to help provide automated or custom messages to clients at appropriate stages in their order process. It's integrated with Commerce Backoffice and Commerce Kickstart v2, so is already in use on quite a number of sites.
Status: There is a beta release available for Drupal 7.Commons Polls
The module, by Ezra Barnett Gildesgame of Acquia, and the primary maintainer of Drupal Commons, integrates Drupal's "core" Poll module as a group-enabled content type in Drupal Commons 3.0.
Status: There is a development release available for Drupal 7.Content callback If you register a content callback via
hook_content_callback_info() it will be available in the Content callback field options.
—Project description excerpt
The module, developed by Jasper Knops of Nascom, allows you to return any renderable array, created in code, via a field; it also contains a sub-module which provides a searchable Views display, as well as a context condition, among other features you should check out on the project page. If it's not clear, though, I might mention this is not a simple add-and-enable module; it provides some tools for coders and advanced site builders.
Status: There is a stable release available for Drupal 7.Context Breakpoint
The module, developed by Christoph, helps bridge Context and Breakpoints so that you can alter a page based on the visitor's screen resolution, browser window size, or aspect ratio. Installing it adds a context condition for "Breakpoint". This could definitely be useful, especially if your site already uses Context. Of course it's a bit complex, so please see the project page and the module's README file for information about how to install, configure, and make use of this.
Status: There is an alpha release available for Drupal 7.Context code
The is another module by Jasper Knops of Nascom. It provides "a new context condition plugin which allows you to trigger contexts from code". It should probably go without saying that it requires the Context module and is a module developed for other developers. See the project page for implementation examples, but I think this looks very useful, at least for advanced Drupalists and coders.
Status: There is a stable release available for Drupal 7.CP2P2: Content Profile to Profile2
The module, written by Damien McKenna of Mediacurrent, is an add-on for Profile2 to convert Content Profile content types into Profile types. Note that there is no admin user interface for this; all functionality is provided by Drush commands run in the terminal, so this module is targeted toward experienced Drupalists and coders.
Status: There is a beta release available for Drupal 7.Create and continue
The module, written by Dominique De Cooman of Ausy/DataFlow, simply adds a button to node forms which saves the current node and opens
node/add/CONTENT_TYPE to create another instance of the same node type and help streamline the content creation process.
Status: There is a stable release available for Drupal 7.Crossdomain
Categories: Media
The module, written by Adam Moore of Stanford Graduate School of Business, simply creates a
crossdomain.xml file at the root of your Drupal site and provides configuration setting for which domains should be included. This is useful for certain web services which may require different domains to have access to your site content.
Status: There is a stable release available for Drupal 7.Currency for Drupal Commerce
The module, produced by Bart Feenstra replaces the native currency-based price display in Drupal Commerce with locale-based display, using the Currency module. Because proper display depends on locale (language and country) and not on currencies, this module helps ensure that users see prices in a format they are used to.
Status: There is a beta release available for Drupal 7.Field Quick Required
The module, written by Jelle Sebreghts of attiks, provides a simple overview of which field are required for a given content type, without having to enter the settings for that field. You can also change the "required" setting for any field. Nice! It does this by adding an extra column to the "manage fields" overview for your content types, e.g. for
/admin/structure/types/manage/article/fields, where you would normally have columns for "Label", "Machine name", "Field type", "Widget", and "Operations", you would also have a column labeled "Required" with a checkbox that can easily be changed if you decide a certain field should (or should not) be required for a particular content type. This could be especially useful during the initial phases of designing a site's content types and logic.
Status: There is a stable release available for Drupal 7."File Metadata Table" Field Formatter
Categories: Fields
The module, written by Jeremy Thorson, with support from Derek Wright, looks interesting. It's still in development, but it provides a customizable "File Metadata Table" field formatter for file fields. All of the options are a bit much to list here, but given the profiles of these two super-contributors, I think this will be an interesting module to check back on. I'm expecting something awesome here!
Status: There is a development release available for Drupal 7.Foresight Images
sites/all/libraries. I'm not convinced that this module offers enough benefits to select it rather than one of the other more-established responsive image modules; I'm also not convinced otherwise and the Foresight Images project page includes a list of other "similar" responsive images modules and some brief notes about how the approach or features differ from those provided by Foresight Images. So this project page could be worth looking at if you need an overview to help choose the appropriate module(s) or approach for your next project.
Status: There is a stable release available for Drupal 7.Forum notifications
The module, created by David Snopek, extends the Notifications module to add some nice UI improvements for notifications involving forums based on the "core" Forums module. If you have a site with forums and wish to have a nice user experience for "subscribing" (and "unsubscribing") to forums or individual threads, this module could help.
Status: There is a development release available for Drupal 7 and a beta release available for Drupal 6.htaccess
The module, coded by giorgio79, autogenerates a Drupal root htaccess file based on your settings, including such configuration settings as automatic insertion of Boost htaccess settings, whether or not to use "www",
Followsymlinks or
SymlinksIfOwnersMatch, etc. You simply configure these settings at
/admin/config/system/htaccess if this module is enabled and of course you could only enable this module when upgrading Drupal, to replace the default
.htaccess with one based on your settings. I don't think it should be so dangerous to try this, but you might want to make your own backup copy of your current
.htaccess file, just in case anything goes wrong (in theory, this module should also make a backup copy of your existing
.htaccess file).
Status: There is a stable release available for Drupal 7.Image optimize effect
The module, yet another contributed by Peter Droogmans of Attiks, adds two new image effects to optimize image files to reduce your average page size. Most websites do not have very well optimized images and images can be substantially reduced in size, even without noticeable change in quality. This module uses pngquant to optimize png files and imgmin, which can work on various formats, but is best for JPEG files. Of course it depends on the relevant libraries (see the project description). For more information, see this recent article on the Performance Calendar blog: Giving Your Images an Extra Squeeze
Status: There is a stable release available for Drupal 7.Image Style Pregenerate
The module, developed by Gabor Szanto, helps you to generate all the images for a new image style before enabling the style; it's designed for bulk image generation on production sites where the performance hit of switching the image style in your field formatter without already having the new images in place, could result in issues. It relies on Views Bulk Operations (VBO) and File Entity.
Status: There is a development release available for Drupal 7.Insert image with text
Categories: Content
The module, developed by Esben von Buchwald of Reload!, extends the Insert module to modify the image markup to include caption text below the image. I don't know how this compares to other methods of adding an image caption, but if you are already using Insert, and you want a simple way to include image captions, this module could be useful.
Status: There are dev releases available for both Drupal 6 and Drupal 7.Joyride
The module, written by Mark Koester of Int3c.com: International Cross-Cultural Consulting, integrates the Joyride plugin to provide a simple way to give a tour of features or information on your Drupal-based site. This looks pretty cool. Of course you need to download the Javascript and install it in your
sites/all/libraries directory… and of course that means it also requires the Libraries module.
Status: There is a development release available for Drupal 7.jQuery Tabs Field
The module, contributed by Varun Mishra, allows you to create up to seven tab fields, each with a "body" and "tab title" on any node where this field is part of the content type. On viewing the node, the module will format the output to display each as horizontal tabs, which can make for more attractive output. This is relatively simple compared to options where you could have a number of fields in each tab, but if it fills the requirements of your use case, this simplicity would be ideal. There are already quite a few sites using this and it should become much more useful when the "body" of each tab supports HTML formats (currently it only accepts plain text, but the first issue for this module has elicited a promise to get HTML support in there.)
Status: There is a stable release available for Drupal 7.Kazoo API
The module, contributed by Bevan Rudge of Drupal.geek.nz, integrates the Kazoo REST API telecommunications platform into Drupal-based sites. This is fairly complex and the use cases for this are somewhat limited, so I'm not going to bother going into great detail, but it's interesting to know about, nonetheless.
Status: There is a development release available for Drupal 7.Kim Jong-filter
The module, coded by the prolific Peter Lieverdink of Creative Contingencies, provides an input filter that wraps all occurrences of names of great leaders in a
<span> element with a suitable class for easy highlighting. Of course you could use it for other purposes, so this might be more than an odd novelty module.
Status: There is a development release available for Drupal 7.Language fallback
The module, written by Peter Droogmans, a very active contributor who has done a lot for multilingual functionality in Drupal, allows you to specify a fallback language for each language on your site, so if a string is found untranslated in the preferred language, you can get the next closest language translation file. Example use cases are for regional variants of a language, so if there is no translation in "nl-be" (Belgian Dutch), it would default to a translation found in Netherlands Dutch "nl-nl" and finally default to a standard translation found in "nl", if available. This could certainly be useful and I believe this is a backport of functionality that's already been built into Drupal 8 "core" (if not, I suspect it will be ported to Drupal 8 as a contrib module).
Status: There is a stable release available for Drupal 7.Layouter - WYSIWYG layout templates
The module, from Alexander of ADCI, LLC, provides a simple way to select a particular "layout" (e.g. columns) for content. It already integrates with the CKEditor and the developer plans support for other popular editors, but it can apparently be used without a WYSIWYG editor, too.
Status: There is a stable release available for Drupal 7.Lazyloader filter
The module, authored by Derek Webb of CollectiveColors, provides an input filter for lazy loading images as they may appear in textareas and relies on the Lazyloader project for the actual lazy-loading of images. This module only provides a filter that renders
<img> tags in a manner consistent with the needs of the Lazyloader module, while allowing you to theme the image output to your liking and preserve original image attributes. This looks useful.
Status: There is a stable release available for Drupal 7.Leaflet MapBox
The module, contributed by Jaime Herencia of WebPartners, provides integration between another Drupal contrib module, Leaflet (which integrates the Leaflet JavaScript mapping library), and MapBox. The Leaflet module's project page actually links to an example which uses Mapbox: The Intertwine, which documents trails in the Portland-Vancouver metropolitan region. This site really looks cool, so if mapping functionality is important for your site, this might be useful for you.
Caveat: Mapbox is not a free service, but is reasonably priced and includes some pretty cool tools and features, not to mention distributed map hosting.
Status: There is a stable release available for Drupal 7.Link CSS
The module, created by Graham Bates of Catch Digital, allows you to add CSS files using the
<link> element instead of
@import. This is useful for live refresh workflows such as CodeKit which do not support files loaded with
Status: There is a stable release available for Drupal 7.Local Foodhub Local Foodhub defines the commerce functionality to support a foodhub in a community, where producers and consumers attend a regular collection day where ordered products can be collected. Foodhubs are a convenient way to provide local produce for people in the community while giving producers more regular orders.
—Project description
The module, developed by Paul Mackay, is a project description which definitely looks interesting, although there is, as of this time, no code released. Normally I don't include modules in this column if there aren't at least some Git code commits, but there is enough information already, and I like the idea well enough that I'm making an exception here. We need to have more local food production and distribution… and infrastructure to support this if we want to live in a future with more environmentally sustainable practices, so on behalf of my future children and grandchildren, I give thanks for people working on projects like this.
Status: Check back. Currently no project code.Mobile Switch (Varnish version)
The module, developed by Paul Maddern of ITV, provides a simple automatic theme switch functionality for mobile devices, utilising Varnish for detecting the user-agent and providing proper cacheable pages using the same URLs per mobile device group. This helps avoid bootstrapping Drupal while still presenting the appropriate, cached content for each device type. Nice! Of course getting this all right is not simple, so be sure to peruse the project page for more complete implementation details.
Status: There is a stable release available for Drupal 7.Moodle Connector
The module, produced by Pere Orga, aims to provide a common interface for modules that integrate Drupal with the open-source Moodle e-learning system. It does not provide any end-user features and the initial release simple adds an admin configuration page for you to enter Moodle credentials, but there are plans for some other appropriate features. If you have a site that bridges Drupal and Moodle, this could be a worthwhile module for you.
Status: There is a stable release available for Drupal 7.Multilingual Panels
The module, created by Valeriy Sokolov, provides support for making Panels panes translatable, which could definitely be useful for multilingual sites which make use of Panels.
Status: There is a development release available for Drupal 7.Organic Groups formatters
The module, produced by Eric Mulder of LimoenGroen, extends Organic Groups by adding additional field formatters for the "Groups Audience" field. The "Group delimited list" formatter allows you to display Group names (labels) as a delimited list. Other formatters may be added if requested in the issue queue.
Status: There is a stable release available for Drupal 7.Panels Image Link
The module, authored by Nick Piacentine of the Mars Space Flight Facility at Arizona State University, provides a simple Panels content type to display an uploaded image and link it to a provided url/path. There are already quite a few sites using this, considering its very recent release, so I suppose this could become quite popular for sites using Panels.
Status: There is a stable release available for Drupal 7.Pants
The module, produced by Angie Byron of Acquia, is an actual module instead of just code used in a tutorial demonstration, but the purpose is the same. The previous version of the Pants "module" (not actually released) was for Drupal 5. This project updates it to Drupal 7 code and may be used as part of Angie's DrupalCon Sydney core conversation presentation about "Upgrading your modules", which will cover getting Drupal 7 code ready to run in Drupal 8.
Status: There is a development release available for Drupal 7.PDF Forms API
The module, authored by Kevin Kaland of WizOne Solutions, is an API module which you should only install if another module requires it or if you are a developer and want to use its functions, which are initially focused on PDF form functionality.
Status: There is a development release available for Drupal 7.Pinterest Verify Website
The module, written by Peter Lieverdink of Creative Contingencies, simplifies the verication process for pinterest by adding a verification tag or page to a Drupal site.
Status: There is a development release available for Drupal 7.Polychotomous Keys
The module, written by Ed Baker of the Natural History Museum, "allows you to build polychotomous keys using Views". At least that is the "project description", but currently there is not even a single code commit. While that would normally mean I'd skip the project for inclusion here, I'm interested in modules being developed for academics and there could be a lot of use cases for such a module. I'm looking forward to seeing it in action.
Status: Check back. Currently no project code available.Prelaunch
The module, written by Dominique De Cooman of Ausy/DataFlow, allows you to set one page of a Drupal site as "prelaunch page". An example use case might be to display a webform to collect emails to notify interested parties when your site is launched, or page with information about what's coming. Your site can essentially be "offline" without using maintenance mode; it prevents users from accessing any part of the site besides the prelaunch page (although assigned roles can access other areas). This definitely sounds useful.
Status: There is a stable release available for Drupal 7.Pushtape Admin
is actually a Drupal distribution for musicians, which was initially released about 18 months ago. So why am I including it here? Well, I'm not really, but there are five new Features package modules which were released in December which are all geared toward improving support for building sites with Pushtape and which might be useful even if you aren't using the distribution. All of the following modules were contributed by Farsheed of Zirafa Works:
- contains admin views and menus.
- adds a simple file field to the Track content type to allow uploading mp3 files.
- configures an event content type, view, and menu link.
- creates a news content type, view, and menu link.
- creates a simple photo-set to share a group of photos. Content type, views, and menu link are bundled; this also uses Colorbox.
Status: For each of these modules, there are development releases available for Drupal 7.Radix Layouts
The module, produced by Arshad Chummun, provides responsive panels layouts set to work with Panopoly and the Radix theme (also contributed by Arshad Chummun). If you are using Panopoly, you might like Radix and if you are using Radix, you might like this module, especially if you need responsive layouts for mobile devices.
Status: There is a development release available for Drupal 7.Restaurant
is a new distribution, also developed by Arshad Chummun, which is based on Panopoly and designed to simplify hosting websites for restaurants. Several supporting modules were also released in December:
- provides base configuration and structure.
- adds a blog system.
- provides structure for creating and managing events.
- provides structure for creating and managing menus.
- provides structure for creating and managing slideshows.
- adds theming helpers.
Status: There are development releases available for Drupal 7 for the Restaurant distribution and each of the listed supporting modules.Search API Stanbol
The module, written by Stéphane Corlosquet and Wolfgang Ziegler provides Drupal integration with Apache Stanbol, a new and exciting search technology for extracting information from "unstructured" text content. Getting into the full details of how this works is well outside the scope of this column, but this definitely does look interesting. This module requires the Search API and RDF Extensions modules.
Status: There is an alpha release available for Drupal 7.Single Image Formatter
Categories: Fields
The module, created by Federico Jaramillo of SeeD, exposes a formatter that displays one image from a multi-value image field. It allows the same options as the original image formatter, but adds an option to choose which image to display. For some use cases, the Field multiple limit may be more suitable, but the Single Image Formatter might be more efficient for situations where there are many values in a multi-value image field.
Status: There is a stable release available for Drupal 7.Sky field
The module, created by Leonid Mamaev and Alexander of ADCI, LLC, is sort of a new, improved version of the Node field module released a few months back by the same developers. It allows you to add unique custom fields to any single Drupal entity (node, user, comment, etc). You can add text fields, long text fields, links, radios, select, checkbox, taxonomy terms, among others and includes an API to add support for additional field types. This could be very useful for sites where an occasional instance might benefit from an extra field that isn't normally used for that content type.
Status: There is a beta release available for Drupal 7.Twitter Web Intents
Categories: Views
The module, developed by Francisco José Cruz Romanos of Hiberus, integrates Twitter's Web Intents system to add extra Twitter links for replying, retweeting, adding to favorites, following, etc, into a view of Twitter messages. This allows users to interact with Twitter content from within the context of your site, without needing to leave the page or authorize an app just for this interaction.
Status: There is a stable release available for Drupal 7.Twysi
The module, created by Tony Star of Acronis, is "an amazing Twitter Bootstrap WYSIWYG HTML5 editor", at least that's what the project description says. But it might be a bit early to tell about the module, itself. Currently, if I install the wysihtml5 library, I can select it as the editor for a given text format, but no buttons are present and no editor shows up on a text area. That said, this does sound like a project worth checking back on.
Status: There is a development release available for Drupal 7.URL token URL token is an API module that provides token-based authentication for other modules, where the token can be used in URLs without requiring a Drupal user. Tokens can also be limited to a set number of uses or a fixed period of time.
—from the project's README.txt
The module, by Marcus Deglos of Techito, is "an API module to make token-based access control simple". Normal users should only install this module if another module requires it. Developers might want to take a look at the project page for some decent code examples of how to request a token and check that a token is valid. Note: in case this is not obvious, this module has nothing to do with the Token module. "Token", in this context, is simply an access key.
Status: There is a development release available for Drupal 7.Views OG cache
The module, from long-time contributor Amitai Burstein of Gizra, adds a Views time-based cache, configurable per group; uses OG-context to identify a group's view to cache; includes OG-access integration: if the group is private, caching is done per-user instead of per-group… among other listed features. This definitely looks like it could be useful for sites using both Organic Groups and Views.
Status: There is a development release available for Drupal 7.Welcome
The module, from Blair Wadman displays a simple, configurable welcome message when a user logs in. Simply enable it at
admin/config/people/welcome, and yes Token support is included. The example message displayed at left uses Tokens for both the site-name and username. (Of course the "Swachula" username is courtesy of "Devel generate" and "d7test" is my local Drupal 7 testing environment.)
Status: There is a development release available for Drupal 7.Yet Another Yellow Box This is mostly being used to announce weather-related school closings on sites where I've been using it.
—from the project description
The module, authored by Micah Webner of Access-Interactive, provides a simple way to add a prominent "announcement" block of filtered text to any pre-configured region. The contents and visibility of the announcement block can then be managed by users who may not otherwise have permission to manage blocks. If you have a site where staff may need to make emergency announcements, this could be a useful module to set up. See the project page for further information about how to get everything working.
Status: There is a development release available for Drupal 7 and a stable release available for Drupal 6.Zoundation Support
The module, written by Jeff Graham of FunnyMonkey, is designed to work with the responsive HTML5-based zoundation theme and its sub-themes. It provides custom menu builder functions and blocks for menus, a foundation navbar and topbar, a custom field formatter for orbit slideshow integration, improved placeholder integration for elements, and "other minor UI improvements" that work better in this module than in the zoundation theme, itself.
Status: There is a development release available for Drupal 7.
November 2012 was a busy month for a lot of people involved in Drupal contribution. It was the final weeks before the "feature freeze" for Drupal 8, so a lot of the focus was on new features for the next great release of Drupal. Many of the "new projects" were simply "namespace reservations" for new core modules or planned contrib modules which relate to Drupal 8; most of which had no project code committed at all (for some, presumably, it's all in the main Drupal 8 repository). But there were also a number of new feature-enhancing modules released for Drupal 7 (and a few for Drupal 6), several which improve search functionality, a few for delivering mobile-friendly content from a Drupal site, some for commerce, others designed to help manage Drupal sites and ensure that nothing slips through the cracks when moving from "development" to "production", among other new gems.
It's fun, too, that we got a couple new "novelty" modules in November: one, Driesday, puts a "Happy Driesday!" message on your site every November 19th; another is a bit more insidious, with a fully-disclosed dependency on Bad judgement: Feature creep allows you to nostalgically hang onto the "good old days" when Features had a few more quirks. So if you want to remember that fun, just turn this module on and, as the module description says, "every time that you export or update a feature the Feature creep module will randomly add an extra component to your feature, what fun!"
Before we get into the module descriptions, of course, I should acknowledge the very late arrival of this month's release of this column. It's been one of those months… again. But let me try to hold onto my optimism that I'll be seeing you with December's write-up in just a couple weeks. I'll be aiming for the first week of January. Now let's have a look at the "new" modules.*/ Apache Solr Term Proximity
The module, coded by the prolific Chris Pliakas of Acquia fame, should be of interest for sites using Apache Solr. It boosts the relevancy of documents in which the search terms appear closer together. In other words, if I'm searching for "data migration", a document which has these two words together should rank higher than another document where they are separated by a few words, which should rank higher than one where these words appear in different paragraphs. Nice!
Status: There is an RC release available for Drupal 7.bigint
Categories: Fields
It's always nice when developers share modules which help to get around some of the native limits in Drupal. One such limit is the lack of a proper "BigInt" integer type, which might not be needed for most sites, but is certainly a limitation that developers have to work around for some use cases. The module, by Ryan Coulombe of NewMedia!, provides a true BigInt field, thus saving site builders from having to find creative ways to handle text or decimal values that they really want to be an integer. Cool!
Status: There is a stable release available for Drupal 7.Block Group
Categories: Utility
The module, by znerol, provides a taste of Drupal 8-like layouts by extending the Drupal block system with "block groups" which can be placed like a normal block, are nestable, and can have regions within them. A simple use case might be that you want all of your user-related blocks to be kept together in one "user blocks" block group, which you can then put into whatever theme region you wish, without having to always fix their order when adding them to a different theme or reorder them if you change the region. Very handy!
Status: There is an alpha release available for Drupal 7.Book Touch
The module, which requires the Thumbnav module, is another innovation from Bryan Ollendyke of Penn State University, who has been contributing loads of great modules in recent months. It provides gestures and touch events for mobile navigation of an online book to help replicate the experience of a touch-sensitive e-book reader. Most awesome!
Status: There is a beta release available for Drupal 7.Bounce reasons
The module, produced by Alexander of ADCI, LLC, may or may not be a good idea. It pops up a Webform in an overlay, when your site visitors attempt to close a window, where you can ask why they are leaving. Personally, I think I would just find this annoying and might likely avoid following future links to the site, but that's just my initial reaction; maybe I'm not the typical web user and it's possible that in some cultures people wouldn't mind a site preventing a window from being closed to ask them why. That said, maybe it would be better to provide an "opt-in" for such an "exit poll" feature, i.e. ask visitors when they arrive to your site if they wouldn't mind being asked about their experience when they leave. But perhaps you have a client who has asked you to build exactly this functionality? If so, rather than argue with them about why this might not be a good idea, you now know "there is a module for that". And maybe using this for a while would help them improve their site. The project description page doesn't specifically mention it, but it would seem to depend on Webform… and possibly also Bad judgement. Hmmm…
Status: There are stable releases available for both Drupal 6 and Drupal 7.ckeditor_syntaxhighlighter
sites/all/libraries per installation directions (and the Libraries module, of course).
Status: There is a stable release available for Drupal 7.Commerce Backoffice
The module, by Bojan Živanović of Commerce Guys, provides administration enhancements for Drupal Commerce and is already in use on over 2,000 sites less than a month after its release (perhaps largely since it's a component of the latest release of the Commerce Kickstart distribution). It includes three sub-modules, each of which have a number of dependencies and the project page does a good job of explaining everything, so I won't say more than this: if you are using Commerce and aren't using the Kickstart distribution, you will probably benefit from adding and configuring this module.
Status: There is a stable release available for Drupal 7.Commerce Price Extra
The module, from Marc ElBichon, adds extra features based on the price component in Drupal Commerce, including allowing ordering of price components in the cart pane, printing discounts on their own line, and other nifty features.
Status: There is a stable release available for Drupal 7.Commerce Rules Extra
The module, also developed by Marc ElBichon, is a library of Rules events, conditions, and actions to support Drupal Commerce site building.
My wish is to merge all modules based on Rules and Drupal Commerce in a single one. It forks the apparently-unmaintained Commerce Extra Rules Conditions module. See the project page for more information about what this module already supports or to suggest additional features.
Status: There is an alpha release available for Drupal 7.Commerce Search API
Categories: Search
The another module, contributed by Bojan Živanović of Commerce Guys, provides Commerce-specific Search API integration and fulfills a feature request that dates back to the early days of Commerce. It was covered on Commerce Module Tuesday and is part of the latest Commerce Kickstart, so is already used by many sites. If you don't use Kickstart, and want improved search functions for your Commerce-based site, this is a good module to consider.
Status: There is an RC release available for Drupal 7.Context Block Visibility
The module, coded by Peter Berryman, provides context for block visibility using the normal block admin page. This could be handy for certain use cases.
Status: There is an alpha release available for Drupal 7.Dictionary Export
The module, coded by Ed Baker of the Natural History Museum, provides support for Microsoft Office-compatible dictionaries in (*.dic) format for any vocabulary on your site.
Status: There is a stable release available for Drupal 7.Download Userpoints
The module, by Eugen, provides a way for you to allow access to private files via user points. This looks useful for communities which provide points for contribution and require points for downloads of community-contributed files (as one example use-case). It requires the Userpoints module.
Status: There is a beta release available for Drupal 7.Drifter
The module, produced by Peter Anderson of PackWeb, allows fields to be floated to the left or right of content. While this kind of layout is normally provided by theme CSS, it can be useful for it to be theme-independent.
Status: There is a stable release available for Drupal 7.EasyRdf
The module, from Chris Skene of PreviousNext, provides Libraries API compatibility for EasyRdf, which, in turn requires Libraries . It should only be installed if other modules require, but definitely looks useful.
Status: There is an alpha release available for Drupal 7.Entity reference multiple display
The module, written by Jean Valverde of Linagora, provides a new field formatter for Entity Reference that let you configure different view modes for each referenced entity, for instance if you want the first elements to be displayed in full and subsequent elements to be displayed as teasers, this module could be your friend.
Status: There is a stable release available for Drupal 7.Entity Reference Views Formatter
Categories: Fields
The module, authored by Maxim Podorov, provides a Views-based entity reference field formatter which allows you to use any view to show entity reference field value(s). It's based on the Entity Reference View Field Formatter (sandbox) project from Katherine Bailey.
Status: There is a development release available for Drupal 7.Facebook Autopost
The module, written by Mateu Aguiló Bosch of Human Bits, provides simple configuration to allow your site to automatically post to designated Facebook Pages. It includes a good developer API, integrates with Rules and the Entity API and includes Libraries integration for the Facebook Developer PHP SDK. It includes a Facebook app, which you authorize to make posts on the designated accounts' behalf. There is a detailed video tutorial on the setup process linked on the project page.
Status: There is an alpha release available for Drupal 7.Field Formatter CSS Class
The module, by Christian Zuckschwerdt, is perhaps a bit similar to the aforementioned Drifter module; it adds a CSS selector for fields so that you can select to, for example, use a class which floats an element left or right on a per-node basis. Of course you need to set up your theme for the classes and configure your fields, so it's not a simple "add-and-activate" module, but it should give content authors a bit more control of display for individual nodes. The author invites the community to request additional features, so I think this will definitely be useful for a lot of sites (and there are already quite a few using it). Nice!
Status: There is a stable release available for Drupal 7.Final Polish
Categories: Utility
The module, by Yannick Leyendecker of LOOM GmbH, helps take care of some of the last steps that are often forgotten when launching a Drupal site. It allows you to disable access to paths like
/rss.xml, etc; it uploads a "touch icon" to be used by mobile devices; it verifies the existence of
/apple-touch-icon.png, etc, so that you don't get a plethora of 404 errors in the logs, and the author invites input for additional features, but already has a nice development road-map to include checking recipients for Webform emails, checking the site email address, redirecting to the front page on errors (access denied / not found), etc. This can definitely streamline the last steps of getting our sites ready for use, so I'll definitely be giving this a try.
Status: There is a development release available for Drupal 7.Gumroad
The module, from Eric Peterson of Tableau Software, helps use Gumroad to sell products on a Drupal website. I normally skip over modules which integrate commercial services, but what Gumroad offers and what they charge for their services seems like a good deal. So if you want to, for instance, sell your self-produced music and don't want to spend a lot of time (and/or money) building up e-commerce infrastructure, handling payments, and all that, this can be a simple way to collect a reasonable percentage of the incoming revenue, and start making sales, without a ton of work. Of course, if you have more involved needs for e-commerce functionality, you'll probably want to use Drupal Commerce, but I think this module should be attractive for a lot of creatives who simply want to focus on the "fun stuff" and just sell a few things from their sites.
Status: There is a development release available for Drupal 7.Hackpad
The module, contributed by Andrew Berry of Lullabot, integrates Hackpad into a Drupal site. Hackpad is a hosted service, based on Etherpad (but with a lot more cool, more modern features), which allows collaborative editing of documents; it's very cool, fun, and can be used for a lot of purposes for teams, so I think the interest in Hackpad will definitely grow, as will the features supported by this module which is still new enough that the API for it has not yet been documented, but with Lullabot behind its development, you know it will be awesome!
Status: There is a development release available for Drupal 7.Image Combination Effects (ICE)
The module, by Guy A. Paddock of Red Bottle Design, is too complex to succinctly summarize, but if you are building an image-centric site (e.g. a site to display your photography), this looks very useful for combining image effects or displaying multiple images at the same time (as one image), i.e., like "spriting" icons, but with larger images. It was designed to reduce the number of requests necessary for loading a slideshow, where they still wanted the client to be able to add new images or adjust the display order, but it looks like there could be a lot of potential use cases. It looks like this offers some pretty cool features that you might want to consider if image display is an important part of your planned site. I'll certainly be playing with this.
Status: There is an alpha release available for Drupal 7.jQuery Placeholder
Status: There is a beta release available for Drupal 7.Legal Extras
Categories: Content
The module, contributed by Rafal W., adds additional features to the Legal module, including the option to allow a registered user to access your site with reduced permissions if they reject the "terms of use", display the date each user accepted the terms of use, and a number of related features to help manage those annoying legal issues that might be a headache for you, too. I hope I won't have to use this anytime soon, but it's nice to know this module exists.
Status: There is a development release available for Drupal 6, but I suspect a Drupal 7 port will be in the works.Mass Password Reset
The module, written by Mark Shropshire of Classic Graphics, allows a Drupal site administrator to reset the password on all user accounts (except
user/1) and then notify all users. It's good to know this module is available if there's ever an emergency situation where we might need it.
Status: There is a stable release available for Drupal 7.Meta tags: Panels
The module, contributed by Diogo Correia of DRI, extends the Meta tags module with support for Panels pages. It also has Features integration, so that if you export a panels page, the meta-tag configuration is exported with it. Cool!
Status: There is a beta release available for Drupal 7.Mobile Switch Blocks
The module, written by Siegfried Neumann, extends Mobile Switch, a module contributed by the same author, to provide block visibility control for mobile devices. This sounds useful.
Status: There is an alpha release available for Drupal 7.OG homepage
The module, produced by enzipher, allows you to configure an Organic group's front-page as the default "home" for logged in members of the group; it also includes options to determine how a user is redirected if they belong to more than one group, among other nifty features. This could be useful for a lot of Organic Groups -based sites.
Status: There is a stable release available for Drupal 7.Performance and Scalability Checklist
The module, contributed by Travis Carden, is similar to the popular SEO Checklist module, which he also helps maintain. It provides an interactive, step-by-step checklist to help manage the common tasks involved in launching or administering a Drupal site; in this case where it comes to optimizing your site's software stack, from Apache to your Drupal theme.
This module is still new and the topic it attempts to cover is so broad, that the module is sure to change and improve in time, but it already looks pretty darn useful. The author is actively seeking suggestions in the Performance and Scalability Checklist issue queue, so please give it a try, then add your 2¢ to help improve this module. Enabling this module requires the ChecklistAPI module.
Status: There is a beta release available for Drupal 7.Performance data
The module, by Nathaniel Catchpole of Tag1 Consulting, is envisioned to be a UI for viewing and analyzing performance data that you've recorded and saved using other tools. When a key core maintainer starts a new project, there's usually reason to take notice and expect there might be great things coming. That said, according to the project page, this is still in the early stages of development, so unless you have an interest in assisting the development process, you might want to wait a while to try it out.
Status: There is an alpha release available for Drupal 7.Print Anything
The module, coded by Chris Desautels of R2integrated, helps you configure special rules for generating print-friendly output for any path. There is some work to getting it all working, but it has some nice features and helps you handle a lot of content that isn't otherwise simple to print, as well as helps maintain your brand visibility by including your logo in the output, among other features.
Status: There is a stable release available for Drupal 7.Quo.js
The module, created by Bryan Ollendyke of Penn State University, integrates the Quo.js mobile event library into Drupal. As with other such modules, you'll still need to download and install the JavaScript code, separately. It provides a number of features, including environment detection, and event detection, such as reading "tap", "hold", "pinch", "rotate" and other such mobile gesture events. It integrates well with, and enhances, the other modules recently released by the same prolific contributor, including the aforementioned Book Touch and Thumbnav modules, so it certainly looks useful and I expect it will grow in use as more sites start providing mobile-specific features.
Status: There is a beta release available for Drupal 7.Search API Page Block
Categories: Search
The module, produced by Tobby Hagler of Phase2 Technology, uses the Search API Page module to perform a search using the currently viewed node's title as keywords, displaying the results in a block, so you can direct users to related content.
Status: There is a beta release available for Drupal 7.Simple Anti-Spam
The module, by xandeadx, adds two new elements to designated forms: one checkbox, labeled "I'm not a spammer" and a hidden checkbox, "I'm a spammer". If user does not check the first or (is a bot which) has checked the second checkbox, the form is not submitted and displays a warning message.
Status: There is a development release available for Drupal 7.Simple Table of Contents
Categories: Content
The module, coded by Devin Carlson of Ontario's Ministry of Northern Development and Mines, automatically adds a table of contents to all of your node content, as long as the content is within the node's "body" field. It's a simple add-and-enable module which presumably depends on normally-structured content (with headings, etc.)
Status: There is a stable release available for Drupal 7.Speedboxes - Fast checkbox handling
The module, produced by Manuel Pistner of Bright Solutions GmbH, provides a Javascript-based method to easily check, uncheck, or invert the current setting of a selected range of checkboxes in a grid, e.g. the Drupal permissions page; simply click and drag over a selection of checkboxes and a toolbar appears which allows you to modify the state of all the selected checkboxes. Too cool!
As an alternative to the module, the Bright Solutions blog also includes post about how to use speedboxes as a browser plugin so you can benefit from this feature on any page you visit with your browser.
Status: There is a stable release available for Drupal 7.Thumbnav
The module, yet another module produced by Bryan Ollendyke of Penn State University, provides a mobile-friendly framework for using a website on touch-driven devices, with support for a variety of navigation methods and an API for developers. It includes support for Quo.js, but doesn't rely on Quo. See the project page for links to some nice demonstrations, but if you are looking for ways to improve your site's mobile support, this could definitely be worth checking out.
Status: There is an alpha release available for Drupal 7.Unit Conversion Formatters
The module, developed by Tony Rasmussen of Metal Toad Media, provides formatters for number fields to convert values between any unit supported by the Units API module. This could certainly be useful for some sites.
Status: There is a stable release available for Drupal 7.Views Drupal 7 to Drupal 8 upgrade
Categories: ViewsBACK UP YOUR DATABASE BEFORE ATTEMPTING TO USE THIS MODULE FOR AN UPGRADE. Really. We're not kidding.
—from the module's project page description
The module, written by Jess of University of Wisconsin-Madison, a major force behind getting "Views in core" in Drupal 8, helps migrate Drupal 7 Views data to Drupal 8. It's nice to see work on this is this far along.
Status: There is a development release available for Drupal 7 (really a Git repository you can check out).Wunderstatus connector
The module, from Henri Hirvonen of Wunderkraut, sends information about installed modules as a JSON to a central service. This could be useful for monitoring a group of sites your company maintains, so I look forward to giving this a whirl and seeing how it develops.
Status: There are alpha releases available for both Drupal 6 and Drupal 7.XSL Formatter
The module, developed by Dan Morrison of Sparks Interactive, provides a field formatter to process XML content through a defined XSL stylesheet for rendering. If that sounds useful, it's probably best you just look at the well-written project page, because there is quite a lot of information there, which runs well outside the scope of this column.
Status: There are dev releases available for both Drupal 6 and Drupal 7.
Ooyala is a paid video delivery service, which manages your videos and handles video delivery to your site. With the Ooyala module you can connect the Ooyala service to your Drupal site to display and play your Ooyala videos from within Drupal. This lesson will walk you through the modules that are needed, and how to configure them to work properly. We will create a new content type for our videos, and configure the Ooyala field using the Ooyala uploader. We also cover adding custom meta data to your video.
October 2012 brought us a nice batch of interesting new modules. Of course I wanted to tell you all about them weeks ago, but without going into excuses and details, I'm afraid getting this published didn't go as planned. I'd like to get back on schedule to release the next installation of this series in early December, though. Anyway, it's great to see all of the innovations that have been introduced in the past month. You can tell that Drupal 7 has truly reached maturity by the kind of modules that are being released now. Many, if not most, of the new modules integrate with and extend the functionality of other contributed modules—for example, there are three new modules which provide plugins for the Facet API—or integrate exciting new jQuery plugins to bring a bit of sizzle to your site.
As usual, the list is in alphabetical order and I haven't tried all of these modules (although I have experimented with quite a few of them and even eliminated a few from consideration since they seemed a bit too "broken" at this point.) Some of these modules might not be ready for use yet, but just show good promise and look worth keeping an eye on. Creating this monthly list is as much for me as it is for you, but I do hope that the modules I select work well for you, if you give them a try, and I look forward to seeing your comments about any of these modules.*/ Adminimal Administration Menu It adds a nice and simple minimalist look and provides some tweaks to improve your Drupal administration experience. The menu hierarchy is now simpler and easier to understand […] The shortcuts fit nicely and have a small icon that separates them from the normal admin menu links.
(Adminimal Administration Menu project description)
The module, by Andonis Ratsos, changes the style of the popular module's menu bar.
Whether or not you like the way it restyles the Admin menu is likely a matter of personal taste, but I do observe that even with only the default shortcuts in the menu (no custom shortcuts added) the larger font of the menu makes it take up a lot space at the top of the window and it starts to wrap to a second line if the window is narrower than about 1,100 pixels, so it's possible that people administering Drupal sites from smaller devices (netbooks or tablets, not to mention smartphones) might find this modification less appealing. On the other hand, the larger links should make easier targets for a finger-tip… six of one, half a dozen of another.
Personally, I like the theme change and I like the Adminimal Adminimal Theme admin theme, too, so for my personal testing sites, I'll go ahead and leave these active. I'm hoping to see some simple customization available in the future… I think I would want to see that before recommending it for client sites.
Status: There is a development release available for Drupal 7.Autocache
The module, by Teemu Merikoski of Wunderkraut simplifies caching of Views and Panels and has some support for appropriate clearing of Varnish caches, too. It's still new and the roadmap is perhaps a bit longer than the current features list, but I'm sure that this will be worth keeping an eye on.
Status: There is a development release available for Drupal 7.Bootstrap optimizer
The module, by Maslouski Yauheni, has only been released for a couple of weeks and there are already over 150 sites using it, so it must be worth a try! On the other hand, if you don't "improperly delete" modules, perhaps it's not so useful for you. It appears that its primary functionality is to remove modules from the system table which no longer exist in the modules directory, so if all your sites are well-maintained, this might not do much for you. It looks like Drupal 8 should hopefully resolve this issue. But until this is really fixed in core, there is a place for modules like this, especially for older projects that might not be very actively maintained and might have had some modules deleted over the time. For such sites, this module claims to provide a several-fold increase in the bootstrap time, and provides screenshots as evidence.
Status: There is a beta release available for Drupal 7.Bulk User Delete
The module, produced by Mark Theunissen of Four Kitchens, provides with a text area where you can enter a list of email addresses for users you wish to "bulk delete". Normally, it's probably easier to simply check the boxes next to the names of a group of users you wish to delete and select the action "Cancel the selected user accounts". But I can imagine scenarios, especially scripted ones, where using this module might be a simpler solution, e.g. when creating a number of test users en masse, users with various combinations of roles and/or other custom relationships, and then removing them after the tests have been run. This could be useful if you want to run such tests on a busy production site without needing to take special care that you select only the right users for deletion or when you have so many test users that they wouldn't all be visible on one page of users.
Status: There is a stable release available for Drupal 7.Cache Lifetime Options
The module, from giorgio79, provides additional cache-time options which can be selected on
admin/config/development/performance, with cache lifetimes up to a year. This is especially useful for sites with a lot of static content. Boost is a recommended companion.
Status: There is a stable release available for Drupal 7.ceaZine
The module, written by Carlos Espino Angulo, allows you to display PDFs in a Colorbox overlay with "page flip" effects and everything. If you want a nice effect for showing off your books, this is a great module. Setting it up is a bit involved, though, so be sure to check the project page for full details. It requires a few of jQuery libraries, and (of course) a recent version of the Libraries module, Views (for an included display of all your online magazines, if you wish to use it), and PDF to ImageField which, in turn, requires ImageMagick, but it uses only CSS, JS, and HTML—no Flash. Nice!
Status: There is a stable release available for Drupal 7.CkEditor Plugin: Google Doc embedded iframe
The module, authored by Sergio García Fernández, is an extension for the popular CKEditor module, which provides a simple editor button for easily embedding Google Docs iframes in your content.
Status: There is a stable release available for Drupal 7.Cloze
The module, written by Sivaji Ganesh of KnackForge, provides Cloze question type for the Quiz module. Cloze questions are the type of question where blanks are inserted in the middle of questions, a question type commonly used in language assessments.
Status: There is an alpha release available for Drupal 6.CodeMirror editor
Status: There is a development release available for Drupal 7.Collapsible comment threads
The module, developed by Manuel Garcia, uses jQuery to collapse and expand comment threads, thus helping remove the "visual noise" of deeply threaded comment conversations. This could be especially useful for sites with a forum or very active discussion in blog comments.
Status: There is a beta release available for Drupal 7.Content Access Admin
The module, by Peter Lieverdink of Creative Contingencies, lists all node grants in a simple table. This is especially handy since special access grants, provided by the Content Access module, are otherwise only visible on the individual nodes.
Content Access Admin displays a table with some filters to see just what you want to, with links on each node title to help you jump right to each node and manage the access.
Status: There is a development release available for Drupal 7.Date Facets
The module, contributed by Chris Pliakas of Acquia, provides date range facets similar to major search engines so that you can look for search results within a defined date range. Too cool! It integrates with the range of search modules available for Drupal, including Apache Solr, among others. Of course it's search technology, so implementing it is not as simple as activating the module.
Status: There is a beta release available for Drupal 7.Dates
The module, created by Chris Charlton of XTND.US, is not actually part of the Date module, but provides a range of additional advanced date formats. This could be especially handy, but beware that disabling or uninstalling this module does not remove the packaged date types and formats which are stored in the Drupal database when the module is enabled.
Status: There is an alpha release available for Drupal 7.Devel Input Filter
The module, contributed by Garrett Albright of PINGV, aids development of input filters; it provides a page where you can enter test input to see filtered input, without caching. It's really only for developers who are debugging text filters.
Status: There is a development release available for Drupal 7.Email Log
The module, authored by Mikael Kundert of Wunderkraut, allows site maintainers to get email notification when there are critical log entries. Log entry tokens would need to be supported for this to be done by Rules, but even so, it greatly simplifies staying on top of important site updates. The user interface and options are almost exactly the same as the Watchdog Digest module's, except that this module will send you an alert whenever there is a watchdog entry of a given severity level, so you might wish to send only the most critical alerts with this module and use Watchdog Digest to send an email which includes all the other log entries in one email.
Status: There is an RC release available for Drupal 7.Entity Translation Tabs
The module, contributed by Ryan Weal of Kafei Interactive, gives site editors an edit tab for each enabled language. For the time-being, it only supports nodes, but the roadmap includes support for other entity types, e.g. taxonomy and user entities, among others. This should be great for multilingual sites! It is currently in active development, so I won't list the potential caveats. Please see the project page for recommended usage.
Status: There is a stable release available for Drupal 7.Facet API Collapsible
The module, by Peter Droogmans of Attiks, is a "full project" release of a sandbox project created by Acquia's Katherine Bailey. If the name doesn't make things especially clear, it probably helps to understand that the Facet API is another Drupal project, which this one extends (although the project description leaves that part out). Faceted search (e.g. searching within a range of pre-selected terms or dates) is what the Facet API does and this widget provides a slick interface for single-click searches.
Status: There is a stable release available for Drupal 7.Facet API tabs
Categories: Search
When it rains facets, it pours facets. The module is another widget for the Facet API, written by Erno Kaikkonen of Exove Ltd in Finland. It allows you to display search facets in tabs and the project description indicates you'll want to do "some CSS work to style the tabs". If a sidebar isn't what you need, this might be the ticket.
Status: There is a beta release available for Drupal 7.Field collection feeds
The module, contributed by Howard Ge, provides feeds integration for field collections and also requires Feeds. This could well be useful.
Status: There is an alpha release available for Drupal 7.Field Collection Tab formatter
The module, written by Lee Rowlands of Australia's PreviousNext gives us a nifty output for field collections in a tab-set. I can think of at least one place I'd personally like to use this and apparently I'm not the only one since there are already more than 50 sites using the module, barely a month after its release… a pretty solid start! Of course it requires the Field Collection module.
Status: There is a stable release available for Drupal 7.Field formatter conditions
The module, written by Kristof De Jaeger of Wunderkraut, adds conditions to field formatters. The "Manage Display" tab for each entity type provides per-field configuration of field conditions. It supports fields from the Field API and Display Suite with a number of included conditions and it requires Field formatter settings
Status: There is an alpha release available for Drupal 7.Flipcard - nodes made into flashcards
The module, by Hugh, helps you create node-based flashcards where the node title is the "answer". Users can sort based on custom taxonomies and can record whether they knew the answer to each card, so questions they are still having trouble with will show up more often. I used to cut up index cards to make actual paper flashcards to study for exams and more recently, but still some years ago, made them to study on an old Palm device, with great success, so I know the usefulness of flashcarding, but this even offers jPlayer support to use automatically-played audio recordings for the questions. Very cool! You can see the demo site, where you can also learn a bit of Thai, to get an idea of the usefulness this module already offers. There are always new things I'm trying to memorize, so I'll be a likely candidate to give this module a try. The only thing I'm really hoping it will offer (that I didn't notice in the demo) is the ability to use the "question" as the "answer" (i.e. to practice both directions), but I doubt that would be too hard to manage. The demo site already offers the option to "view words" (clicking on each word in English takes you to the audio recording of its equivalent in Thai, whereas in practice mode, you hear the word and check to see if you know what it means). Personally, I think the current mode is better for the initial phase of passive comprehension, but for learning to actively speak a language, it's better to work from "mother tongue" to "other tongue". So ideally, the module should support working in both directions and keeping track of your answers in both directions, too, but maybe all this is already in the development roadmap.
Status: There is a development release available for Drupal 7.Invites
The module, developed by Raz Konforti of Linnovate, allows you and/or your site members to invite new members to your site and includes an OG module to provide for inviting people to a particular group; it provides for the creation of a custom, fieldable Invites type and for custom invitation emails with Rules integration, among other interesting features. Google has proven the power of viral campaigns to build a community around a new product with "invitation-only" access… so this could definitely be a good idea for your community site, too. Note: Administrators of OG sites might, alternatively, wish to use the OG Invite People module, which eliminates the registration process for invitees.
Status: There is an alpha release available for Drupal 7.jQuery selectBox
sites/all/libraries, according to the nicely detailed directions on the project page. The selectBox demo is really freakin' cool! There are various options for slick effects in addition to the various ways of building a SELECT box for improved UX.
Status: There is a beta release available for Drupal 7.JS Watchdog
The module, coded by Bevan Rudge provides
Drupal.watchdog() in Javascript to log errors to the database. It's really mostly a developer tool for people working on Javascript code, but this should be useful. It provides a number of nice features, though, so if you are working on JS code, you might want to take a look at this. Unfortunately, there isn't a Drupal 7 version (yet), but according to the project page, creating one should be "trivial", so hopefully we'll have a nice D7 version ready for use before long, too.
Status: There is a beta release available for Drupal 6.Leaflet Widget for Geofield
The module, developed by Tom Nightingale of Affinity Bridge, a Geofield widget that provides a Leaflet map and uses the Leaflet widget plugin to work with geometries, making it possible to, for example, mark up web-based maps with the outline of a real estate propery or city district. Of course it requires Libraries and configuring any kind of mapping is never as simple as just activating a module, so be sure to check the project page for more details.
Status: There is a beta release available for Drupal 7.Logo Block
The module, authored by Kristofer Tengström, provides flexibility in how you display your site logo, including applying an image style, and provides a block you can place anywhere, thus circumventing the limitations of the Drupal logo configuration.
Status: There is a stable release available for Drupal 7.MC Hammer
The module, written by Nils destoop of Wunderkraut, provides tools and templates for sending sophisticated email newsletters from your Drupal site. There is only a development release, so far, but it already has an impressive feature-set, so if you plan want to produce a newsletter, this could be a great tool to look at, and with Wunderkraut behind this, we can bet this will develop nicely.
Status: There is a development release available for Drupal 7.Nice Date
The module, written by Nicholas Thompson of Turner Broadcasting Systems, provides a nicely formatted date to display the publication date of nodes, e.g. blog posts, and comments. It uses a CSS Sprite with all the months, days and years to generate a 41x40px block with the date in it.
Status: There is a stable release available for Drupal 7.Node Display Field
The module, contributed by Christian Biggins of PreviousNext, provides an alternative teaser display mode which can be enabled for any node, e.g. a "promo" mode. This could be useful.
Status: There is a development release available for Drupal 7.No term pages
The module, written by Gaël Gosset of Insite, provides an extra option for a vocabulary which blocks the terms in that vocabulary from ever being displayed as a page. With all the different ways that terms are used in a typical Drupal site, not wanting term pages for some vocabularies is a pretty common use case, so now you know—there's a module for that! This functionality should probably be in "core".
Status: There is a stable release available for Drupal 7.OG Invite People
The module, developed by Aleš Rebec, has some features in common with the previously-mentioned Invites module, but it's only for Organic Groups. One interesting feature of this module is the complete elimination of the registration process. A user entity is during the invitation process and the invitees receive a one-time login link in their invitation emails.
Status: There is a development release available for Drupal 7.Panels Content Cache
The module, developed by Graham Taylor of Capgemini, provides a content-aware cache plugin which supports caching Panels and other Ctools displays, until their content changes. Isn't that how caching should work? Caching strategies and the technologies that support them are not trivial and there are a number of options, but this module looks promising for those who are working with Panels content.
Status: There are dev releases available for both Drupal 6 and Drupal 7.Permissions Grid
The module, by Joachim Noreiko, provides a per-role grid of permissions for modules which declare structured permissions. These permissions can be viewed, on a separate page for each role, with the entity types in rows and permission verbs in columns. Of course it doesn't eliminate the normal sea of permissions… but for the basics related to your site content, this helps simplify things. This is very nicely done and I'll be sure to use it.
Status: There is a stable release available for Drupal 7.Retina Images
The module, contributed by Michael Prasuhn, provides the option for core image styles to output a high resolution version of images for high DPI or retina displays. It can be used to return high resolution images for all devices. There can be very little difference in file-size between a low-resolution, high-quality image and a high-resolution, low-quality image. But the high-resolution image will work better on high-resolution devices and still look fine when scaled down for display on a normal-resolution monitor. This module already has a strong user-base, considering its recent release and the developer seems to be doing a great job managing the issues, so if improving mobile UX is important for your site, this module might well be worth considering.
Status: There is a beta release available for Drupal 7.Rich Snippets
The module, developed by Chris Pliakas of Acquia, enhances the search results to provide nicer "snippets" of content returned in search results, much like those displayed by major search engines. Instead of just displaying the teaser or first characters of an article, it displays that with ellipses and the user's search term within the context of the content. Very nice! Caveat: Be sure to read the "Usage" and "Gotchas" on the project page. Configuring a perfect site search is a non-trivial task, but this definitely looks helpful and works with core search and Apache Solr.
Status: There is a development release available for Drupal 7.Role memory limit
The module, developed by Kevin Yousef, is a small module which allows you to configure separate PHP memory limits, per role. For normal users, the memory limit could be set to 128MB, while the admin interface, which can require much more memory, can be allocated what it needs. Of course you need access to change the memory limit in your
php.ini file. Since the memory limit is set per-user and this often has to be higher than normal for a Drupal site, just because of the greater needs for the site administrator, logical configuration with this module could, in theory, dramatically improve the number of concurrent users your site can handle. I'll certainly be giving this a try.
Status: There is a stable release available for Drupal 7.Scoville
The module, produced by Garrett Albright of PINGV, which gets its name from the "hotness" scale used for describing a variety of chili pepper's level of spiciness, helps you easily display a block or page of your site's "hottest" content. For more complicated use cases, you'll probably want to use the Radioactivity module, instead, but since configuring it can be a bit of a chore, people who just want to get a basic "hot content" block into their site might want to give this one a try.
Status: There is a development release available for Drupal 7.Search API Taxonomy
Categories: Search
The module, developed by Steven Jones of ComputerMinds, adds some extra features for integrating taxonomy into the Search API, including indexing the taxonomy term parents and display of a facet (using Facet API) for top-level terms. It's still in development, so additional features could well be added, but this already looks very useful.
Status: There is a development release available for Drupal 7.Taxonomy Freetag Detection
The module, by Leigh Morresi, extends Term reference fields of type Autocomplete term widget (free tagging) with an option to add a button to scan other fields (e.g. your node "body") to and add words which it finds which match existing terms in that vocabulary. Of course you might need to eliminate any terms it adds, e.g. a word in your document might match an existing term, but have the wrong context for the meaning of the term (e.g. "Features" is a taxonomy term here on the Cocomore Drupal site, but if I simply talk about the features of a module, I'm not going to tag the article with that term). This looks pretty simple and very useful, especially if your site uses the standard autocomplete "tagging" widget, which is the only widget this module complements. See the project page for configuration tips.
Status: There is an alpha release available for Drupal 7.Twitter Profile
The module, created by Rishikesh Bhatkar, provides a nice, very configurable, Twitter profile block which can show any or all of: your Twitter profile info, counts for Tweets, Favorites, Listed, Followers, and Following, and avatars for your Followers and Following, with a configurable size and number of avatars displayed. It also includes some theming presets for the block. This is much more configurable than many of the other Twitter blocks. What would be nice for community sites would be allowing each user to display their Twitter profile on their user profile page, but it looks like the block only supports one Twitter account.
Status: There is a stable release available for Drupal 7.User Pic Kit
The module, written by Daniel Phin, allows your site's users to choose a user image (avatar) to represent their account, from any of a number of providers, while still supporting a Drupal core image upload option. Each user can choose which provider they wish to use. The included third-party image host providers include Gravatar (which requires the Gravatar integration module) and Robohash, but with the add-on User Pic Kit Extras! module, you can add Twitter, Facebook, and other avatar hosts. You can also locally cache the remote pictures (such as Gravatar) and use Drupal image styles on the downloaded pictures! There is even a documented API which allows you to implement other image hosts. This looks like fun and can certainly improve the user experience for configuring a new user account profile for users who already have an established online persona.
Status: There is an alpha release available for Drupal 7.User Search to People Administration
The module, developed by Benjamin Melançon of Agaric, removes the user search functionality from your site (for normal users) and moves it into
/admin/people/search (a tab on the
/admin/people). Most sites probably have no need for visitors to search user accounts, but administrators can still find such a search useful. By moving the user search tab into the "admin realm", this also opens up the option of allowing people to view user profiles without also providing the "search users" functionality (since, by default in Drupal 7, if you want to block access to
/user/search for a particular role, you need to leave the permission to "access user profiles" unchecked. So in addition to moving the user search functionality into a tab where it's convenient for site administrators, it also breaks this unnecessary relationship between access to user profiles and to using the user search feature. This looks useful for many common use cases, perhaps even more ideal for most sites than the Drupal default.
Status: There is a stable release available for Drupal 7.View mode per Role
The module, developed by Edouard Cunibil allows site administrators to set a view mode for content depending on the user role, with configuration in the content type edit form. This can be useful when you want your content to be displayed differently, to different user roles, but do note that this is not a content access module, so if you must prevent certain roles from being able to gain any kind of access to certain fields, you should consider the Field Permissions module.
Status: There is an alpha release available for Drupal 7.Watchdog digest
The module, created by Edgár Prunk-Éger, sends watchdog entries by email in a digested format, so you don't get a separate email for each entry (of a type where you might want to send a message to a site administrator). This looks very useful, but the current project page is very lacking in detail and there is no link to the configuration, so it took looking at the code to figure out where to adjust settings for this. It adds a fieldset to the "Logging and errors" configuration page (
/admin/config/development/logging), where you can configure the number of messages per e-mail, the e-mail address(es), and the severity level threshold, which can be set anywhere between "debug (all)" and "emergency", although probably for anything that extreme you might want a Rules-triggered action to immediately email the site administrator.
Status: There is an alpha release available for Drupal 7.WYSIWYG Configuration with TinyMCE and Shortcodes
The module, coded by Jurriaan Roelofs, is a Features-generated module which helps streamline a particular Wysiwyg configuration which is rather sophisticated. If it happens that you want all the features included here, it could be a nice way to get it all configured. But if you want something simpler or wish to use a different editor, etc, this is probably not for you. It includes Media integration and all kinds of things that a lot of sites won't use, but which are notoriously tricky and time-consuming to work out, so if this kind of rich configuration is what you want, then all you need to do is download all the dependencies (see the project page, there are a ton!) and then simply enable this module to have it automatically enable and configure all its dependencies. This looks very useful if it happens to be exactly what you need; if not, it could be also be useful as a quick route to experimenting with a lot of modules and features that you might want to use.
Status: There is a beta release available for Drupal 7.
I'm not sure how it happened, but today I noticed that Drupal's menus were behaving very oddly. After upgrading to Drupal 6 and installing several additional modules, I noticed duplicate menu entries as well as other disturbing oddities. Items I was placing into the menu were not showing up. Menu items that I moved around were apparently saved but they did not appear properly in a dropdown context.
Looking further into it via the absolutely awesome SQLYog tool, I verified that there were dozens of duplicate entries. Some items were duplicated up to six times. It was a real mess.
The database tables involved here are menu_links and menu_router. These are two of the more mysterious tables in Drupal. I haven't had the need to spend much time with them in the past, and I know now that this is a good thing. Fortunately, you do not have to know anything about them to fix this problem. While I spent a couple hours carefully deleting items from this table, ultimately I gave up. I was able to remove all the duplicates, but the menus were still misbehaving. At this point, I just wanted to do a factory reset on the menus, but it's not so simple as flushing cache. However, that is not far from the solution.
This solution will do a 'factory reset' on your menus. You will lose any customizations you have made. However, all core and contrib module entries will be restored very nicely.
Please backup your entire database before doing any destructive database manipulation.
Step one is to empty the corrupted tables:
In your favorite SQL client, run the following commands:
truncate menu_links;
truncate menu_router;
At this point, your site will be completely unusable. But not for long. To complete the final step, you will need to be comfortable with the Drupal admin's best friend, drush.
Simply run the following commands from your terminal (Viva tcsh!):
drush php-eval 'menu_router_build();'
drush cc menu
Now my menus are as fresh as the day they were installed.
Though I could not clearly identify the cause of this problem, I would suggest backing up your database before installing the Taxonomy Menu module.
I've been putting it off for a few years, but I finally decided to upgrade devbee.com to Drupal 6.
I didn't really need to, but it bothered me that I wasn't running supported code and I figured I might learn something. And I did. Mostly obvious things that I should be familiar with already.
I've only ever played around with this. I don't like learning new things unless they are going to be truly useful to me. Drush is definitely something I shouldn't have ignored for so long. It comes in particularly handy when doing a site upgrade as you can download and install modules, clear cache, set variables, run DB updates and a lot more all from the command line. This tool is crazy good if you're comfortable in a terminal.
Themeing didn't change much
I was able to convert my dated theme to 6 with very little effort. I created a .info file, changed the names of the region variables in my page.tpl.php file and tweaked a small amount of CSS. Took me about 20 minutes. Pretty painless. I was able to preserve my table-based layout so all you markup nazis will have an example of bad design.
The whole process was made much easier by the fact that I don't like using a lot of modules. I tend to go with a handful of the more popular modules such as Views, CKeditor, CCK, Pathauto, etc... Because I use only popular modules, I'm almost certainly going to have no trouble upgrading them. At least that's my experience.
Key things to remember
- Start with a brand new install of D6 with no contrib modules. It's tempting to try to force an upgrade on your existing site, but it's just not going to work. You must create a clean install.
- Import your old database into the clean D6 database. I tried to skip this and just point D6 to my old database, but then you end up with missing tables and a whole lot of brokenness.
- Run DB updates and get your core Drupal site working before worrying about contrib modules.
- Lastly, and this is where drush will save you time, download and enable the contrib modules you need one at a time.
Unfortunately, the upgrade process is no longer something that can be done by the average site owner. There are going to be snags, and you're going to need to know how to interact with your database to get things up and running. I think this is the reason so many users are still on D5 and D6. I'd really like to see an upgrade path that was more accessible to non-developers, but at the same time, I'm also grateful that Drupal is upgradable and there is no need to manually migrate data for major upgrades.
At this rate, I should be upgrading to D7 sometime around the end of the decade.
The popular Features module is the current king of the hill when it comes to bundling up Content Types, Views, and other custom configuration data for reuse on Drupal projects. Sometimes, though, a Feature needs site-specific tweaks before it's ready for prime time. Changing the API keys for external web services like Google Analytics and Disqus, for example, can be done using those modules' native configuration screen. But if your Feature module is consolidating the configuration work, wouldn't it be great to consolidate the settings forms, too? That's where Configuration Builder comes in. It allows you to build custom Drupal settings screens that can be exported and stored in a standard Feature module.
Creating a new configuration screen, or altering an existing one, is clean and simple. Site builders can choose what URL their config screen will live at, as well as what permission or role will be necessary to access it. Config Builder leverages the powerful but little-known Form Builder module for the meat and potatoes work of designing the config form itself. Drag and drop addition of new form elements and re-ordering of existing ones makes things fairly straightforward; if you've ever used the WebForm module, it's leveraging the same interface tools.
By default, the forms that you've created will simply save their settings like a standard Drupal system settings form. It's up to you to write code that does something with the values. However, if you manually set the names of the different form fields to match the names of existing settings fields on other Drupal configuration pages? Voila! Your custom configuration form will begin loading and editing the same values. This means that you can create consolidated configuration forms that control specific important settings, like the Site Name or the Google Analytics API Key, without forcing users to hop from one screen to the next.
Once that's done, the custom settings forms can be saved and exported into a Feature just like your content types, Views, or custom site variables. If you'd rather bypass all the importing and exporting, Configuration Builder can also output the form you've designed as a standard set of Drupal hook implementations that can be pasted into a custom module, with no outside dependencies.
Configuration Builder may be overkill for developers who are used to slinging around custom settings forms and are comfortable embedding them in Feature modules. For site builders who want to tide up their own features, or developers working on larger multi-site platforms that need cleanly encapsulated and overridable settings forms, this module could be just what the doctor ordered.*/
Rules is an especially useful Drupal module for all kinds of tasks. One use you might want to put it to is providing admin notifications of certain events on your site, e.g. user registrations and the creation of new comments and content by these "untrusted" users (assuming your use case allows them to create any content at all). I recently created such rules to help monitor the creation of users, content, and comments on drupal.cocomore.com/.de. Since we use the Project module (and supporting code) to host and track issues on some Drupal modules, we allow users to create accounts and "Issue" nodes. But there hasn't been much recent change to the modules we host, so most of the "users" turn out to be spamming scumbags who post "issues" with links to questionable sites (you know the type). Since we allow anonymous users to comment on our blog posts, we also get our fair share of comment spam, but a tricky Captcha (we're using Riddler, these days, to filter out visitors who don't know or can't take the time to search the answers to simple Drupal trivia questions) helps keep comment spam to a minimum. Keeping vigilant about stomping out spam is important since leaving spam published looks unprofessional and is bad for SEO… and since it also attracts more spam (spammers see that your site leaves spammy links in place); but of course it's also important to keep an eye on the valid posts, too, and to respond to them in a timely fashion.
So we will assume that you have a site without a massive flow of new user registrations or new content and that you want to be alerted with some useful information whenever these events occur so that you can take appropriate action (block users and clean out the spam… or respond to valid content/comments). This article will lead you, step-by-step, through the creation of three different rules on both Drupal 6 and Drupal 7 -based sites, identifying particular set-up differences between these versions of Drupal/Rules. The three events we want to create Rules for are:
- New user registered
- New comment posted (by non-staff user or "untrusted" user)
- New content posted (again, by some kind of "untrusted" user)
*Note: This article also does not cover setting up HTML mail, but some modules, such as Mime Mail help make this a relatively pain-free process and provide a "send HTML mail" action for Rules. Adding specialized modules is probably not justifiable if you don't plan to use HTML mail for anything more than admin notifications, but if you want to email users, such modules can help you create much more attractive and useful emails.
In every case, creating a new rule starts by going to the "add rule" page:
Notify admin when a new user registers
This is a simple rule which sends an HTML email with a link to a new user's profile, along with their username. If you allow users to register themselves on your site, you will likely notice patterns that persistent spammers follow and be alert enough to just block the most suspicious user accounts before they even start spamming your site. I won't specify the suspicious patterns I've been reacting to here (I don't want to teach spammers how to be sneakier or more effective), but if you have a spam problem, you probably already know the patterns or will quickly recognize them.*/
Adding a new rule to react to user registrations
The first step is virtually the same on both Drupal 6 and Drupal 7. Pick a name for the rule that you will not be confused by later, add tags (categories) if you have lots of rules, or plan to make lots, and select the event, "After saving a new user account" ("User account has been created" on Drupal 6).
Click "Add action"
The "Add action" pre-step is also almost identical in Drupal 6 and Drupal 7 and we will skip over illustrating this in the following rules:
Add action "Send mail" or "Send HTML mail"
In Drupal 6, the options for sending an HTML mail (provided you have Mime Mail installed) are separate from the rest of the "Send mail…" options. In Drupal 7 they all appear together in the "System" options. Either way, you can choose to send an email to an appropriate person or group of people. The "arbitrary email address" options can be useful if you want to send email to more than one person, regardless of their site roles. You could, for example, send a mail to the author of content that received a comment (using a "replacement pattern", i.e. "token") and/or to a particular person. More than one email address (or token substitute) can be added to recipient fields as long as the addresses are comma-separated.
Complete the email subject and body
The email "subject" and "body" fields can accept a variety of tokens or "replacement patterns". In Drupal 7, these are apparently separate from "Tokens" provided by the Drupal contrib module, Token, which of course you also have installed; the Rules replacement patterns are available even if Token is missing or disabled, but in Drupal 6, you need the Token module enabled in order to have "replacement patterns" available for use.
Download import code for this rule
Rules allows you to export and import rules from saved code, so I have attached an export of this rule. Even if you don't want exactly the same action, this could be useful as a starting point for a new rule on your site. There are four versions of the import code attached, two each for Drupal 6 and Drupal 7 (for each version of Drupal, there is one version of the rule which uses HTML mail for the admin notification email, and one which just sends a plain mail.)
I suggest initially triggering a very simple rule to send a very simple email (to test that you get your message) and then build up the complexity a small step at a time, testing as you go.
There's a new kid on the block in the configuration management world that claims to be lean, simple and easy to understand. We're using it internally for some exciting new projects, and have found that it lives up to it's promise.
Ansible's goal is to unify two similar but traditionally separate tools: configuration management and deployment. Instead of using a combination of Puppet + Capistrano or Chef + Fabric, you can now use a single tool to update your configuration, deploy new code or execute ad-hoc tasks against groups of servers. There is no requirement to setup any daemons or any software at all on the target servers - as long as you can reach them over SSH, you're good. There is also very little setup on the machine running Ansible, since it only relies on a few standard Python libraries. There's a detailed comparison page in the FAQ that compares Ansible to these various other tools.
To illustrate some of the features, we've created a playbook that sets up an Ubuntu 12.04 server as a multi-user LAMP developer environment. Our old method of creating a server would be to perform these steps once, document them on a wiki, and then anytime we want another similar server, clone the first one or repeat the steps manually. This procedure is fragile over time and in the case of cloning, virtualization-platform specific. It's far better to create a reusable, automated set of steps that can be tweaked and improved, and executed against any fresh Ubuntu 12.04 server, running anywhere. The example is documented and fully functional, although it's not 100% secured so be careful.
The tasks that need to be performed are recorded in YAML formatted Ansible playbooks, which are then executed against the target host. The main components of a 'play' are:
- Hosts against which the actions are performed.
- Variables that can be used in the play or in file templates.
- Actions that will be performed when the play runs.
- Handlers that respond to change events from the actions.
Here is an abbreviated example from our server build playbook file, setup.yml, that will apply php.ini and restart Apache if the file has changed:
--- - hosts: all user: root vars_files: - vars/settings-default.yml tasks: - name: PHP configuration file, php.ini action: template src=templates/etc-php5-apache2-php-ini.j2 dest=/etc/php5/apache2/php.ini notify: Restart Apache handlers: - name: Restart Apache action: service name=apache2 state=restarted
The first two directives, 'host' and 'user', are easy - they specify that the play should by default run against all hosts, as the root user. In the following sections we'll cover what the others do.
The vars_files section lists files that will be imported into the current play. The variables specified in these files are then available to use as value substitution or logic control in both the play and in the templates.
In our case, the settings-default.yml file contains a list of configuration variables for the services like Apache, MySQL, etc. They're all organized into their respective sections, but looking at the file as a whole we get a great birds-eye view of how the play will be modifying the default server configuration. Here is an excerpt:
--- # php.ini php_max_execution_time: '90' php_display_errors: 'On' ... # my.cnf mysql_max_allowed_packet: '128M' mysql_character_set_server: 'utf8' ...
Any value that will be modified from it's default out-the-box state is recorded in this one place. This makes changing settings really easy - no more grepping through thousands of lines of configuration in the master template file.
Tasks & Handlers
tasks: - name: PHP configuration file, php.ini action: template src=templates/etc-php5-apache2-php-ini.j2 dest=/etc/php5/apache2/php.ini notify: Restart Apache
These are the meat of the playbook. Each task is given a descriptive name and an action. In the example above, the action is 'template' and the parameters 'src' and 'dest' point to a source template on the local host, and a destination location on the target host, respectively.
To execute this step, the Ansible 'template' module will be invoked, passing the etc-php5-apache2-php-ini.j2 file through the Jinja2 templating engine, which performs variable substitutions in the appropriate place. For example, in this template we can insert the value of the variable php_max_execution_time (sourced from settings-default.yml above) in it's correct place:
etc-php5-apache2-php-ini.j2 which becomes php.ini
; Maximum execution time of each script, in seconds max_execution_time = {{ php_max_execution_time }} ...
The great thing about Ansible modules is that they're idempotent, meaning no changes will be made if the new file is identical to the old one. And since we have this data available, we can trigger events when changes are actually made. That's what the 'notify' section does - when Ansible detects this file has changed, it will call 'Restart Apache', which is defined at the end of the play and does exactly what you might think it does.
When Ansible executes a task, it creates an SSH connection to the target server and copies the required module over. The module is then executed on the target with the correct parameters, and all the module has to do is return a JSON object containing pass/fail and other optional status information.
This has several advantages: for one, modules can be written in any scripting language, as long as the target can execute that code from the shell. It also means your modules can be quite sophisticated, and since they're running locally on the target server as opposed to sending individual commands over the wire, they run fast.
There are git, apt, yum and service modules, just to name a few. Developing extra modules is easy and there is a growing collection of 'contrib' modules that come from the community but are not part of core Ansible.
Command mode
In addition to creating playbooks, you can also execute ad-hoc tasks against your servers using the exact same modules and syntax. For example, I could execute from the command line:
ansible webservers -m shell -a '/sbin/reboot now'
That would reboot all servers defined in the 'webservers' pool. This shared syntax and configuration is one of Ansible's strengths, we can reuse a single server cluster specification for all tasks.
Project Status
Michael DeHaan is the project lead, and he has a lot of experience in this area, having worked at Red Hat & Puppet Labs, co-created Func and developed Cobbler.
Ansible is still very new, having only been released this year. However, it's already used in production and there is a strong community forming. Michael announced recently that he'd written almost zero code in the upcoming 0.5 release, a sure sign of good community momentum.
Check out the pedantically commented playbook example, that covers almost all the features in one place.
The Ansible mailing list is active and friendly.
It's been a busy past several days in Barcelona (for the Drupal Developer Days) and most of us who'd been sprinting during the week before seemed to be in the same condition by Sunday—rapidly running out of energy from progressive sleep deprivation from an increasingly later return to our hotels. But it's been an exciting week for Drupal core (and contrib) development and significant work has been completed on the Drupal core (mostly building up Drupal 8, but also some for added features in Drupal 7) while a lot of important decisions have been made which will likely shape development in a number of initiatives for the coming months until the sprints at DrupalCon Munich.
In addition to the Sprint I was primarily involved in (I was just trying to get my feet wet with assisting the Drupal 8 core development process by joining the multilingual sprint, but I did write my first committed core patch—admittedly this was a very basic patch), there were also sprints running for "Views in core", Entity API, Media initiative, Mapping in Drupal 7, configuration management, abstracting social networking, search-related sprints, the Drupal.org upgrade… and possibly more still. I'll cover some of the highlights of the week that I'm most knowledgeable about.
Multilingual Initiative
The multilingual initiative sprinted all week before the Developer Days sessions, and even continued through the weekend. And a lot of key decisions were made and important code changes committed and pushed to the central Drupal 8.x repository.
New user interface translation improvements in Drupal 8
This is something I got to do a bit with, but Swiss developer, Michael Schmid (Schnitzel on d.o), of Amazee Labs, was the primary developer working on this task during the Sprint. He and his colleague, Vasi Chindris, were among the stars of the week. It was a real privilege to get to look over their shoulders and to get Michael's support when it came to using Git to manage code in the sandbox we were using for the issue. (Thank you, once again, Michael!) Once everyone was happy with the work, it got committed to core. This new sandbox workflow, used for larger issues, helps avoid a lot of bugs creeping into the main branch, as has happened during previous periods of intense core development. Of course the tests and test bots catch a lot of issues which could otherwise be major headaches for all concerned (automated testing was also a part of Drupal 7 development). If you recall, the long wait for Drupal 7's release was due to hundreds of critical bugs. Now this should be a thing of the past since we have an established threshold for critical issues; and the core team only commit new patches to the central repository when we are below that threshold (15 "critical" bugs, 100 "major" bugs… among other thresholds specified).
The new user interface translation system allows you to keep imported (community contributed) translations separate from customized translations and search for a particular translation within either or both categories as well as filter by translated strings, untranslated strings, or both. If you have any unsaved translations, they are highlighted to help remind you not to leave the page without saving them and there discussion about providing a dialogue to prevent a site admin from accidentally leaving the page with unsaved changes, too. There is also an issue to allow the string search to be non-case-sensitive (checkbox) to find more strings that contain a particular word or phrase, regardless of text case. Since this feature came up in discussion after the rest of the user-interface changes had already been made, we elected to put the discussion about adding this feature in a separate issue. If you have ideas for what might further improve the Drupal 8 user-interface translation workflow, your input is valued.*/
New content language options
You can enable translation for a particular content type and also choose to hide the language selector (automatically selecting the language for a new piece of content by any of a number of contextual rules). The automatically selected language for a new piece of content can be any particular language enabled on your site, "not specified", "not applicable", "multiple", the "site's default language", the "current interface language", or the "author's preferred language". While all these settings might arguably be a bit confusing for new users, they should help smooth the content creation and translation workflow for most sites. Of course the option to "enable translation" is hidden if the default language for the content type cannot be resolved to a single language (i.e. for "not specified", "not applicable", or "multiple"), since translation does not make sense here.
Translate the English UI to… English!
In the edit preferences for the English language, you can enable translation to English and then it's easy to change, for instance, the "Log out" link to "Sign out" (or "Disembark", "Abandon ship", "Terminate session" or anything else you might want on a particular site). Of course this could also be useful for fixing any oddities you find in the UI strings provided by contributed modules if you find a mistake in a field description, for instance, you don't need to wait for a module developer to commit your patch or add a "site English" custom language just to modify a few strings.
Configuration Management related to Multilingual sites
One of the biggest issues of the week was determining how multilingual configuration would be handled in Drupal 8. The core team knew that they wanted to store language configuration in files rather than in the database, so that it's easy to "push" new language configurations to an established site that already has content, among other benefits of this approach. But this brought with it a number of challenges which the Multilingual Initiative team, Configuration Management Initiative team, and other interested parties discussed in several sprint discussions through the week. Many of the standard configurations for a site might also differ, depending on the language: you might, for example, want a different site name or site slogan or logo for each language. There were three different proposals for how to handle multilingual configuration, and to keep a long story short, the final decision was to go with "Plan B" (or a minor variant, thereof). You can still lend your voice to the "review" process in the main issue for the language configuration system in Drupal 8. If you would like an overview of the plans, there is a nice graphic by Gábor Hojtsy (the Multilingual Team lead) which outlines the differences between the three proposals and some variants.
Drupal 8 Configuration Management
One great session from the weekend was the Introduction to the Drupal 8 Configuration Managment System by Greg Dunlap ("heyrocker" on Drupal.org), the Configuration Management Initiative team lead. There has been some good progress in determining what this is going to look like, some of which took place during the sprints in Barcelona. Basically, this will be a bunch of smaller files stored within a logical directory structure in the
sites/[…]/files directory. The new configuration system is currently planned to be YAML-based (rather than PHP or XML, which were used in earlier visualizations of the system). And the goal, as described by a slide in Angie Byron's Sunday-morning keynote, "Drupal 8: What you need to know" is to be like "Features in core, only better". The aim is to help us remove the complications involved in pushing configuration changes, modified in a development or staging environment, to a site that already has user-created content that we don't want to lose. The main problem with the current system is that there is no consistent system: configuration settings are scattered across multiple tables, variables, files, and other locations and there is no consistent structure in any case. The idea is now to have a contexts, which Drupal responds to, when determining which configurations files to use.
What it should look like when loading a configuration from module code, is something like this:
And when setting and saving configuration data:
$config = config('image.style.large.yml';
$config = config('system.performance');
$config->set('cache', $form_state['values']['cache']);
The YAML code for the image example, which saves configuration for the "large" image style would look something like this:
name: large
name: image_scale
width: '480'
height: '480'
upscale: '1'
weight: '0'
ieid: image_scale_480_480_1
This should be pretty easy for developers and site builders to learn to work with and of course an interface is planned which should automatically build the configuration files, when edited by site builders. Configurations will be loaded into the "active store". Changes are saved back to the active store and back to the YAML files so they can easily be moved between sites (staging and production sites, or completely different sites if they should have some settings in common). Building up an ideal import/export system for configurations is one of the major remaining hurdles. Update: heyrocker's presentation slides are now available for download, so you can see other examples of Drupal 8 configuration.
Other Drupal 8 news
Twig library committed to core!
One of the new developments which has received some press is that Twig, the templating system designed by Fabien Potencier, the innovator behind Symfony, which also bundles Twig, has now been added to the Drupal core repository.
However, the fact that the Twig library is in the repository does not mean that it's ready for any kind of use yet, except for those who are working to build a new templating engine for Drupal, which uses it. How this works is still open to discussion; according to webchick, it may be that we keep both PHP-based and Twig-based templating engines to ease the pain of this change. On the other hand, while there is a learning curve involved, there are many advantages to Twig, especially in terms of security (removing PHP vulnerabilities from themes, altogether), and the saying that "the drop is always moving" applies here. It may be that Twig is the only templating engine which will be supported by Drupal 8, but if you feel strongly about this or have ideas for how to do this "right", it's a good time to get involved.
Context-based layout and blocks
Everything in Drupal 8 will be a block or a layout area and blocks can have multiple contexts which determine their behavior (and whether or not they are displayed). This is going to be a major change which should produce much more flexible layouts and site designs. Of course this will touch on every major Drupal initiative: configuration, HTML5, mobile, multilingual… all are involved.
Drupal 8 will have clean, semantic HTML5 (and will abandon IE)!
Say goodbye to the messy nested
div hell! Drupal 8 code is going to be much smaller and cleaner which will make designer/themer types love Drupal and make it possible to produce code that renders nicely, regardless of display size. Oh, and don't worry about trying to support older versions of Internet Explorer; the community has decided it's time to put that tiresome task to rest. Yay!
Drupal 8 development needs you!
Webchick, heyrocker, Gábor Hojtsy… all made the same point: As a community effort that's still underway, the Drupal 8 effort needs more of the community at large to get involved and find ways to help out. There is a lot of complexity, but there will be smaller tasks that anyone could work on, so there's going to be something for everyone. Even non-coders can help by testing, filing bug reports, helping manage the issue queues, making suggestions, documenting finished features and APIs. There are several places where you can get involved:
- The core initiatives overview page provides information about when the different teams meet in IRC and in which channels among other information which can help people who want to find ways to get involved.
- Drupal Ladder is a project aimed at helping more people learn how to contribute to Drupal
- [ … ] (Comment below if you have other tips for where to get involved)
Big thanks to the organizers, sprint leads, and session speakers
The Drupal Developer Days in Barcelona were a big success because of all of you pulling together to make things happen. The local organizers made us all feel welcome and provided a lovely venue and took us out on the town just about every night. The sprint leaders helped find ways for everyone to play a part in building Drupal 8 or contributing in other ways, and the sessions were awesome.
I was supposed to get into Barcelona at 10:30PM on Tuesday evening, but with delays in my flight, it wasn't till after midnight that our plane landed; it was after 1 a.m. by the time I reached my hotel. Normally travel, when it runs late and long, makes me feel exhausted, but I was excited to be joining my first Drupal core sprint. I've been wanting to do a bit more to help build Drupal and it's great to not only be somewhat aware of what's coming in Drupal 8, but to also know that I've at least played a small part in making it happen.
I wasn't sure I would attend the Drupal Dev Days in Barcelona till a couple of weeks ago, but I'm glad I'm here. We have a fairly sizable group of developers here at the Citilab helping work on cutting through the issues for Drupal 8 Multilingual Initiative (D8MI). I've been helping with some user interface quirks and since it had been long enough since I'd actually done string translations of the user interface, I started out yesterday as a "tester"… at least trying to look at the problem of translating the interface (e.g. translating "Add content" to German) as if I had never done anything like that before. And we did find some issues and, even better, we were able to address and correct those issues during yesterday's coding. Others have been working on multilingual issues related to the new configuration management system, and a number of other issues which you, too, can help with, if you'd like to join us remotely (or in person, if you happen to already be in Barcelona — the Sprints continue through Friday, too). There are currently about 40 of us in the IRC channel for i18n and I'd say that at least half of those are working on the Sprint. There are about a dozen (give or take, since people are working on other sprints, too) who are here in Barcelona working on D8MI.
You can help make Drupal 8 better, too!
Jump on IRC (#drupal-i18n) and look at the focus issues for Drupal 8 Multilingual Initiative if you'd like to join use remotely. There is a lot going on right now and it's not all on Multilingual issues, so if you have some time, I'd like to encourage others to join me in helping ease the burden on the few who do so much and at least do a small bit to make Drupal 8 as awesome as it can be.
April 2012 delivered a fresh batch of promising and useful-looking new contributed modules to the Drupal world. Perhaps because the immediately-preceding DrupalCon gave developers some time to collaborate and work on their contributions more than they normally might, this month seems to have a notable number of interesting new projects, especially considering the relatively "mature" state of Drupal 7 at this point. To help keep abreast of some of the most interesting new developments we have planned a monthly article to showcase these new modules; this is the first edition of our "Modules of the Month". At this point in the release cycle, newly released modules are mostly only being released for Drupal 7, but a few have also been released for Drupal 6 as well; where Drupal versions are not mentioned, you should assume the module is only for Drupal 7.
Caveat: I have tested some, but not all of these modules. Be especially careful if you choose to use any of the "pre-stable" releases on production sites. I should also note that some other awesome modules released in April may not be included—I did my best to select the modules I'd be most likely to use, but there are some "special use case" modules which were not covered, but which might be very useful for some sites. The 30-something modules included here have been sorted into very loose categories.
3rd Party Integration / Social Media
Twitter Follow Block
The Twitter Follow Block module, by Pradeep Saran, provides a nicely styled box to show your Twitter link and followers in a jQuery-loaded block that can be placed in any region of your theme. You can configure the dimensions of the block (and thus, the number of "follower thumbnails" displayed) and you can choose from different color schemes to better match your current theme. It currently only displays the Twitter feed for one Twitter user, but what might be an interesting development would be a way to dynamically load the Twitter username (e.g. from a Profile field) so that the Twitter follow block would link to different users (based on the author of content currently viewed or the profile page being viewed, if applicable). The module is currently available as a "stable"
7.x-1.0 release and I look forward to seeing this get further developed.
Social Buttons
The Social Buttons module by Linnovate's Raz Konforti, provides a field that can be added and configured for any content type (or any fieldable entity) and includes default button code for Facebook, LinkedIn, Twitter and Google+, but you can also easily add new buttons. Since it's a field, you can also determine where and whether it is shown for each display (node view, teaser, RSS, etc). It has a
7.x-1.0-beta2 release as well as more recent commits to the developer branch.
Content Access Control
Hidden Nodes
The Hidden Nodes module, created by Bryan Ollendyke of Penn State University, helps allow staff to hide nodes from regular visitors while still allowing users with "staff" permissions (admin or author/editor -type roles) to see the content in the menu as it will appear when the content is finished. This helps get around the issues caused by the "black-and-white" absoluteness of published/unpublished status (and only being able to access content through the "administer content" system). It was created to integrate well with the Outline Designer module, another project sponsored by Penn State. Hidden Nodes has recently had its fourth beta release and is certainly an interesting project for streamlining team-based content workflows.
Restrict node page view
The Restrict node page view module, authored by Christian Johansson of Sweden's Kodamera AB, helps prevent users from viewing content outside of its intended context. The example use case for this module involves a requirement to prevent users from directly viewing Views slideshow nodes (via their
node/xxx paths), but of course there could be other content you want to restrict access to but still have its information available in a Views display, so direct access to the node by most roles can easily be blocked with this module. The initial release is shown as "stable", and it's simple enough, so may never require any fixes or updates. That said, I do hope that they modify the module so that full-node access is only restricted to selected node types (i.e. blacklist). It currently adds a set of permissions for all node types, which defaults to no view access for all roles and content types, which would be a pain on sites with lots of roles and content types, especially if the goal is only to restrict non-staff access to one limited node type out of many.
Node access book
The Node access book module, by the prolific danielb, is a content access module which allows access settings placed on a parent "book" page to apply to all child pages of that book; or, similarly, if content includes a reference to another node to which they have access. It makes it easy to change access to a whole Drupal "book", according to roles. The module is still new and very experimental, so you should use it with caution; at this time the only release is a development snapshot.
Theme Enhancements
Content Theme Code
Autoload JS
The Autoload JS module, authored by Justin Dodge, provides for particular JS files to be loaded according to their filenames. Labels added to the Javascript filenames or used in the path (directory names within your theme folder) can determine JS to be loaded on blog pages, your site's front page, all pages, etc. For example, the file found at
sites/all/mytheme/js/nodetype--blog.js would automatically be loaded only for page loads for the "blog" content type. A "stable"
7.x-1.0 version was released in mid-April.
Twig template engine
The Drupal Twig template engine module, by Steve Mokris integrates the Twig PHP template engine, an exciting, new-generation template system for PHP which is faster, more secure, extensible, and uses compact code which is easy to read and to learn. Twig is another awesome innovation from Fabien Potencier, the creator of the Symfony framework (of particular interest since Drupal 8 will incorporate a number of key Symfony components). It has a stable
7.x-1.0 release and should be worth experimenting with and keeping an eye on.
Field Extractor
The Field Extractor module, by Commerce Guys' Bojan Živanović, allows you to easily get information from a referenced entity (e.g. within a Views display). This looks very useful and I look forward to seeing a "stable" release (the module is currently only available as a "developer snapshot").
Hierarchical Term Formatter
The Hierarchical Term Formatter module, by Hannes Lilljequist, provides additional formatting options for a term reference so that you can display its hierarchy (on, for example, a node display), with "
parent > child" rather than simply
"child". It provides a number of options to control the levels of hierarchy displayed, the markup used for display, and whether or not the terms are linked to "term pages" and at this time is available in with an "alpha" release for Drupal 7.
Token formatters
The Token formatters module, by super-contributor Dave Reid, enhances your control over how fields are output, by providing token support for field display formatting. This module has a beta release available for Drupal 7.
Google Map Field
The Google Map field module, by Scot Hubbard, provides a simple way to add maps to any fieldable entity with a relatively light-weight system compared to Location/GMap -type implementations. The location and zoom level for each map is independently selectable, directly from a map. It also provides an option to add the map within your Wysiwyg content by providing a simple map selection button (which inserts a custom token) that can be enabled for your editor; so you could potentially have several maps displayed within, e.g., a blog post. There are a few rough edges, but this looks like a promising way to embed maps, directly within content, without all the overhead of using other methods.
The Defacto module, by Acquia's Christian Yates, extends ApacheSolr search to provide biasing on content which has been tagged (using a specific taxonomy reference field) with a particular term, e.g. searches for that term will be biased in favor of content tagged with the term. You can also mark specific content as the "canonical" (default) result for a search on a particular term to push the content to the top of the search results. This is a very new module, which currently only has a developer snapshot available, but it does look promising.
Administration and Content Management
Content Menu
The Content Menu module, by Wunderkraut's Daniel Nolde (also the local "sitebuilding" track chair for the upcoming DrupalCon Munich), provides a system to streamline the process of working on menus and the associated content in one simple interface to make "building a structure-oriented website [ … ] effortless and intuitive". Getting into the specifics of how this works is outside the scope of this article and since it's also currently only available as a developer snapshot I will only say that this module looks very worthy of notice.
UUID Redirect
The UUID Redirect module, by David Rothstein, sounds like a very useful module for a rather complex use case: If you use the Deployment module to stage content to your production site, and use the Universally Unique ID module, UUID Redirect allows you to configure administrative "edit" links on the "production" site to link to your "content staging" site's edit page so that certain content types (or any other entities) are only ever edited on the non-public-facing server. This module currently only has a
7.x-1.0-alpha1 release.
UUID Entity Autocomplete, Context UUID, and UUID Link (three related modules)
The UUID Entity Autocomplete module, by Dave Hall, provides a simple autocomplete/lookup field for Universally Unique IDs. It is a dependency of Context UUID, also recently released by Dave Hall, a module that "provides a context condition so reactions can be based on a collection of entity UUID—so they remain consistent between environments" (of course it also depends on Context and UUID and would normally be used in a situation where the Deployment module is used to stage content between "administrative" and "live" servers.) Finally, the UUID Link module, also by Dave Hall, provides a link field based on a UUID, which means that links won't break when content is deployed to a "live" server. At present, all three of these modules have
7.x-1.0-beta1 releases.
Views arg parent term
The Views arg parent term module, by David Langarica Lorenzo, provides a simple Views plugin which allows you to access a parent taxonomy term in order to display more "related content" than might be shown through the child term. It currently has a "stable" 1.0 release for Drupal 7.
Views argument cache
The Views argument cache module, by Mike Stefanello, allows administrators to configure individual caches for each argument in a Views display so that you only need to clear a particular argument's sub-cache when relevant content has been added. This should help boost your site's performance, especially for sites with a lot of content displayed with argument-enabled Views.
Link Title
The Link Title module, by Rolf Meijer, is a text filter which can be enabled to add a "title attribute" to any link created which does not include a title, e.g. those automatically generated by the "convert URLs" filter. The added title attribute is taken from the HTML header of the linked resource. It currently has a "stable"
7.x-1.1 release.
Context Set Message
The Context set message module, by RJ Pittman of Phase2, allows your site to display a user message based on the current context. It supports a variety of tokens for more dynamic messages and depends on the Context module. The current release is only in an "alpha" stage, but this looks like a promising and useful module.
Media Gallery Extra
The Media Gallery Extra module, by Sergio Martín Morillas, extends the Media Gallery module (surprise, surprise!) to provide a number of extra useful features. There is only a development snapshot available at this time, but the features which have already been implemented look like a great start and we can only hope to see the planned features and roadmap implemented without issue. If you are planning to use the Media Gallery module to display images or videos on a new website, you might want to keep an eye on development here.
Internationalization contributions
The Internationalization contributions module, by Jose Reyero (who also happens to be the primary committer to the Internationization module) provides additional sub-modules which can be enabled to provide extra i18n functionality, e.g. synchronizing node references across different translations of content and adding "hreflang" attributes. It's still a development module and likely will remain that way (presumably this module is a place to experiment with new features before rolling them into the main i18n module.) But if you have urgent need for these features, the new submodules could be stable enough for use, provided you carefully check them out, beforehand.
pjax for Drupal
The pjax for Drupal module, by Hannes Lilljequist, uses jQuery's pjax library to load new content into a browser window without fully redrawing the page. It correctly updates the page title and URL path and loads any new content with a smooth process, lessening load on the server and lowering bandwidth that need be transferred, so is especially useful for delivery to limited-bandwidth mobile devices. The module is still only in a "development" state, and has a number of limitations which you should examine before use, but I think you will agree that there are some cool ideas going into this development and it is worth watching.
Variables that suck less
The Variables that suck less module, by beejeebus, is partially described with the caveat: "This module requires a core patch, and can break your site and eat your lunch." That said, if you need to resolve some site-crashing variable cache-clearing behavior and boost performance, and don't mind "killing kittens" in the process, this module might be helpful. It's currently got a
7.x-1.0-beta3 release.
Fast Private Downloads
The Fast Private Downloads module, by beejeebus, provides a Node.js -enabled method to improve the performance of private downloads in Drupal. It's still in an "alpha" development state for Drupal 7, but looks interesting, especially if you already have Node.js set up on your server for other features.
The jReject module, by Domenic Santangelo, allows a site to present a "your browser is out of date" message with download links for recommended browser versions if a user visits using an older browser version. Most such modules simply target Internet Explorer, but this module allows you to recommend a newer version of any browser which has older versions that might not support the cool features your site includes. It has a stable
7.x-1.0 release.
The env project (not actually a "module", per se), sponsored by NPR and authored by Irakli Nadareishvili, improves the ease of creating a portable environment-dependent set of configurations for Drupal so that you can easily have multiple configurations for dev, staging, and production sites, etc. Be sure to read the installation instructions, since this is not installed the same as "other modules" and requires changes to your
settings.php file and additions to your
sites/default directory.
The Genova project, by blueMinds, is not an actual module; it's a Drush utility which helps developers provide a "stub" for the creation of new modules, creating basic files, implementing hooks, database schemas, etc. The aim is to streamline all the boring, repetitive aspects of creating a new module to allow developers to focus on the important logic. It's still only available as a development snapshot, but what's been implemented and what's planned provide enough hints of coming awesomeness that we should plan to keep an eye on this.
The Subs module, by Alex Weber, helps create subscription services to a website's "premium content" with a broad range of features (e.g. useful subscription duration preset defaults, integration with Devel, Drush, Features, Rules and Views, automatic expiration of subscriptions, grace periods, etc.) Its only dependency is the Entity API (integration with aforementioned modules would obviously require having those available and active, too). If you are planning to build a paid-subscription service-based site this module could be exactly what you are looking for to streamline some of the involved business logic. The current version is a
7.x-1.0-beta2 release.
How do I allow a user to create other users?
It's a pretty common use case which requires a non-admin user role that can create other users for a Drupal site and I've frequently seen questions about how to best implement this. I recently also saw the suggestion to simply create a role with the 'Administer users' permission. At first blush, it might seem to work; if that's the only "administer" permission they have, users with this role can only create basic users with the role "Authenticated user", they cannot edit the user to add any other roles or upgrade their own role directly. In limited situations, this might even be appropriate.
What might not be immediately apparent, however, is that a user with this permission can edit any other user's account… and I do mean any. This means that, if their intentions are not pure, a user with this role could easily change the password (or any other fields) on a more privileged user, even
user/1, and then log into that account. Once they've done that, there is really no limit to what they could do to your site. Even if they have no means to add modules, ones which might be used for particularly nefarious purposes, if you have a module like Backup and migrate available, they could download your database with all sensitive user data; and even if this module is not available to them, you most likely have Views, which they could also use to harvest all user email addresses or other private data fields. And then they could easily cover their tracks, too. If they don't do anything obvious (like deface your site or start sending spam from it), and only change the password on the admin account, you might be puzzled by why you cannot log in with your normal password, and follow the normal procedure to reset your forgotten password, then forget all about it. Meanwhile, your "user moderator" has collected lots of sensitive data from your site and still has the means to do it again one day.
There's a module (or a few) for that!
Depending on your actual use case, which might include requirements a bit more complex than just creation of a basic "Authenticated user", there are a number of modules which might be useful for a "user moderator" role. Some of these modules do nothing about actual creation of users, after all, probably most Drupal sites allow users to just register themselves, but deal with the related need to delegate the responsibility of giving some users additional roles beyond the "Authenticated user" role. But for sites which don't provide self-registration, there are a couple of modules which allow non-Administrators to create new users, as well.
- Role Delegation is one of the most popular such modules, used by over 8000 sites with stable releases for both Drupal 6 and Drupal 7, but it's limited to role assignment and does not allow users without additional permissions to actually create new users.
- Administer Users by Role has stable releases for Drupal 5 and Drupal 6 and allows users of a particular role to create, edit, and delete other users. In theory, it should provide limits to the "administer users" permission by allowing them to administer users with roles that you select. There is no version for Drupal 7 yet available, but a port is in progress. It's a fairly popular module with about 2,500 users.
- RoleAssign is a module with a stable release for Drupal 6 and a "release candidate" for Drupal 7 and is used by about 2,800 sites. It allows users with appropriate permissions to assign pre-defined roles to other users.
- Subuser is a module available for Drupal 6 (stable) and Drupal 7 (currently in -alpha2). It is, perhaps, the most advanced and interesting of these modules, although it is not used by the most sites (currently only 282 sites). It allows for a user to be given permission to create users which that user then has permission to manage. Users not created by this "parent" user are not available for management. "Child" users can be given any of the roles which the "parent" is allowed to assign, and the role assignment can be automatic. In other words, an "editor" might create "author" users or a primary "site moderator" might create "forum moderator" users, etc. I think this module shows a lot of promise, especially since it's written and maintained by the highly esteemed boombatower, a true "Drupal rockstar".
- User Creator is a module which will not be ported to Drupal 7 (they suggest using the aforementioned Subuser module). It allows users with particular roles to create other users with particular role limitations. The example is provided that, for a school website, a "Principal" could create other users with the roles "Teacher" or "Student" and a Teacher could create only "Student" accounts. Site administrators can determine which roles are allowed to create accounts for which other roles.
- Control Access to User Settings is a module which seeks to increase the granularity for the "administer users" permission, so that user settings and user administration are separated under this permission and a site administrator can assign just a part of this permission. It has a "stable" release for Drupal 6 and a development snapshot for Drupal 7.
In short: Beware of granting excessive permissions
Be very careful (and generally avoid) granting any kind of "administer" permissions to non-Admin-role users. This article should make it clear that the "administer users" permission is one that could lead to disastrous results if given to the wrong user. While it might even be appropriate to give this permission to a very trusted "admin helper" (e.g. if you want to hide some of Drupal's administration complexity from your partner—so want to give them some admin permissions—to avoid having them be overwhelmed by the full admin interface), you must absolutely trust such a user not to do anything to abuse the power. And then, it's probably still best to use one of the appropriate modules, just in case you might forget and grant the same role to someone you trust less than your partner, just to allow this other person to add some new user accounts.
Hopes for the future of Drupal
As I see it, something like the Subuser modules could well be a part of Drupal core. There is almost no reason for any non-admin user to be granted the full power of "administer users", but there are many reasons you might want to allow for a role that can at least create users and provide limited management of other users (with fewer permissions than their own). I believe some degree of this functionality would be a good thing to include in Drupal core and hope to see that in the future.
In this chapter, Karen turns on the Date, Date API, and Date tools modules, and walks us through some initial configuration of core date settings, so that we can use Date module properly. We look at the site timezone settings, as well as talk about the core date formats. Then we go ahead and create some new custom date formats and date types.
At the latest Rhein-Main region Drupal meetup, and then at the recent DrupalCamp in Essen, I gave presentations about installing and configuring the latest version of the Eclipse IDE (Eclipse Indigo / 3.7.x) for Drupal development, with coverage of commonly-used plug-ins, and identified some features which enhance a Drupal development workflow. This article is related to that presentation and covers some tips for the PDT (PHP Development Toolkit), productivity shortcuts, and configuration requirements for coding in accordance with Drupal standards. The Aptana Studio (as an Eclipse plugin) is not covered in great depth; much of it differs from PDT and PDT-supporting plugins, so it may be covered in a separate post.
Disclaimer: I am not an expert Eclipse power user, nor am I a Drupal development expert, however I have taken the time to look at the latest developments and to experiment, so while this material might be especially helpful for people new to Drupal development who are just starting to use Eclipse and configuring it for the first time, I hope that even experienced Eclipse users may find some useful tips in this article. Before I started my internship for Cocomore, back in October 2010, I think I'd used Eclipse for one course in Java development, but it had been some years, and since then I'd used NetBeans in other courses, but whenever possible I still used my editor of choice, TextMate, which I still find most useful for those times when I just want to make a few simple edits. But there are times when a full-fledged IDE is the right tool for the job and when that's the case, it helps to have your IDE properly configured and to be proficient in its use. Writing this guide has helped improve my knowledge of Eclipse and I hope reading it will help yours.
Some benefits of the Eclipse IDE:
- Free / Open-source
- Multi-Platform (Java-based)
- Powerful debugging features
- Syntax highlighting and error flagging
- Lots of plugins to extend features
- Drupal templates available
- …
We may first want to talk about the pros and cons of Eclipse. Among the benefits of using Eclipse are that it is free and open source, it's a Java application which has builds for all major platforms (Mac, Linux, Windows), has powerful debugging features, is a full-featured IDE with syntax highlighting and error flagging, and that it has a very active developer community, which means that there are loads of plug-ins to extend the features of the basic Eclipse environment, and there are even Drupal templates available to help streamline your development workflow.
Downsides of Eclipse include:
- Resource hog
- Java-based, not a native app
- Some pricey IDEs may be better, especially if you already use them
- …
Some of the benefits also include the drawbacks: complex Java applications like Eclipse tend to consume a rather high amount of resources; since it is not a native application, its interface and some of the ways that it works may be a bit less polished than, for instance, a native Mac application. Because of the great number of plug-ins available, and the complexity of the system, even without considering plug-ins, Eclipse has a steep learning curve. Finally, some commercial IDE's may be better, especially if you already own and use them, in which case there might be little reason to experiment with Eclipse.
Downloading and Installing Eclipse
This article was written using the latest version of Eclipse, so-called Indigo or version 3.7.x, but I have also used earlier versions and much of the material should apply to other Eclipse versions, both past (and likely) future versions. To best follow along with this article, please download the latest version of Eclipse Classic appropriate for your operating system. There are some bundled versions (Eclipse plus PHP plugins) available, but at least at this time, neither the Eclipse package nor the PHP Developer Tools in recent bundles are very up-to-date, so you're probably best off just getting all of the most recent stable releases separately.
I'm using Mac OS X, (10.6.x, aka "Snow Leopard"), so chose to download the 64-bit version of Eclipse classic for OS X, which should also be appropriate for Macs already running OS X "Lion" (10.7.x). If you have a suitable system, the 64-bit builds should be your best choice. In any case, installation is simple. You merely download a gzip tar ball, unzip it, and put the resulting directory under applications, or wherever makes most sense on your system. This probably goes without saying, but of course you do need a Java virtual machine (JRE or JDK). If you think you might be doing some Java development, you'll want to install the JDK, otherwise at least a JRE. Modern versions of Mac OS X already have a suitable Java runtime environment, by default, so if you are on a Mac, you should probably be okay. Please note that Linux users may want to use the Oracle JDK if they plan to use the latest Aptana studio as the OpenJDK is apparently not supported. If you are on Windows or Linux, you may want to look over the installation notes for Eclipse and/or download the Oracle JDK or JRE.
When you first start Eclipse, you'll be asked to select a location for your workspace. This is where Eclipse stores your projects and preferences. Note that your source code does not need to be in this location, and indeed, if you do put source code in this directory, e.g. a Drupal installation, it will not allow you to create a new project from it. It's also a good idea to create projects with the directory structure which includes the Drupal root level; that way, core functions will be recognized within your code, and documentation and auto completion hints will show up. When the IDE opens, you'll see a welcome page. You may want to take a little time to browse the overview or tutorials sections before going to the workbench view.
Plugins in Eclipse, like modules in Drupal, are the source of the power
There are a number of Eclipse plugins which you might find useful for your PHP/Drupal development workflow. Following are some of the plugins you are most likely to use. If you already know how to install plugins into Eclipse, the list below provides the general installation info for several plugins; but I will also provide more detailed information about others. Note: Trying to browse to the links given for "Location" will result in an error; those URLs point to the repository Eclipse uses to install and update plugin software. If an "Info" link is provided, that is the place to read more about the plugin.PHP Development Toolkit (PDT)
The PDT has long been the primary plugin for PHP development in Eclipse, although now the Aptana Studio 3 plugin also supports PHP development, so it's possible you could do without the PDT (there are certainly some benefits to both, but which you prefer and whether you want both installed is a personal decision). (More about the PDT, below.)
- Name: PDT
The Eclipse Marketplace client plugin helps find and install popular plugins directly into Eclipse with an interface to browse the selection of available plugins on the Eclipse Marketplace website. It's actually a part of the distribution in most other packages of Eclipse, but is not included in the "Classic" package.
- Name: Marketplace Client (MPC)
The XTND.US Drupal for Eclipse plugin adds support for the common Drupal filename extensions so that they are recognized and opened as PHP files (or text files in the case of .info, etc). More about the Drupal for Eclipse PDT plugin, below.
- Name: XTND.US
- Location: http://xtnd.us.downloads/eclipse
The EGit plugin provides a GUI for exploring your Git repository. You can add an existing Git repository to Eclipse, clone one from the EGit GUI, or create a new Git repository from Eclipse. Note that you already need to have Git installed; neither EGit nor Eclipse include a Git client. (More about EGit, below.)
- Name: Indigo
This is actually included in Indigo, but needs to be added to earlier versions of Eclipse. At least part of this is probably already included in your Eclipse Indigo download, even if it may not be installed/active.Subclipse for Subversion (SVN) Integration with Eclipse
While Subversive is the default Eclipse SVN-integration plugin, you probably want to use Subclipse, instead. Subversive is the one you will find if you search for "SVN" or "Subversion" in the general "Install new Software…" panel. But Subclipse has about triple the user satisfaction ratings on the Eclipse Marketplace, is much more recently updated, and is maintained by Tigris.org, the makers of Subversion. If you are using a different version of the Subversion client from 1.6.x, you will want to check the Tigris website for the correct version of Subclipse. More about Subclipse, below.
- Name: Subclipse 1.6.x (Eclipse 3.2+)
Note: This plugin is only for the PDT PHP editor, the Aptana Studio 3 "PHP Source" editor already includes a Word Wrap function. If you have both PDT (with the Ahtik Word Wrap plugin) and Aptana Studio 3 installed, you will see two different Word Wrap options in the contextual menu, even though only one of them will apply to the editor you are currently using. Note: Since the word wrap feature does not maintain line numbes, when turned on, you should only turn this on when you need to (or should remember to turn it off when debugging by line number.) This is a known bug, but can at least prevent the need for horizontal scrolling through long lines, like unbroken translatable strings.
- Name: Ahtik Word Wrap
- Name: Webtools
Allows you to integrate PHP CodeSniffer and PHPUnit, among other useful features. This is required for the Drupal Code Sniffer library, which you can load as a support library for PHP CodeSniffer (helps identify issues with Drupal coding standards compliance). Drupal.org documentation has information about how to set up the PHP CodeSniffer to work with the Drupal Code Sniffer library.
- Name: PTI
If you want to still work with the PDT and plugins which extend it, without conflicts, you are probably better off using the standalone version of Aptana Studio, but if you install Aptana Studio 3 and don't mind doing without PDT and some of the PDT-related plugins, this has some cool features which will likely be covered in a separate post since Aptana Studio is a topic worthy of separate discussion and since so many of the plugins and techniques outlined in this article are really PDT-centric. The Aptana Studio is available as an Eclipse plugin, however, which, if you are happy with how you have Eclipse configured, can be a nicer way to work; some people may prefer the Aptana PHP editor to what is provided by the PDT. More info on the official Aptana Studio 3 downloads page. Note: Aptana Studio 3 will not support your PHP templates from PDT, but has a set of Drupal 7 templates available which include more than the Drupal Eclipse (hook templates); you also have theme function templates, among some other cool features, but nothing for Drupal 6.
- Name: Aptana Studio 3
- Name: Aptana Studio 2
The Eclipse Color theme plugin provides a set of extra color themes you can choose from rather than the limited appearance configuration available in Eclipse, by default. I don't mind Eclipse's default theme, but some users find this a "must-have" plugin. Note: If you are using the Aptana Studio plugin, the Eclipse Color Theme plugin won't be used in Aptana-provided editors; Aptana has its own appearance settings.
Settings for the color theme are found in the preferences panel under:
General > Appearance > Color Theme
- Name: Eclipse Color Theme
The PHP Developer Toolkit (PDT) Plugin
The first plug-in you will probably want to install is the PDT (PHP Developer Toolkit). To install it, simply go to the Help menu, and at the bottom, you should see the option to "Install new software…". If you select from the list of available software sites, you'll see downloads for Eclipse.org releases for Indigo, and among the available downloads, in the programming languages section, you'll see the PHP development tools are available for download, however these are not the latest version, at least not at this time of this writing.
Instead copy the linked URL (do not follow this link as it is only used for the repository and does not contain HTML) into the field labeled "work with", and click on the "Add…" button. The "Add Repository" dialog will prompt you for the a name and location. I just used "PDT" as the name; the "Location" has already been filled in with the URL added in the "Work with" field. I installed the full development tools all-in-one SDK, but at the very least, you'll probably want the "PHP Development Tools (PDT) SDK Feature". Select the components you want, and continue to the next step, where it should confirm which packages will be installed. At the next screen, you'll need to accept the terms of the license agreements before you'll be able to click on the finish button and complete installing your software.
You should see a progress bar as the installation is completed, and when it's done there will be a prompt to restart Eclipse. When you are installing a number of packages in a row, it may be just fine to click on the "Not now" button, to continue installing other packages, but since the proper installation of the PDT is critical for some of the next steps, restarting now is probably a good idea.
The Drupal for Eclipse PDT plugin
The Drupal for Eclipse plug-in, available from XTND.US, is a useful extension to the PDT. Note that if you read through this guide and decide that you want to use the Aptana Studio plug-in for Eclipse for your PHP code, you might skip installing most other plugins. It's possible to use both the Aptana Studio 3 plugin and PDT, but you may encounter some conflicts and things can get more confusing. In any case the XTND.US Drupal Eclipse plugin is only for PDT and it doesn't do much more than associate the PDT-provided PHP Editor to files with the
.engine, and
.theme file extensions so that these files are recognized as being PHP code. In my experience, the repository where this plugin is located is sometimes not available, so you may get an error when attempting to add this plugin.
The EGit plugin as a Git GUI within Eclipse
EGit offers an Eclipse-integrated front-end for Git. Once the plugin has been installed, to work with it, click on the Open Perspective button, up near the top right of the Eclipse window (look for the little yellow plus sign). Select "Other…" from the drop-down menu, and then select "Git Repository Exploring" and click "OK".
From the Git perspective, you can create a new repository, clone a repository, or add an existing already-cloned repository. In the illustration, I chose to open a repository I already had in my file system. Since the
.git file won't show up, assuming you are using Mac or Linux, when browsing the main repository directory, you should check the "Look for nested repositories" checkbox, then click on the "Search" button, and the.git file should show up in the results below, where you can select the checkbox next to it and finally click on the "OK" button.The Git Repository Exploring perspective might be especially useful for those of us who are not already proficient with Git from the command-line, especially if you don't already have another GUI for Git.
Subclipse for Subversion (SVN) integration
At Cocomore, all of our projects are in Subversion. If you also need to be able to check out and commit to SVN repositories, you will want to add a supporting plugin to Eclipse. I should point out that for Git support and SVN support, all the Eclipse plugins do is add a front-end. You will need to install the appropriate SVN and/or Git client(s) for your operating system, just as you needed Java (a JVM) in order to run Eclipse, itself. There are two plugins which are commonly used for SVN support. The default one, Subversive, which is from Eclipse, is not the more popular of the two and I strongly recommend using Subclipse. At this time, if you look at the Eclipse Marketplace website, you'll see that the latest version of Subversive is about two years old, whereas Subclipse's latest release is July of last year — and you will also see that it has about triple the ratings. Subclipse is from Tigris, the developers of Subversion, so this also lends some credibility to their version. In any case, your experience may differ, but I accidentally got Subversive when I first set up Eclipse, soon after I started my internship with Cocomore, and couldn't get things properly configured for our "svnexternals" repository until I replaced it with Subclipse, at which point it was just simple. So assuming you take my advice and use Subclipse, you will need to add the repository using the "Work with…" option when you go to
Help > Install New Software…. And you first might want to go to the official Subclipse website to check which version to use with the actual Subversion client you have installed. I'm using Subversion 1.6, so used the corresponding plug-in. After installing, you'll find new preferences for SVN and should be able to create new projects by checking them out from SVN, compare diffs of versions, commit new or edited files, etc.
Uninstalling plugins
Sometimes you experiment with a plugin, only to find that it doesn't do what you want it to do or that it conflicts with other plugins you're more interested in keeping. Luckily uninstalling plugins is simple, but the interface for uninstalling plugins is not as easily found as for installing them. It's actually the same interface. Simply open the
Help > Install New Software… window and look for the link near the bottom "What is already installed?". Clicking that opens a new window showing installed plugins. If you select a plugin, you will see the option to uninstall it becomes active. This is useful if you want to optimize your Eclipse installation to trim extra cruft you aren't using or if you accidentally install a full package when you only wanted one component. Unfortunately, some plugins, such as the Aptana Studio 3 plugin, can only be installed as a whole package, not by sub-components. You can also uninstall plugins to troubleshoot issues. It will be easier to reinstall the package if uninstalling it does not resolve a possible conflict issue since the repository will still be available for easy selection and, even better, any associated preferences are not removed along with the plugin.
Most critical… Preferences for configuring to Drupal coding standards
The preferences window in Eclipse has many critical panels where you will need to configure settings for proper support of Drupal coding standards. Especially important: you'll want to make sure that your text file encoding is set to UTF-8 and that the line delimiter is set to "UNIX". Don't ask me why these settings are stored under "Workspace".
Set tabs to two spaces
General > Editors > Text editors
Perhaps of greatest importance is making sure you use spaces instead of tabs and a tab-width of '2'. In the illustration shown above, I also turned on a print margin of 80, since we normally want to keep lines to a maximum of 80 characters long. Getting into the details of Drupal coding standards is outside of the scope of this article, but if you are not familiar with the Drupal coding standards, you'll want to read them; the Drupal coding standards are well documented. You'll find similar settings which you need to change in just about every text editor for each language: PHP, CSS, XML, etc; set the tab policy to spaces and the indentation size to two in each.
Other places to fix tabs/spaces/indentation settings:
Preferences > PHP > Code Style > Formatter
Preferences > Web > CSS Files > Editor
Preferences > Web > HTML Files > Editor
Preferences > XML > XML Files > Editor
Note: If you install other language support or add plugins like the Aptana Studio plugin for Eclipse, you will likely have additional editors you need to configure in this way.
Remove trailing whitespace
Preferences > PHP > Editor > Save Actions
Be sure to set the PHP editor save actions to remove trailing whitespace from all lines.
Importing Drupal hook templates
Another useful thing we can do from the preferences panel is import templates for Drupal hooks. The templates, themselves, can be downloaded from the Eclipse project on Drupal.org which, although listed among modules, is not a module at all, but instead contains an XML file with definitions for templates for each of the Drupal core hooks. Both the Drupal 6 and the Drupal 7 versions extract to the same directory name, "eclipse", and you can install both of them if you code for both Drupal 6 and Drupal 7. To use them, simply go to the PHP editor templates section in your preferences panel and click on the button labeled "Import" at right.
Preferences > PHP > Editor > Templates
Navigate to where you saved your downloaded Drupal Eclipse project, and select the XML file within, and almost instantly you'll have hundreds of templates for all of the core hooks. To use the new hook templates, all you have to do is start typing the name of a hook, for instance "
hook_action" and you should see an auto-complete helper which displays the signatures for each of the different hooks available starting with whatever you typed in. Replace the selected
module_name part with the short name of your module and hit ⇥ (tab) to continue to the template's default cursor position. If your module name appears more than once in the hook function, you only need to type it once.
Creating your own templates
You can also create your own templates. For instance, if you are writing a module which makes heavy use of hooks provided by the Views module, and anticipate writing other such modules, you can create templates for these hooks easily enough, simply by looking up the API, copying the hook function definitions, pasting them in the area for the pattern of your new template, and making a few minor modifications. To see how the patterns are created, it can help to look at an existing template in "Edit mode".
Here, I've opened up the template for
hook_action_info_alter(). Note that the "
hook_" part has been replaced with "
${module_name}", a template variable, and all of the dollar signs in the function have been doubled in the template. The
${cursor} variable is a special placeholder for the cursor insertion point after replacing the
${module_name} variable. If you click on the button labeled "Insert variable…", you can experiment and see how other variables (replaced when using the template) can be used. Also pay attention to naming conventions since your name and description will appear in your code hints. Ideally, you should aim to keep non-core API hook code separate from the core API hook code by appropriate naming and descriptions.
The drupalcontrib.org website is a good place to find API documentation for contrib modules. Let's assume we want to add a hook for a Views API function, like the Drupal 7 version of hook_views_form_submit. All we need to do is click on the "New…" button and copy and paste code and descriptions, then make the appropriate changes, doubling all existing dollar signs, replacing the
hook_ with
${module_name} and put the
${cursor} in an appropriate position. Of course we might want to add an appropriate comment block above the function part of the template, perhaps indicating that the function
implements hook_views_form_submit and/or that the function is a
Views form submit handler.
Use keyboard shortcuts for a productive Eclipse workflow
Preferences > General > Keys
Eclipse's keyboard shortcuts are awesome and help perform a number of actions which would take much longer with the mouse or trackpad, not to mention that they keep your hands on the keyboard, where they belong if you want to develop a productive coding workflow. Like many other useful parts of Eclipse, the hotkey bindings are hidden in a Preferences panel, but can easily be reached with a keyboard shortcut. To see all shortcuts without opening the preferences, you can hit ⇧⌘L (Ctrl-Shift-L on Windows or Linux), which pops up the Key Assist selector. This can be useful for learning the keystrokes, but may not be much quicker than finding the command from the menu (and looking at any keystroke shown there).
If you hit the same keystroke combination again, i.e. ⇧⌘L twice, the preferences panel for keystrokes will pop up. By the way, opening the main preferences window is most easily done with a keyboard shortcut, too: ⌘, (i.e. Command + Comma on Mac, or Ctrl-, on Windows and Linux.)
The Keys Preferences panel
The Keys preferences is where you can get a bit more information, quickly search for the keystroke you are looking for, or assign new keystrokes to commands. By default, the panel opens with all keystrokes sorted by command name. Clicking on the column header labeled "When" or "Category" to see shortcuts sorted by context (editing, navigating, Git, window, …) can make it simpler to see commands related to your current needs. You can also type in a word you are looking for, e.g. in the illustration below, we are looking at all commands related to "move" and can now see that the very handy keystroke for moving selected lines up and down in the document is ⌥-↓ / ↑ (alt-↓ / ↑). So holding down the alt/option key while using the up/down arrows can move a block of code around. This can be very handy and it's worth mentioning a related keystroke: if you add ⌘ (Ctrl) to this (i.e. ⇧⌘-↓ / -↑), the current line (or selected lines) are duplicated above or below, which can be useful for adding a similar line (e.g. initializing an array with key/value pairs). It's much quicker than selecting the line, copying it, moving up/down, then pasting.
Of course some of the default keystrokes assigned by Eclipse may conflict with keystrokes used by your operating system. If it's an obscure task you never perform in your OS, of course you can go into the appropriate preferences panel for your operating system and remove the keystroke or reassign it to something more complex (less likely to conflict with any other application-specific keystroke). Or you can reassign the keystrokes (binding) used by Eclipse, quite simply, by typing your desired keystroke combination in the "Binding" field of the Keys preferences panel. And, of course, if there are commands that you commonly use, but which are not assigned to keystrokes, you can find the commands and add a new binding. Very cool!
A few of my other favorite keyboard shortcuts in EclipseDelete
⌘D (Ctrl-D)
Delete (current line or selection). Of course you can use many methods to delete a selection, but to delete a line without first having to select it is handy.Go to function declaration
If the function declaration is in the same file, it just takes you to the function declaration, but where this is really handy is when the function is declared in another file, e.g. if you have selected a call to
drupal_attributes() in a contrib module and hit F3, you'll see a new editor tab open with (Drupal core's)
common.inc scrolled right to the function declaration on line 2295.
⌃Q (Ctrl-Q)
Return the cursor to the last edit location. Very useful if you have been browsing around a lengthy document, perhaps copied something from somewhere else, and now want to return to where you were editing.Maximize/Restore view
⌃M (Ctrl-M)
Maximizes the currently-active "view" (section of the Eclipse window), especially useful when working on a smaller monitor when you want to have the editor area at its maximum width. Hitting the keystroke again restores the normal perspective (e.g. shows the Project Explorer at left, etc). Note: Double-clicking a tab performs the same function.Next / Previous
⌘K / ⇧⌘K (Ctrl-K / ⇧-Ctrl-K)
Jump forward and backward in the editor between, for example, function calls in a document (or next/previous occurrences of whatever you have selected.)Outline - Look up functions in document
⌘O (Ctrl-O)
Displays a quick contextual menu to navigate to any function in the current document (or quickly view the function signatures). For classes, it displays a class outline.Search
Much more refined search options than the simple "find" function (⌘F
). Both "search" and "find" support replacement, but "search" also supports searching/replacing within the whole project or workspace rather than just within the document or selection, as well as searching within different document types, regular expressions, etcSwitch Editors
⌘F6 (Ctrl-F6)
Switch between open editor tabs; works similarly to the "Switch Views" pop-up menu in that repeating the key sequence steps you through available editor tabs in the menu. Enter or mouse-click selects the editor tab.Switch Editor (filtered)
⌘E (Ctrl-E)
Works similarly to the normal "switch editor" menu, but has a filter field at the top where you can start to type non-case-sensitive file-names to filter the list of available editor tabs. This one is especially handy if you have a lot of editor tabs open.Switch Perspective
⌘F8 (Ctrl-F8)
Provides a menu similar to the Switch Views / Editors pop-up, which instead allows you to switch perspectives.Switch Views
⌘F7 (Ctrl-F7)
Pops up a switcher to move between views. Hitting the same key sequence moves you through the available (open) views. Enter or mouse-click selects the view.Toggle line comments
⌘-/ (Ctrl-/)
// line comments: Adds or removes
// line comments in front of each selected line. Useful when debugging code.
There are lots of great plugins for Eclipse; this guide only scratches the surface. Do you have any favorite plugins, keyboard shortcuts, or other hot tips for a productive workflow with the Eclipse PDT? We'd love to hear them, so please do share your knowledge in the comments, below.
I was already planning to provide an overview of what's been going on in the various Drupal 8 initiatives even before last week, when Dries announced the timeline for Drupal 8, which includes a "feature freeze" for Drupal 8 in only a little more than nine months from now, and planned release at the DrupalCon Europe, in late August 2013.
Drupal 7's Plateau of Productivity?
While most of the top Drupal 6 modules are now available, in some state or another, for Drupal 7, and I would certainly choose Drupal 7 for a large Drupal-based project that is not expected to be deployed for some time, from the outcry of protests I think there are a lot of people who would not agree that Drupal 7 is yet at its Plateau of Productivity. I would choose development in Drupal 7 for most projects, but there is still plenty of reason for site builders to work with Drupal 6, especially if they need particular features (e.g Nodewords / Metatag functioning properly, among others) and if they need to deploy the site now, with those features ready for use. Dries indicated that he thought Drupal 6 reached its Plateau of Productivity in late 2009, about 18 months after its initial release. At that point, there were fewer than 20,000 sites using Drupal 5 and more than 200,000 sites using Drupal 6. While this order-of-magnitude-greater-usage is not likely to ever be seen comparing Drupal 7 vs Drupal 6 usage (at least not before Drupal 8 is released), I do think that it's significant that Drupal 7 usage has finally overtaken Drupal 6. That said, I don't think we are truly at Drupal 7's Plateau of Productivity, the point where building a new site on Drupal 6 would be "pointless". Both in terms of time-after-release and usage statistics, it is arguably premature to say we are quite to that point yet.
Quibbling aside, I also don't think it matters whether we believe we have reached the Plateau of Productivity for Drupal 7, or not — and it certainly doesn't matter whether we are all in agreement about that. I do think Drupal 7 is very "ready for use", though and I do think we are ready to see core development for Drupal 8 get kicked into high gear and I don't think it will significantly delay the development of certain lagging contrib modules or resolving core issues in Drupal 7 which are the final barrier, in my view, to truly reaching its Plateau of Productivity. Additionally, many of the fixes and features going into Drupal 8 are regularly being back-ported to Drupal 7, and there is increased discussion of relaxing the criteria for what can be back-ported to Drupal 7, so I see the increased attention to Drupal 8 core development as exciting: a win-win for the whole Drupal community. We now have a release date for Drupal 8, which is important for business decisions, and a better timeline to facilitate a roadmap for the final stages of determining feature inclusion.
Drupal 8 Core Initiatives
Currently there are 6 official Drupal 8 Core Initiatives which are working on various aspects of desired improvements to core. There are others likely to be added to the list as soon as a bit more progress has been made on the current list and/or as qualified individuals step up to take on some of the other "top 10" desired improvements we had on our collective community wishlist. Some of the improvements require fixes to issues plaguing Drupal 7 and 6 and have been backported. Most of the others involve dozens, if not hundreds, of related issues. Following is a brief summary of each of the current core initiatives and what their priority goals are for Drupal 8. In the interest of brevity, the explanations leave out a lot of juicy details, but for those who haven't been paying close attention and who might like to get involved, I hope this summary is useful:
Web Services and Context Core Initiative
The Web Services and Context Core Initiative (WSCCI, pronounced "Whiskey"), formerly referred to as the "Butler" project, is a core initiative led by Larry Garfield of Palantir.net, aka "Crell" on Drupal.org. While the traditionally typical HTTP request has been for HTML pages, the modern Web has brought with it the need for HTTP services which deliver information which is not necessarily in the form of HTML. This is especially true for mobile applications, but also applies to feeds and other communications via HTTP. The goal is to "take Drupal from being a first-class Web CMS to being a first-class REST server which includes a first-class Web CMS". Really, this initiative spans a huge range of related issues and without writing an article many times the length of this one, I could not possibly cover everything, but…
Using Symfony2 components is a big part of this effort; Symfony2 is an open-source application framework with a lot of nicely abstracted and discrete components, several of which are being integrated into Drupal to build on its strengths as a CMS. The HttpFoundation and ClassLoader elements have already been added to Drupal 8, but the latest WSCCI Sprint, attended by almost all of the Drupal core developers most of us can probably name, along with Fabien Potencier, the Symfony lead developer, determined that several other Symfony2 components would also be included. While these changes may sound daunting to many long-time Drupal developers, it should actually make the core much more approachable for developers new to Drupal, while also making Drupal inviting to experienced Symfony developers. Additional benefits include reducing a the heavy load of Drupal requests, making it more "lean and mean" and providing partial page caching for example, while also delivering a number of powerful features for Panels-like applications, better blocks, and much, much more. Some of the work related to the WSCCI project has been underway for some time now and was encapsulated in a Drupal 7 development module called "Butler". [Update: I had linked in the Butler project, but Larry Garfield has indicated it is "vestigial" and there is no way that any of the final WSCCI changes will be back-portable or functional as a D7 module.]
If you want to learn more about WSCCI, Daniel Kudwien (aka 'sun' on Drupal.org) has recently posted an excellent article which, similar to Dries's post about the Sprint, also focuses largely on what was covered at the recent WSCCI Sprint and goes into greater technical depth about what it all means. Update: There is also a new post from Larry Garfied which also explains some of the latest developments in WSCCI. Again, this is a huge and crucial initiative for Drupal 8 to live up to the envisioned dreams, and there are ways for community members of all experience levels to dive in and contribute to its success. There is a ton to do in the months remaining.
Multilingual Initiative
The Multilingual Initiative, led by Gábor Hojtsy of Acquia, covers a wide range of issues related to improving Drupal 8's support for multilingual support (internationalization and localization issues). The issue queue is daunting, but there are a lot of experienced developers pitching in. If you've worked with non-English sites in Drupal or sites with more than one language, or have written and contributed a module and then realized you had to sort out how to deal with all the issues related to multilingual support, this work should be of interest. I'm not going to go into all the pain points you might be aware of in Drupal 6 and Drupal 7 or which of the improvements have been or might be backported, but we can only hope that many of them will be. Issues related to language negotiation, translation, and associated APIs are a particularly confusing area of Drupal and the more they can be improved, the better. There was a Multilingual Sprint which was just held in Budapest (with participants in other areas communicating via IRC) and a multi-day Sprint is planned to follow the Denver DrupalCon.
Since a primary reason for the existence of the Cocomore Drupal Core and other related Cocomore-maintained contrib module forks has been issues related to multilingual support, this is of particular interest to the Cocomore development staff, as it should be to anyone working with non-English or multilingual Drupal sites or who cares about making their modules and themes properly locale-aware. So jump in and help out if you can!
Mobile Initiative
The primary goal of the Drupal 8 Mobile Initiative, led by John Albin Wilkins of Palantir.net, is to make Drupal the leading mobile CMS. While there are naturally overlaps between the goals of the Mobile Initiative and the WSCCI (web services needed for native mobile applications) and HTML5 initiatives, there are still a wide range of goals left for the Mobile Initiative to work on, including (but not limited to):
- Getting Drupal's administrative forms mobile-device-ready
- Converting Drupal 8 themes to be "responsive"
- Performance improvements (e.g. "responsive" images)
For the Mobile Initiative to be truly successful, the team will need a great deal of community support, not only from the obvious PHP and Javascript coders, but also people with design and usability knowledge and ideas, people knowledgeable about accessibility issues, HTML and CSS gurus, people to help with documentation, and testers… lots and lots of testers with every kind of mobile device.
I should mention, for readers who are new to Drupal, that mobile support is not something new to Drupal 8; you don't need to wait for it since there are already ways to produce mobile content in Drupal 6 and Drupal 7. But the mobile initiative will hopefully take a lot of the current pain out of working with all the inter-related modules, themes and other technologies required to have anything approaching an ideal solution to mobile issues in current versions of Drupal. You should still do a search to find the right solution for your use case, but some of the popular mobile-related modules include: Mobile Tools, the Mobile Theme module, Browscap, SMS Framework, WURFL, and Mobile Codes, Phonegap, among other common modules which are not specifically for mobile development, but can be helpful. And DrupalGap is another promising module which is still in the developer's "sandbox" at this time. There are a number of themes which are well suited to Drupal development, including the Mobile theme, which can be used as-is or as a basis for a custom mobile theme, AdaptiveTheme (as well as all of the themes based on it, such as Pixture Reloaded, Sky, and Corolla), and Boilerplate. You'll find numerous blog articles, recorded DrupalCon sessions, and resources. There is also a new book which is expected soon and which you can already pre-order and start reading (RAW): Drupal 7 Mobile Web Development Beginner's Guide.
HTML5 Initiative
The HTML5 Initiative, headed by Jacine Luisi, is another of the major initiatives for Drupal 8, which (as mentioned, above) has strong ties to the success of the Mobile Initiative, as well. You probably saw the announcement a few months back that Drupal 8 already has HTML5 as its default "doctype", but that was just the first step toward getting Drupal 8 fully HTML5-ready. Templates, theme functions, markup… everything needs to be ready and there are still plenty of open issues related to HTML5 in Drupal 8 if you'd like to join the effort.
The HTML5 Initiative also has close connection to the web services and mobile initiatives, of course, so getting this all working is a vital part of the effort.
Configuration Management Initiative
The Configuration Management Initiative (CMI), led by Greg Dunlap (aka heyrocker on drupal.org), aims to sort out the issues related to maintaining, storing, and deploying configuration of a Drupal site. Currently, all the configuration for a Drupal site (except, of course, for the basic database access settings stored in settings.php) is stored in the database, and deploying it is a pain. Furthermore, if someone changes settings and it breaks site functionality, there is no simple way to "roll back" just those changes. The CMI moves all configuration from database to disk in a standard format which can be more easily deployed, can be stored in a version control system, and can be used in multiple sites more easily. This provides a much better development workflow to easily take configuration used on one site to another, and to modify it, as needed. Of course it should provide for much more useful distributions and installation profiles.
You can read more technical details about the CMI, at least as it was initially conceptualized, in Webchick's summary of the first CMI Sprint held in June 2011 and there is ongoing discussion of the initiative in this Drupal Groups thread. Needless to say, this should be a big improvement over what's currently possible to do with Drupal's Features module, but if you need to package configurations to use them on multiple sites, the Features module is currently your best friend.
Design Initiative and Usability/UX
Last, but certainly not least, the Design Initiative, led by Jeff Burnz of AdaptiveThemes, aims to give Drupal a new look for Drupal 8 Of course the theme design will also be fully mobile-ready. Part of the effort involved designers collaborating about the new look before the coding phase for the theme was begun. According to the official timeline set out by the initiative team, we are now in the middle of the development phase. If you are a theming expert and want to help, contact the initiative team and see what you can do. Currently all work is in the initiative development sandbox, so you won's see it committed to the "current" (Git) version of Drupal 8 until it's pretty well done.
I know, I know... my graphic for this section has more to do with UX than "Design", per se, although they are closely related. Good designs should be user-friendly. Anyway, strictly speaking, Usability is a completely different initiative which is not currently on the "hot-plate", at least not for Drupal 8. Why? I guess there is always time to improve the UX of a product as long as it does not break (too much) and does more good than harm, so improvement to UX can continue even after product release. And of course we still have 18 months before Drupal 8's release, so getting the core features right, first, is of most importance. If you are interested in Usability issues, however, there are regular meetings held in IRC. You can connect with the Drupal Usability group here. You might be particularly interested in the discussion of the recent Drupal 7 Usability Study at Google. The videos videos from usability study are particularly useful for identifying current "sticky points" in Drupal 7's usability. Presumably all of these usability issues will be fixed in Drupal 8 and hopefully most can be backported to Drupal 7 without causing more harm than good.
The "Current" State of Drupal 8 Core Initiatives is in the initiative sandboxes
As a point of reminder, don't expect to see much of the progress in Drupal 8 if you check out the project from Git. Not a lot has been pushed to the central repository and is, instead, on individual developers' repositories and/or in shared initiative "sandbox" repositories. By keeping experimental code out of the "master" repository, the hope is to keep the issue count down and prevent issues caused by incomplete code in one area of the product from wreaking havoc (or masking issues) in other parts. This is the benefit of a distributed VCS like Git, but it also means that in order to test the latest, most experimental features, you will need to work with the sandbox versions.
So many initiatives, so little time!
If you are like me, you are now inspired but you might be having trouble picking where to best apply your talents. Check out the issue queues for each initiative if that's the case. You might find something you can take on and help lay a few stones in the foundation of what's sure to be the most awesome version of Drupal yet!
Installation procedure
While there are several ways to install Tomcat 6 and Apache Solr, we will use the repository version to gain the benefit of automatic updates.
What is needed:
Tomcat6 as Servlet container
sudo apt-get install tomcat6
sudo apt-get install tomcat6-admin
Apache Solr Search Server
sudo apt-get install solr-tomcat
Once everything has been correctly installed, you should see the message, "It works!" at http://localhost:8080 and "Welcome to Solr!" at http://localhost:8080/solr/
Configuring Tomcat 6
In the default Tomcat installation, no privileges are created for the Tomcat Manager, so in order to make use of the Tomcat Manager GUI, we still have to create the proper role and a corresponding user.
Add the following lines to your Apache Tomcat 6 configuration file
We'll edit it with Vim:
sudo vim etc/tomcat6/tomcat-users.xml
<role rolename="manager-gui"/>
<user username="tomcat" password="tomcat" roles="manager-gui"/>
Now we need to restart Tomcat:
sudo service tomcat6 restart
Now we can start the manager at http://localhost:8080/manager/html. At this point, you could also deploy Java applets, but for our use case, the manager simply provides an overview of our Solr installations.
Drupal-specific customization
In order to use Solr with Drupal, we still need to make some adjustments to our Solr configuration.
We'll start by creating a new directory in the file-system:
We'll use Vim to create a new file (
sudo vim solr_cocomore_drupal_demo.xml) with the following content:
<Context path="/solr" docBase="/usr/share/solr" debug="0" privileged="true" allowLinking="true" crossContext="true">
<!-- make symlinks work in Tomcat -->
<Resources className="org.apache.naming.resources.FileDirContext" allowLinking="true" />
<Environment name="solr/home" type="java.lang.String" value="/opt/solr-tomcat/solr_cocomore_drupal_demo/" override="true" />
And we need another file (
sudo vim solr.xml), containing the following code:
<solr persistent="false" sharedLib="lib">
<cores adminPath="/admin/cores">
<core name="cocomore_drupal_demo" instanceDir="cocomore_drupal_demo">
<property name="dataDir" value="cocomore_drupal_demo/data" />
Next we need to create a sub-directory…
sudo mkdir /opt/solr-tomcat/solr_cocomore_drupal_demo/cocomore_drupal_demo
Now we copy the current standard Solr configuration files
cp -R /etc/solr/conf /opt/solr-tomcat/solr_cocomore_drupal_demo/cocomore_drupal_demo/conf
The following files must be present in the conf directory for Apache Solr to function:
The files marked in red will be replaced with those included in the ApacheSolr Drupal module.
Now we need to tell Tomcat where our Solr configuration can be found. We will create a symlink for this purpose:
sudo ln -s /opt/solr-tomcat/solr_cocomore_drupal_demo/solr_cocomore_drupal_demo.xml
Important: Set correct privileges!
chmod -R 775 /opt/solr-tomcat/solr_cocomore_drupal_demo/
chown -R root:tomcat6 /opt/solr-tomcat/solr_cocomore_drupal_demo/
Now, when we visit http://localhost:8080/manager/html, we should see our Solr installation (solr_cocomore_drupal_demo).
Adding and activating the Drupal 6 Apache Solr Modules
The following modules must be installed and activated in our Drupal project:
Before we can activate the Apache Solr Search module, we must first install the SolrPhpClient in the ApacheSolr module's path, ideally with:
Note: If you do not have SVN installed, you can download the SolrPhpClient from a variety of sources. See the readme file included with the ApacheSolr module for further information.
Now we should activate the following modules:
- Search (if not already activated)
- Apache Solr framework
- Apache Solr search
- Apache Solr multilingual
Configuring the Apache Solr module in Drupal 6
Since the default settings should match the module, a connection can already be made to Solr. However, we do not want to use the default Solr index, but our own core, so we have some adjustments to make.
Now we set our Apache Solr core
The core consists of Corename and Instance, entered in the Solr path field:
Other settings - Apache Solr module (Drupal 6)
"Number of items to index per cron run:" A reasonable value is 50. Higher values can result in problems during Cron runs.
In the "Advanced configuration" fieldset: we should now set Apache Solr Search as the default ("Enabled").
Search Index (before Cron has been run)
In the "Search index" tab, we can now see how many documents are in the index. Of course we don't have any yet. We can also see the number of items to be sent for indexing. Content is only indexed during Cron runs. So let's run Cron!
Search Index (before Cron has been run)
After Cron has run, we should see that there are no items left to send and that documents have been indexed. Please note: There is a delay time after adding new content before it is indexed. In this example, the delay is set to two minutes.
Search fields - "Field biases" fieldset
In the "Search fields" tab, we can specify index "weights" for different fields. Higher weight values for a field give it a greater importance in the search results (not to be confused with "weight" in the context of menus or taxonomies where a higher value makes an item appear lower, i.e. "sink").
Content bias settings
Under "Type biasing and exclusing", we can also apply weights to different content types or exclude a content type from the search index, altogether.
Congratulations! Apache Solr is now ready for use!
Some time back, I promised another short article in the WYSIWYG set-up series for Drupal 7, one which covers BUEditor. First, we should note that the BUEditor is not actually "WYSIWYG", but it offers some nice features which might make it a bit better than the WYSIWYG options, depending on your use case. It also does not integrate with the Wysiwyg module. You add it separately (and instead of Wysiwyg), but it does have some great supporting modules and code libraries. This article covers some of the basics about use and installation of the BUEditor on a Drupal 7 site (most of the information applies equally to Drupal 6, where the BUEditor module is also available). I've also got some good tips for some ways to extend the default button-set. (And you can download my modified button code here to easily import the buttons into a new editor profile.)
The BUEditor is now used on Drupal.org
Since the time I planned to write this post, BUEditor has surely got some additional attention; it's now what you'll use if you leave a comment on an issue or forum post on Drupal.org. It's refreshing to have more than just a plain text area for HTML entry; I think this is a great step for the Drupal community's official site. In addition to basic set-up of the BUEditor, as it's used on Drupal.org, I'd like to cover some nice features of the BUEditor which are not being used on Drupal.org.
The BUEditor integrates nicely with IMCE
The most recent article in this series covered the set-up of IMCE and supporting modules for inserting images. You'll be glad to know that the BUEditor supports adding images with IMCE. I'm sure you could also simply "attach" images and add them to content with the Insert module. The BUEditor's default image popup is very limited, which was at first a deal-breaker for me to suggest using it on this website, however I learned it's not so difficult to adjust the pop-up dialog to add more fields; by default it only has the URL, dimensions, and
alt text fields. I also wanted fields for
title text,
class, and
style (though it is probably best to avoid using inline styling, it's sometimes handy and nice to have a GUI for adding this to your tag when you create it).
Remaining downsides to the image dialogue
Proportional dimension calculations: It would be nice if there were support for automatic adjustment of the "Width" and "Height" fields to adjust one automatically (by ratio) if the other is modified. I tend to place images that are often wider than 600 pixels, which means they would not display nicely in the layout of this site. The Image Resize Filter automatically creates a smaller image, to be displayed in the content, if I adjust the size when placing the image. And it's easy to link the full-size original image to appear in either a Lightbox2 or Colorbox overlay. If I have an image which is 938 pixels wide by 529 pixels high, and I change
"Width" to 600 in the BUEditor image popup, I'd like a default option for the
"Height" to automatically be proportionally re-scaled, as it works in CKEditor and TinyMCE. It's not hard to calculate what the height should be, but I'd rather not have to, and I'm not the only one who would have to. The easy solution to this is to just leave the height field empty and the Image Resize Filter will still proportionally resize the image, but if the image doesn't load, for some reason, the page layout will be affected.
Longer fields: Even after working out how to add the new fields, I couldn't figure out how to make the whole dialogue larger (assuming physical display size is large enough) so that these fields could all be a bit wider. The default size of the text fields is pretty darn short, but my initial attempts to modify this just ended up breaking the whole editor. Well, it's not a big deal, but perhaps I'll figure out how to further customize the image pop-up. (If anyone knows how to make such modifications through simple button code (or an add-on module), please share your tips.)
Quibbles aside, the BUEditor really is awesome!
The BUEditor provides a nice, clean user interface with what could be a perfect balance between simplicity and usefulness, provided users are comfortable with working directly with HTML code. It's easy to apply formatting to selected text and it's also simple to modify the values of the editor buttons or add your own. Converting unstyled lines of text into lists (ordered or unordered), blockquote, or heading, is as simple as the click of a button and if anything gets mucked up, you have the code right there to adjust, but it's less likely to get messy than with a WYSIWYG editor since you have complete control over what you select before you click the button. This might be a good time to mention that there is also a Drupal-free version of the BUEditor, though the BUEditor was first created specially for Drupal, unlike so many of those other ("WYSIWYG") editors.
It's especially awesome with the Ajax Preview option enabled
The Ajax markup module, also written by the author of the BUEditor, allows you to simply modify the "Preview" button to provide a display which closely matches the end result (taking the text format settings into consideration). Awesome! I'd like to see them add this integration on Drupal.org, too, since it's much faster and nicer than reloading the page with the main "Preview" button. It would be great to also have this functionality in a Wysiwyg-integrated editor. Bear in mind, once you have this configured and working, clicking the "Preview" button displays the preview and by dragging on the handle at the bottom of the editor pane, you can see the corresponding code… but you won't be able to edit that code till you click the "Preview" button again.
BUEditor keyboard shortcut support
Not all browsers support the shortcuts equally, but when you are actively using the text editor, you should be able to use keyboard shortcuts to add tags, snippets you've configured, or perform other editor functions. In Safari, I found that I had to use the
control and
option keys in combination with the configured key. In Firefox it was just the
control key. More than one editor in a page can mess this up and the shortcuts may not work at all in some browsers, but they can certainly be useful. You can also remove the key codes if you think it might cause more problems for your users than it's worth.
Keep in mind: The button-set is based on role
One potential issue is that the editor button set is based on the user role, not on the Text format. So it's still easy to create content (as a privileged user) in the "Filtered HTML" format, and include images or other tags… that are then stripped on output. With Wysiwyg-integrated editors, the button sets are per text format. There are pros and cons to this, but I'd prefer to have a default editor configuration for each text format. There is a BUEditor Plus add-on module which aims to take care of this issue, but it's still in beta (actually still in the developer's "sandbox"). Since it's likely to be released soon as a full project, I won't link to the sandbox. Instead look for the module on HollyIT's user page on Drupal.org. Caveat: I can not confirm that the sandbox beta is ready for production use. Use or experiment at your own risk.
Another cool feature: BUEditor supports BBCode output
Many forums and sites support BBCode, which is easier for users to enter, a bit simpler than HTML, and removes many of the potential hazards of allowing users to enter HTML. If you want to have commenters post using BBCode, it's as simple as configuring the button-set for the included BBCode editor. The defaults might already be everything you need. Of course you'll also have to add and enable a BBCode text filter.
Are you ready to install and configure the BUEditor?
Add and activate the modules
You will want to download the appropriate modules. The BUEditor module is required, of course, and I also recommend the Ajax markup module. Add them both to your
sites/all/modules folder, then activate them, as usual. If you want to use IMCE, IMCE Mkdir, and/or the Image Resize Filter, be sure to add and activate them, too (see previous lesson about using IMCE with images in a Wysiwyg-integrated module and just follow the steps for configuring IMCE and the Image Resize Filter.)
Note: The BUEditor Plus module is also shown here, but may not yet be ready for production use. And, in case you were wondering, Internal links is a module I'm working on in my free time, so you see an "unversioned" copy in the screenshot from my D7 development installation. I will be committing some improvements to that in the near future.
Configure the BUEditor
Click the "Import editor" link to easily start from exported button code, like the modified button-set I've attached here. By the way, I've tested this button code in both BUEditor 6.x-2.x and 7.x versions. The same button definitions work in both.
To import a previously exported button-set, paste the code in the "Editor code" text area
You can create a new editor based on the Default profile (as I did originally) or you can import the code I've already modified to provide what might be a better starting point. Simply add a name for your new editor and paste the code from that file into the text area labeled "
Editor code (PHP)"
If you choose to start from the "Default" set, and want to enable Ajax preview, look for the "Preview" button in the "Buttons" rows and paste over the existing "Content" for that button with the following code:
js: E.prvAjax();
Note: This is already done in the attached version of the button-code.
Another change I made was to remove the "Heading1" selector from the default Headings button code. Why? A page should really only have one
<h1> tag, and it's already provided by the node's Title field, so except in unusual use cases, you'd never want to have this in your editor. That tag can be removed from the button very simply by dragging the "Content" text area for Headings open to see the full contents and selecting the second line for deletion. I also added a few new text buttons for
<br />, and
<?php tags; adding or customizing such tags is super-easy, especially if you simply add a plain text "Icon" to represent the button in the editor, as I did. If you want to add custom icons, you can supply the path to find your custom icons (e.g. a copy of the default icons, plus a few more that you create yourself; or you could replace the original icons with ones you like better. The original icons are all 20 pixels high, so match the height and your icons should look fine; for my paragraph and line-break buttons, a plain-text button suits me, but I've created a few alternate icons, included with the attached code.) If you choose to use alternate or extra icons, be sure to follow the directions included in the
readme.txt file within the BUEditor module's "icons" subfolder and copy all default and custom icons that you want to use to a new sub-directory under your
files path.
Additional simple toolbar configurations
You can drag rows up and down to adjust the order of icons in the BUEditor toolbar. You can also modify the keyboard shortcuts linked to the buttons and make other simple modifications before saving. I would suggest that you actually save periodically and make sure that everything is still working in the "Demo" text area, especially if you are editing button code or adding new buttons.
It's a good idea to periodically select all buttons and export your button set. To export all buttons, simply select the checkbox at the top right of the "Buttons" configuration table, which will select all checkboxes, then at the bottom of the list, select the "Export" action and click "Go". You can also use this action selector to remove buttons with the "Delete", copy selected buttons to another configuration of BUEditor, etc. If you don't do this, you might not notice when your custom code gets broken until you just have no icons showing up above the Demo textarea after clicking Save configuration. If you've got the buttons backed up, you can easily revert to a working set.
Assign the new editor(s) to suitable role(s)
Be sure to go back to the main BUEditor configuration page and select your new editor configuration to use for the appropriate roles. In this case, the "advanced" editor I set up for "Staff" needs to be assigned to all trusted roles who have access to "Full HTML". You may also want to assign an editor for basic "Anonymous" and "Authenticated" users. Untrusted roles should probably not be allowed to add images, headings or other special tags. The included "Commenter" editor configuration is likely appropriate for your "Filtered HTML" needs, but if you add any additional buttons to be used by roles who only have access to "Filtered HTML", be sure to make corresponding changes to the "Allowed HTML tags" in your "Text formats" configuration:
As mentioned before, you could also configure the BBCode editor or set up an editor for other special markup languages. Exploring these use cases is outside the scope of this article.
More advanced configuration
You can do a lot more with the BUEditor… this article might be a bit long, but the official documentation is even longer. There are loads of API functions for doing really cool stuff with BUEditor buttons; and don't overlook all the pages of contributed button code. Before you spend a lot of time trying to figure out how to implement a particular button for your needs, take a look at what's already tested and available; even if you don't want the exact functionality offered by a contributed button, it may offer an example you can more easily adapt to achieve your particular needs.
Some of my favorite contributed buttons include the:
- Special Characters button, which provides a nice pop-up panel for just about any "special character" a user might want to insert
- Text Color button, which provides a pop-up selector with color swatches which can be applied to text or backgrounds
- Class Attribute Library; allows easy addition of a particular class to selected HTML
- Smileys Button, which provides reasonable integration with the Smileys module (unfortunately not yet officially available for Drupal 7, though it does look like the port is reasonably complete.)
- Remove Formatting button (perhaps less risky than the one I created since it only strips designated tags, so won't remove everything inside of IMG tags or between the php tagset used for longer blocks of syntax-highlighted code.)
- BUEditor Imagecache button (similar to the standard insert image button, but also allows selection of a pre-set image style)
- BUEditor Quick Table (okay, HTML tables are worth avoiding, but sometimes data content really is best displayed in a table; this makes it easy)
Good luck and have fun…
We wish you every success configuring your Drupal site for maximum productivity and a user experience to write home about. The BUEditor might not be for everyone or every use case, but its light-weight code-base is amazingly efficient and with the proper configuration it can be better than a WYSIWYG editor for offering a friendly way to add and edit content. If you come up with some interesting things to do with it or have comments about this article, or any of our others, we look forward to hearing from you. Please feel free to leave a comment, below.
Thank you for visiting us on the Cocomore Drupal blog.
This article covers the configuration and use of IMCE (and related modules) to integrate uploading and inserting images within your Drupal content. We assume you are using either TinyMCE or CKEditor with the Wysiwyg integration module, but in a separate post we will cover using IMCE with the BUEditor, a simpler text editor which also works well with Drupal. Note: This article uses Drupal 7, but most of the tips should also be helpful if you are configuring a Drupal 6 site for the same functionality. Indeed, this site is still running on Drupal 6 and also uses a Wysiwyg-integrated CKEditor, IMCE, the Image resize filter, and Lightbox2.
Add necessary modules to sites/all/modules
If you've been following along, you've already added the IMCE and IMCE-Wysiwyg Bridge modules; otherwise this is the first step you'll want to take. In addition to these required modules, this post also covers using the Image Resize Filter and Lightbox2 modules, which work together with IMCE and Wysiwyg to allow you to automatically create smaller images embedded in your content, which are linked to the full-size images and can optionally be viewed in a Lightbox overlay. This is very cool, especially if your original images are wider than the content area and you wish to give users a closer look without actually opening a new window for the image or forcing the user to click the back arrow to return from a linked image to your Drupal content. The IMCE Mkdir module allows you to add directories to your file hierarchy so that you can keep uploaded media nicely sorted.
Activate the modules you've added
You'll find the Image Resize Filter in the "Input filters" fieldset. IMCE and IMCE Mkdir should be in the "Media" fieldset. And the IMCE-Wysiwyg Bridge and Lightbox2 modules are activated in the "User interface" fieldset. Click on the "Save configuration" button and you're ready to move on. Note: Using Drush to add and activate modules is outside the scope of this article, but is a nice time-saving trick.
Configure IMCE
After saving your configuration, you can go through and click on the "Configure" links beside the modules which have additional configuration. If you only intend to allow your "User-1" (initial admin account) to upload and insert images into content, then the defaults for IMCE might already be suitable. But assuming you have other roles who you trust enough, you'll probably want to adjust the default configuration and permissions.
Start by taking a look at the IMCE configuration for your "User-1" profile (we have made no changes to this profile, so will not display a screenshot, but if you don't have IMCE installed yet, you can see a screenshot of this configuration here).
For the sake of this example use case, we have created additional "staff" roles for "Editor" and "Author" users, who will be allowed to use the "Full HTML" text format (or a custom text format which allows image uploads) and will be allowed to upload images using IMCE and perform various levels of file administration. Our standard anonymous and authenticated users will not be allowed to use a text format with
<img> tags at all, so we will not need corresponding IMCE profiles (allowing untrusted users to use
<img> tags is a potential security issue which is best avoided; using BBCode or Markdown for these roles can help mitigate the risk if you really want to allow new users to display images on your site — but further discussion of this matter should be considered outside the scope of this article). If you do add new roles, be sure to give them appropriate permissions. For this use case, we've given our Author and Editor roles permission to "Use the Full HTML text format" and permissions to create and edit various content types. (
Add a new IMCE profile
You will probably wish to add a new profile for any new roles. For my simple use case, I will create one "Staff" profile which will have almost the same defaults as the "User-1" profile. We can save time by clicking the "Import settings from other profiles:" link labeled "User-1" and then tweaking the profile a bit more. We might want to cap the directory quota a bit, but not nearly as much as the 2MB, which is the default for a new profile. We also want to allow our staff to create directories in the main files area rather than within a subdirectory with their user-ID. Be sure your settings are a good fit to your use case.
Make your Role-Profile assignments
Assign the "Staff" profile to appropriate roles and make sure the "weight" of each role has them in correct order of their importance (descending order). We aren't going to allow authenticated or anonymous users to upload images, so we won't assign any profile to them.
Make sure applicable Wysiwyg profiles include IMCE in "Buttons and plugins"
Assuming you have followed the steps in the previous article in this series, you have already configured Wysiwyg profiles for your editor(s) of choice. The IMCE-Wysiwyg Bridge module which you've activated in this lesson adds another checkbox (to at least some of the editors which you can integrate via Wysiwyg, e.g. CKEditor and TinyMCE), labeled IMCE, which you'll probably see down in the bottom row of your "Buttons and plugins" section for each applicable profile. Check the IMCE box and the "Image" (and "Advanced image" for more features in TinyMCE) checkboxes. The IMCE checkbox does not actually add a button to the editor's menu bar (you just see the normal image button). The pop-up box for adding images should now include a link to "Browse server".
Configure the Image resize filter module and Lightbox for your text formats
The only settings for the Image resize filter are found in Text formats. It is a filter which you can turn on and configure individually for each text format. What we want is to configure the Image resize filter to link a resized image to the original and display the full-sized original image in a Lightbox overlay. In my simple use case, I'm giving all "staff" roles access to Full HTML; you may wish to create and configure an additional text format, e.g. one somewhat more restrictive. We need to make sure the Lightbox filter is active, as well as the Image resize filter. I have had good success with the Filter processing order displayed (with the Image resize filter running before the Lightbox filter). Note: There are several other Lightbox-related filters available if you want to use Lightbox for other special purposes (e.g. video, slideshows, etc), but for the basic needs of our use case, we only need the "Lightbox filter".
When the Image resize filter is active, there is a tab at the bottom of the Text format configuration screen to adjust its settings. Click on that tab and at least select the option to resize locally stored images. Check the box next to "If resized, add a link to the original image." We can see, from looking at the help text for the Lightbox filter that "Image links with
rel="lightbox" in the
<a> tag will appear in a Lightbox when clicked on." So we put if we put "
lightbox" in the text field for adding a
rel attribute, everything should work correctly. Note: The JavaScript degrades gracefully — even if JavaScript is unavailable or inactive, the link will still work; it just won't open the full-size image in a Lightbox overlay, but in the current window.
There are additional settings available for Lightbox2
Assuming you only want Lightbox for the purpose of giving visitors a better look at images resized and embedded in your content, the default settings should suffice. Lightbox will even add captions to images if you add a
title attribute to the images. This is default behavior. But if you want to use Lightbox to view galleries of images (e.g. a group of images attached to a node), adjust settings for displaying video content in a Lightbox, prevent Lightbox from being active on certain pages or sections of your site, or want to configure Lightbox for Flickr content, Gallery2, Image assist, or other possible integrations, there are some settings you may wish to adjust. Note: there are four tabs at the top of the Lightbox configuration page, so in addition to all the settings hiding in the individual collapsed fieldsets on the "General" tab, there are dozens more settings there for you to tweak. Digging into everything you can do with Lightbox2 is well outside the scope of this article, but may be covered at a later time.
You are now ready to start uploading and inserting images
There are a few steps to the process of adding an image into your content:
Click on the Image button in your editor…
Be sure your cursor is at the beginning of the paragraph where you want your image to appear (especially if you want text to flow around your image). The "Insert/edit image" button is similar in both TinyMCE and CKEditor:
Click on the "Browse server" button…
You should get a pop-up window for inserting an image, which should look something like this. Note: This illustration shows the basic Image popup option for TinyMCE, further below we also show what the popup looks like if you've selected the "Advanced image" option in TinyMCE (recommended, if using TinyMCE) or if you are using CKEditor (similar to TinyMCE with the "Advanced image" plugin option.)
Click on the "Upload" button in the IMCE window…
In addition to the "Upload" button, which pops up a "browse" window to files on your local operating system, this window is where you can create a directory structure for your files. You may want to create directories for your content types and/or for individual nodes, if each article has many images. If you've set permissions in your IMCE profile for non-admin users (e.g. the "Staff" profile we created) to upload, create, and/or delete directories, you will see the corresponding buttons in this window. Note that if you use IMCE's "Resize" function, this will create a resized version of your file as the "original" passed to your editor, which would be viewed in your Lightbox overlay. I do not usually use the "Resize" or "Crop" buttons in the IMCE window. Resizing an image, especially one in a stored in a file-type with "lossy" compression, e.g. JPEG, is best done as few times as possible, so we should preferably only upload files which are already cropped and sized the way we wish them to appear in the Lightbox overlay. That said, there may still be times when these functions are useful.
Click on the "Insert file" button…
After you select a file to upload (you can upload several and then just select them from your server directory as you insert them), click on the "Insert file" button.
Adjust options in your editor's Image popup window
Selecting left or right alignment translates into inline CSS styling:
style="float: left; ", for example. This is a good time to talk about some of the differences between the image popup panels provided by TinyMCE and CKEditor. The "Advanced image" plugin for TinyMCE provides a field for "class", which can be a better way of styling image placement since the class can also include padding or margin settings, etc. It also allows you to resize an image, automatically adjusting the second dimension (width or height) to keep the same ratio, and provides a field for the image title, which is used by Lightbox2 to provide a caption below the image. To get the advanced options, select both the "Image" and "Advanced image" options when configuring "Buttons and plugins" for the applicable Wysiwyg text format(s). Be sure to enter something useful in the "Image description" field; this will be your
alt text; it is displayed if the image does not load or if a visitor is using assistive technologies (i.e.
alt tags are required for better accessibility);
alt tags are also required if you want pages to pass HTML validation on W3C and are useful for providing search engines more information about an image (so are good for SEO). In CKEditor, the standard "Image" button yields a popup with all the features of the "Advanced image" version in TinyMCE. The fields and buttons are labeled somewhat differently, but each has three tabs which include fields which provide basically the same end result.
These are the most important two tabs in the TinyMCE Image popup
The "General" tab in TinyMCE's "Advanced image" popup includes both "Image description" (alt) and "Title" fields. The popup also has a tab for "Appearance", where you can set alignment (i.e. "float" left or right), dimensions, and other styling.
The corresponding tabs and fields provided by CKEditor…
In CKEditor, the "Image Info" tab provides your basic
alt text and size options, as well as the "Alignment" for "floating" an image left or right in your content. The "Advanced" tab provides a field for the HTML
title attribute (labeled "Advisory title") and allows you to tweak the inline CSS styling.
Resized images appear in the Lightbox overlay when clicked
And this is what your Lightbox overlay will look like (if you adjust the width and/or height in the editor's popup window or in the HTML source code, the original is displayed in the Lightbox overlay when you click on the resized version).
In Drupal, there are actually a number of ways to add a WYSIWYG editor to a text area. The new "Drupal way", used on over 150,000 Drupal sites and arguably not so "new" anymore, is to use the Wysiwyg integration module, which has support for several of the editor libraries. I would personally suggest using it, if your needs can be met by it, since it's becoming more and more powerful and offers a fair bit of flexibility to easily change the configuration or editor used. That said, there may still be reason, in Drupal 7, to use one of the single-library integration modules, such as the still-popular CKEditor project. The TinyMCE integration module development has already been abandoned in favor of Wysiwyg, but it's good to have alternatives. Note: In this post, we assume you already know your way around Text formats. Text format configuration can be one of the most tricky parts of properly setting up your WYSIWYG experience, so if you don't already feel you know your way around this common stumbling block, be sure to read our recent post about Text formats / Text filters, too. This article is a companion-post to that one, but it also includes some degree of overlap, since when we turn on the Lightbox and Image Resize Filter modules, we have new filters we'll want to use in some text formats and we will want to pay attention to the order in which they are applied, so we will briefly revisit this topic here.
If you happen to like the more "minimalist" editors, and your site's users won't be freaked out by having to see actual HTML code, you may wish to consider using BUEditor instead of any of those which integrate with Wysiwyg. We will cover using it in another post, since I've personally been convinced that it's maybe even more awesome than a "WYSIWYG" editor. This post will simply cover setting up TinyMCE or CKEditor with the Wysiwyg integration module.
First we'll add and activate the Wysiwyg module
Please start by downloading the latest stable release of the Wysiwyg module. Contributed modules like this are usually added to the
sites/all/modules directory. It's activated on the Drupal
admin/modules page in the "User interface" fieldset, which you should see near the bottom of the page. Since it's common to want images within posted content, we are also going to demonstrate using IMCE and the IMCE-Wysiwyg Bridge to upload and insert images and we'll also add Lightbox2 and the Image resize filter module for improved display of images. You can add all four of these image-related modules to your
sites/all/modules directory and also activate them at
admin/modules. This blog post will not delve deeply into configuring images or associated modules — this can be a rather complicated topic, so it should also be covered in a separate post. So, while we'll be integrating IMCE and Lightbox2 for display of embedded images in this tutorial post, the full configuration of these modules will be covered separately.
Add editor library(ies) to your sites/all/libraries directory
If you aren't already sure that you want to use TinyMCE or CKEditor, it's a good idea to take a little time to experiment with at least some of the different alternatives to determine which you like the best for your use case. CKEditor and TinyMCE are the two editors which integrate best with the Wysiwyg module and IMCE (to allow uploading and adding images to text areas). You could try some of the others, but bear in mind that, at least at this stage, many of the editors are not very fully supported by the Wysiwyg integration and may not have support for the full button sets available, nor for integrated image upload, etc.
Editor libraries are added to Drupal by extracting their code files and putting them in the
sites/all/libraries directory, which you should create if it doesn't already exist. In a few odd cases you may need to rename a directory or add/remove a level of hierarchy, so it's best to read the installation directions on the Wysiwyg profile page, which you'll find at the bottom in a collapsed field-set. Click it open and find the directions that apply to your editor of choice. For TinyMCE or CKEditor, you should be able to simply download the latest stable version of the Javascript libraries for the editor and extract the archive (.zip file) into the
sites/all/libraries directory, as per the directions:
One of my long-time personal favorite editors for embedding in browsers is the Markitup editor. It's simple, light-weight, and technically is not truly "Wysiwyg", but it offers some nice features you won't normally see in the really fancy-looking editors. If your target audience could be described as "HTML-savvy" (or BB-Code-savvy / Markdown-savvy, etc), they may prefer such an editor since they always have access both to editor buttons and to a view of the generated code. And where other editors may add a dozen lines of in-line CSS styling when you paste text from a styled document, Markitup will only copy the text, not the styling. Even better, you can wrap a tag-set around selected text with just a simple keyboard shortcut.
What the Markitup editor normally looks like
As you can see it offers most tags you'd want for any HTML content and you'd only need to hand-code a few tags, here and there. You can experiment with this configuration on the Markitup "examples" page.
This is Markitup integrated by Drupal 7's latest version of the Wysiwyg module
And that's with ALL available buttons selected… so Wysiwyg integration supports only a fraction of Markitup's standard Filtered HTML button set. Most disappointing! Well, having read up on the topic, I believe that it's just some work, currently, to integrate each button, so some editors that many people use are much better supported while others may still be more of a "development stub" example that the community can build on. It may just be that those of us interested in Markitup will have to help complete its integration with Wysiwyg (or help complete the port of the Markitup module to Drupal 7). But the search for a better "non-WYSIWYG" editor (text editor) did lead me to the BUEditor, a nice alternative which can be used with Drupal 7.
The safest solution is to use one editor
It's probably best to adopt just one editor for all text formats. Otherwise if you have privileged users with access to more than one format, that will mean two different libraries of Javascript code are added to the text areas and you can start to run into weird conflicts… like no editor showing up for a text format which is assigned to an editor… or no ability to properly switch between "rich text" and "code" views. It also means a lot more Javascript is added to each page, so it can delay initial page loads. So we strongly suggest choosing one editor which is sufficient for all your needs. To my knowledge, since only TinyMCE and CKEditor are supported by the IMCE-Wysiwyg bridge (which you may want if you'd like to add images to posts), it might be worth trying out both, before selecting one. From this point on, in this article, we are assuming you have settled on TinyMCE (or CKEditor), so some steps will include tips or screenshots which apply only to TinyMCE (but CKEditor is very similar in terms of the configuration).
We'll start by configuring the Filtered HTML button-set
First we need to select an editor to use for "Filtered HTML". Select "TinyMCE" (or CKEditor, or whatever) from the select list for "Editor" and then click "Save".
But wait… you still have to select the buttons
If we stopped now, we would only have an empty editor, one with no buttons — which would be much like no editor at all. Don't make the mistake of stopping now and thinking the defaults are probably good enough. Unfortunately, they aren't. Be sure to click on the "Edit" link which is now active for Filtered HTML and TinyMCE in the "Operations" column.
Select appropriate buttons when configuring your editor for a "filtered" text format
Just select buttons which will be useful and appropriate for the limits of the text format. In this image, you can see what should be an appropriate selection of buttons for a Filtered HTML text format. I would be sure to add the
<p>, and to be safe, both
<br> and
<br /> tags to the allowed list of tags for your Filtered HTML text format. (See related article for more info about configuring text formats). Why? Now you can turn off the "turn line breaks into HTML" filter (which turns double line-breaks into
<p> tags and single ones into
<br />). You will probably find that any WYSIWYG editor is going to add those tags, anyway. And people will try to add them (in code view) and be annoyed by having them stripped out on output. Plus, you'll probably find that your code gets re-formatted, no matter what settings you use in configuring the editor.
Tweak the settings for "Cleanup and Output" (optional)
I personally can normally accept all the other default settings, but change the Cleanup and Output settings, as shown. Verify HTML should be good, but I don't like the editor to add lots of styling when people paste. Let's try to keep that in the CSS files. I also don't like all the linebreaks removed, since I tend to look at the code, and I'm sure many others are like me and will also want to see or adjust the code. Assuming you don't have the "convert line breaks to HTML" turned on (you shouldn't if using a WYSIWYG editor), it's safe to leave "Apply source formatting" on. It will give you some appropriate line breaks (hopefully) so that it's easier to read through the code. The "Force cleanup on standard paste" option helps clear out some of the garbage that people might attempt to paste in. I've seen no reason to disable that feature.
Now your editor should look something like this
Provided you are configuring TinyMCE and selected the same buttons I did, your editor should look something like this, at least to your regular users who probably will only have a limited set of HTML tags they are using.
Make sure selected buttons correspond to allowed tags
To make sure that your editor and corresponding text formats are properly configured, you should test the different buttons and pay attention to the preview. Here, we can see that the
<strike> tag is not allowed by the current format (Filtered HTML) and should be added to the list of allowed tags for Filtered HTML if we want to have that button available for use*. Nothing is much more confusing and annoying to users than when they add the proper code, can see it in the code view, but don't see the same result in the saved output. Look at what tags are output by the editor (for each button used) and either disable the button or add the corresponding tag to the text format's allowed tags. Use the node preview button (at the bottom of the page, next to the "Save" button) to check [*Note: Actually, in the current TinyMCE, the "strikethrough" text treatment is accomplished by wrapping text in
<span> tags with a style attribute which achieves the same effect. In the current version of CKEditor, it's
<strike> tags. In other editors, you may find the "same" button adds
<del> tags. All three achieve the same effect and if you want to include the strike-through button, you may wish to add more than one of these tags to those allowed for your text format.]
Don't enable the "preview" button
There is a common issue across various editors integrated by Wysiwyg. If the editor provides a "preview" button, and most do, the preview will render any HTML, regardless of tag limitations imposed by the current text format. For example, this means that images and
<strike> tags used for strikethrough text will work as expected in a preview, but since the tags are not part of the default "Filtered HTML" text format, the
<strike> or
<img> tags will actually be removed on output instead of displaying an image or the text between the
<strike> tags with "strikethrough" styling. You can still preview by clicking on the "Preview" node button, before saving, but the "preview" provided by the editor can be misleading. Hopefully future development of the Wysiwyg module might implement something like Ajax markup, which integrates with BUEditor (but not with the Wysiwyg module) to display text with correct output, i.e., according to active text format filter settings, etc.
Repeat for other text formats, but keep it simple
It should be easier to set up your editor for Full HTML. You may also wish to create a filtered html text format for trusted users, e.g. a "Filtered+" HTML. Just follow the same steps. Add a few more tags to the allowed set (perhaps you trust these users to add images or sub-headings). My only advice is to follow the KISS principle and "keep it super simple". It's easy to get carried away and add all buttons available for Full HTML. Resist the urge. You are more likely to run into bugs and you'll end up with an overwhelming user experience. I'd suggest keeping the button-set limited to the most useful tags.
This is what the button-set looks like if you select them all:
My recommendation would be to add just a few more buttons to the set you created for Filtered HTML. If you want users to be able to simply add images within their text and you've turned on the IMCE module, be sure to select both the Image and IMCE checkboxes. Working with images and IMCE is complex enough that we'll cover that in the next post.
Make sure the text filters for the format make sense and are in logical order
Now you should check your filters. Make sure the appropriate filters are enabled and that text is processed by the filters in a reasonable order. The Filtered HTML Text format normally includes the "convert line breaks to HTML" filter, which doesn't make sense if you are using a WYSIWYG editor (just be sure to include the
<p> and
<br /> /
<br> tags in your allowed set). For Full HTML or other text formats with images, you'll probably want to include other filters, such as the Image Resize Filter and/or Lightbox. Again, we'll cover image-related tips in the next post.
Congratulations, you now have a killer WYSIWYG editor configured!
Be sure to test that everything works the way you want it to. Be sure to test that all of your user roles have the expected access to the editors and text formats and that features are working as expected. If you are working on a local development environment, it can be helpful to turn on the Devel module's "switch users" block and give all user roles permissions to use it. This will allow you to easily switch between a user of one role and your user-1 admin to tweak permissions or other configuration.
Be sure to check back for our next post about working with images in a WYSIWYG editor, which should be posted in the next few days.
Sometimes, when troubleshooting a Drupal issue on a site, it's best to determine how much time you are willing to spend on fully solving an issue and be willing to accept a reasonable compromise. We encountered such a situation recently with a rather odd issue: If an authenticated user attempted to post a comment on any of the German blog posts here, they were unable to complete the operation since the "save" button was missing ("preview before save" was required) and for some odd reason, "preview" was not working for admin or other authenticated user roles. If logged out, there was no problem. Actually, it took a while to determine it was the preview, itself, that's not working. We also determined that this may be a bit obscure and could take time to troubleshoot and be better put on the "back burner" for now.
If you want to post a comment, please log out and then try again...
The issue was that we had comment settings on blog post configured to "preview required". It worked fine on English posts, but on German posts, the "preview" would never appear, so neither would the "Speichern" ("Save") button ever be available. Oddly, this issue was only seen on German posts, and also only seemed to affect authenticated users. If a user was not logged in (was seen as an "anonymous user"), they would get the preview and then be able to save their comment.
The simple interim solution: Make 'Preview Comment' Optional...
Preview was set to 'Required' in the Comment settings for the content type, "Blog Entry". Since it wasn't immediately apparent what was interfering with the preview functionality for authenticated users posting comments on the German blog posts, when the issue came to my attention, I immediately set this configuration to "Optional", which meant that while the "Preview" button still doesn't work for authenticated users posting comments on German blog posts, they can at least save their comment without logging out and making their comment as "anonymous". This was a workable interim solution which I had time to implement.
Troubleshooting... trying different things to determine a pattern...
During troubleshooting of this issue, I noticed that an older "localhost" (development) installation of the site worked as expected, even though it also included the language switching by domain and almost entirely the same configuration. What was different? Well, my older localhost was not up-to-date and had a slightly outdated version of the Cocomore Drupal Core. It also had a new version of Captcha (there is a hidden Captcha on the comment form). I wondered, first, whether the Captcha module could be involved, so I turned off Captcha for the comment form and found the problem persisted. Admin and other authenticated users still could not get a 'preview' of a comment posted on a German blog post.
After restoring Captcha for the comment form, I decided to check whether authenticated users (with rights to create a blog entry) could preview a German blog entry node. I determined that preview worked, on both the localhost and production sites when creating German or English blog entry content. So the issue really is limited to comments. I also tried changing the input format for the comment (as "admin" I could select "full HTML" instead of our "blog HTML" input format). But the admin user could still not see a preview.
Wondering whether this affected other content types, I tried responding to a forum post in the German section, where "preview required" also seems to be set. The preview worked as normal. So far, this issue only seems to affect previews of comments on blog entries.
There are more things I could do to troubleshoot an issue like this, but it takes time and simply not having a functional preview of comments, while not ideal, is also not worth wasting a lot of time on, if none of the "obvious" troubleshooting steps yields more useful information. For now we will just have no "preview" of comments added to German blog posts, at least for authenticated users. This is ameliorated by the fact that the authenticated users can edit their comments, so can use "save" (and then "edit") in place of preview if they notice any real need to fix something.
Has anyone else seen something like this?
Any ideas? If you have experienced a similar issue and you did happen to track down the cause, please comment here. In the meantime, I'll simply be paying attention this issue and see if it clears up "on its own" (e.g. after another core update or something) and/or keep my eyes open for possible causes or solutions. You can't always justify spending a lot of time getting one small feature of a site "perfect", especially if the "client" is yourself, but these things can be puzzling till the cause is identified.
In any case, I trust I'll know what's going on before too long, but won't give high priority to solving this issue, at least not for now. Sometimes it's best to just keep such issues in the list of "things which need an explanation". There are plenty of other things which are higher on my current "to do" list. At some point, I'll have other reasons to get my development version of this site back in complete sync with the production server and maybe, then, I'll be able to replicate this problem on my local machine, and do things to troubleshoot it that I'd rather not do a on production server. Until then, this is a just a bizarre quirk of our production environment. I'll post an update when the mystery is solved.
Although CCK automatically does some basic validation on your fields that you add to your Drupal content types, there are some cases where you'd like to do some additional validation for your site. One use case that I ran into recently was a basic text field that was being used to house hyperlinks for one of my websites. The text field had already been in place and working perfectly for months. Rather than do something drastic like replacing the field altogether with a field provided by the "Link" module, I decided to do a hook_form_alter to add in my own custom validation function.
Basically you just create a custom module for your site called "form_alterations" or whatever you like. Here's the code for adding in this sort of functionality:
* Implementation of hook_form_alter().
function form_alterations_form_alter(&$form, &$form_state, $form_id) {
switch ($form_id) {
case 'announcement_node_form':
// Simply add an additional link validate handler.
$first = array_shift($form['#validate']);
array_unshift($form['#validate'], $first, 'form_alterations_link_validate');
* FAPI #validate handler. Make sure the hyperlink they used is correctly formatted.
function form_alterations_link_validate($form, &$form_state) {
if (!empty($form_state['values']['field_web_address'][0]['value']) && !strstr($form_state['values']['field_web_address'][0]['value'], 'http://')) {
form_set_error('field_web_address', t('Please enter a full web address starting with "http://".'));
hook_form_alter allows you to use the Drupal Form API to make changes to existing forms. In the code above, I'm adding in a call to my custom function called "form_alterations_link_validate" after the basic CCK validation takes place. Then, within the function itself, I check to make sure that the user entered a value and that it contains "http://" at the beginning of what was entered. If you use the code above, please just be sure to change the line with "case 'announcement_node_form':" so that it modifies the form for your node type. My node type was called "announcement".
I was recently trying to figure out exactly how long my users' sessions were lasting on an existing Drupal site that I had built. Generally it seemed like users were remaining logged in for an extremely lengthy period of time. I did some research and finally discovered that this setting is actually configured in the default settings.php file that ships with Drupal. There's a line in the settings file that initially reads:
ini_set('session.cookie_lifetime', 2000000);
Basically this means that, by default, when a user is logged into the site, they will receive a cookie from the server that won't expire until two million seconds have passed (that's just over 23 days). I'm not sure quite why the default setting is for 23 days. Maybe for development sites this would be a good idea so that your developers don't have to log in all the time, but for most of my production sites, I actually prefer that the user only be logged in for a maximum of about 10 hours at a time. To change the setting to a more reasonable ten hours, you would use:
ini_set('session.cookie_lifetime', 36000);
Also, if you want the user to be logged out as soon as the browser is closed, you can change the setting to:
ini_set('session.cookie_lifetime', 0);
DrupalCon Copenhagen comes to an end, as does my blogging hiatus.
Two of my primary learning objectives here in Copenhagen were configuration management and deployment process. Historically, working with Drupal in these areas has been unpleasant, and I think that's why there is tons of innovation going on in that space right now. It needs to be fixed, and new companies are springing up to say "hey, we fixed it." Often, the people running the companies are the same people running the project that encapsulates the underlying technologies. I'm referring to:
- The hyper-performant core distro, Pressflow
- Distros with sophisticated install profiles, like OpenAtrium, ManagingNews and OpenPublish
- Configuration externalization with Features
- Development Seed's "for every site, a makefile" workflow using drush make
- The different-yet-overlapping hosting platforms Pantheon and Aegir
Dries commented in his keynote that as Drupal continues to grow, it also needs to grow up. I think advances like these are part of the community's answer to that. I want to wrap my head around some of these tools, while continuing to watch how they progress. Others, I want to implement right now. What's perfectly clear though is that I have a lot of work to do to keep up with the innovation going on in this hugely powerful community. Which is actually nothing new, but reading a blog post about these technologies doesn't make my jaw drop the way that it does when I'm in the room watching Drupal advance.
This article describes how to install the Drupal 6.2 CMS on MySQL 6.0, using the Falcon Storage Engine. The operating system is a default Ubuntu 8.04 "Hardy Heron" (x86) installation.
I will make a few assumptions here, in order to keep the instructions simple: a fresh OS install, no other MySQL databases or web services are running or have already been installed. Both MySQL and the web server are installed on the same host. You should be able to become root to install packages and to have access to the local file system and the system configuration.
This article will explain how to install and configure Apache/PHP, MySQL 6.0 and Drupal 6.2.
Running Drupal requires a web server (e.g. Apache) and PHP. We will use the packages as shipped with the distribution and will then install a MySQL 6.0 preview binary from http://dev.mysql.com. Other web servers like lighttpd will work equally well, but this article focuses on using the Apache web server.
Fortunately the MySQL 5.0 client applications as shipped with Ubuntu Linux are compatible with the MySQL 6.0.x client/server protocol, so we only make use of the 6.0 server and will use the installed, pre-compiled client applications and libraries to connect to it - there is no need to recompile PHP or anything to get going!
First of all you have to make sure the following packages have been installed (e.g. by using a package management tool like the Adept Package Manager, synaptic, aptitude or apt-get):
- apache2
- libapache2-mod-php5
- php5
- php5-common
- php5-mysql
- php5-gd
- mysql-client-5.0
To enable the mod_rewrite Apache module (as recommended for Drupal), you need to enter the directory /etc/apache2/mods-enabled and create a symlink to the module loading instructions:
cd /etc/apache2/mods-enabled/
sudo ln -s ../mods-available/rewrite.load .
This will ensure, that mod_rewrite will be loaded when Apache starts up.
Additionally, you have to edit the file /etc/apache2/sites-available/default and make one change. In the directives for the Directory /var/www, change AllowOverride from "None" to "All". This will make sure that Drupal can enable the rewrite engine to allow nicer looking URLs.
Now restart the Apache server to apply the changes:
sudo /etc/init.d/apache2 restart
To verify that Apache is up and running, try opening http://localhost/ in a browser on the same machine that runs the web server. You should get a simple page, stating that "It works!".
Installing the MySQL 6.0 Falcon preview
Now that the web server is up and running, we need to install a MySQL database server that the Drupal installation can use. Download mysql-6.0.5-alpha-pb87-linux-x86.tar.gz (or any newer package, if available) from http://downloads.mysql.com/forge/falcon_feature_preview/
Create a /etc/mysql/my.cnf file with the following content (replacing the existing file, if necessary):
The default-storage-engine option will make sure that every CREATE TABLE statement will default to using the Falcon storage engine. Now extract the binary tarball distribution into /usr/local and perform the following steps to finalize the installation/configuration:
$ sudo groupadd mysql
$ sudo useradd -g mysql mysql
$ cd /usr/local
$ sudo tar zxvf ~/mysql-6.0.5-alpha-pb87-linux-x86.tar.gz -C /usr/local
$ cd /usr/local
$ sudo ln -s mysql-6.0.5-alpha-pb87-linux-x86 mysql
$ cd mysql
$ sudo chown -R mysql .
$ chgrp -R mysql .
$ scripts/mysql_install_db --user=mysql
$ sudo chown -R root .
$ sudo chown -R mysql data
$ sudo ./bin/mysqld_safe --user=mysql &
The installation procedure is outlined in more detail in the reference manual at http://dev.mysql.com/doc/refman/6.0/en/installing-binary.html
If you want to enable the automatic startup of MySQL at system bootup time, you need to install an init script in /etc/init.d/ - follow the instructions as outlined in the reference manual. Note that the mysql.server script has been moved from the directory support-files to share/mysql for the binary tarball distributions and that the current 6.0 documentation has not been updated yet (I filed BUG#36382 about this).
Now start the server using the mysqld_safe script:
$ sudo /usr/local/mysql/bin/mysqld_safe &
Next you should verify that you can connect to the server and that the Falcon storage engine is enabled:
$ mysqladmin version
mysqladmin Ver 8.41 Distrib 5.0.51a, for debian-linux-gnu on i486
Copyright (C) 2000-2006 MySQL AB
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license
Server version 6.0.5-alpha-pb87
Protocol version 10
Connection Localhost via UNIX socket
UNIX socket /var/run/mysqld/mysqld.sock
Uptime: 43 min 6 sec
Threads: 1 Questions: 6 Slow queries: 0 Opens: 15 Flush tables: 1 Open tables: 8 Queries per second avg: 0.2
$ mysql -u root
[email protected]:(none) > SELECT * FROM information_schema.engines WHERE engine='Falcon';
| Falcon | DEFAULT | Falcon storage engine | YES | NO | YES |
1 row in set (0.12 sec)
Before performing the actual Drupal installation, you need to create a Drupal Database and a user account. I chose "drupal" as the user name and password, please use some more sensitive values for your own setup!
[email protected]:(none) > CREATE DATABASE drupal;
Query OK, 1 row affected (0.01 sec)
[email protected]:(none) > GRANT ALL ON drupal.* to 'drupal'@'localhost' IDENTIFIED BY 'drupal';
Query OK, 0 row affected (0.00 sec)
Now MySQL 6.0 is installed and ready!
Installing Drupal 6.2
Now that the web and database server have been set up and configured, it's time to perform the installation of our application, the Drupal content management system. Start by downloading drupal-6.2.tar.gz from http://drupal.org/ (by clicking on the Drupal 6.2 download link on the front page).
Remove the default start page /var/www/index.html and extract the content of the drupal tarball into this directory. Then change the ownerships of these files to the user that apache runs under (www-data by default):
$ sudo rm /var/www/index.html
$ sudo tar --strip-components=1 -zxvf drupal-6.2.tar.gz -C /var/www
$ sudo chown -R www-data /var/www
The Drupal package installation itself is now done, the remaining installation and configuration steps are performed in a browser by opening http://localhost/ in your browser (reload the page if you still see the "It works" default page).
Follow the instructions in the Drupal installation manual on how to perform the actual installation. In the "Database Configuration" dialogue, use the MySQL database username and password that you created earlier.
Now the Drupal installer should perform its duty and you should see you fresh Drupal installation up and running!
Once the installation has finished, let's verify that we're really running on Falcon by running the following query in a MySQL command line client:
mysql> SELECT TABLE_NAME, ENGINE from information_schema.tables WHERE TABLE_SCHEMA='drupal';
| access | Falcon |
| actions | Falcon |
| actions_aid | Falcon |
| authmap | Falcon |
| batch | Falcon |
| blocks | Falcon |
| blocks_roles | Falcon |
| boxes | Falcon |
| cache | Falcon |
| cache_block | Falcon |
| cache_filter | Falcon |
| cache_form | Falcon |
| cache_menu | Falcon |
| cache_page | Falcon |
| cache_update | Falcon |
| comments | Falcon |
| files | Falcon |
| filter_formats | Falcon |
| filters | Falcon |
| flood | Falcon |
| history | Falcon |
| menu_custom | Falcon |
| menu_links | Falcon |
| menu_router | Falcon |
| node | Falcon |
| node_access | Falcon |
| node_comment_statistics | Falcon |
| node_counter | Falcon |
| node_revisions | Falcon |
| node_type | Falcon |
| permission | Falcon |
| role | Falcon |
| sessions | Falcon |
| system | Falcon |
| term_data | Falcon |
| term_hierarchy | Falcon |
| term_node | Falcon |
| term_relation | Falcon |
| term_synonym | Falcon |
| url_alias | Falcon |
| users | Falcon |
| users_roles | Falcon |
| variable | Falcon |
| vocabulary | Falcon |
| vocabulary_node_types | Falcon |
| watchdog | Falcon |
46 rows in set (0.00 sec)
Looks like we were successful - all Drupal tables are using the Falcon storage engine! Congratulations.
From here on, you can configure and change Drupal to your heart's content. Note however, that additional Drupal modules may contain code that is specific to the MyISAM or InnoDB storage engine, your mileage may vary. In that case it would be great to notify the module developers about these incompatibilities.
If you want to quickly populate a Drupal installation with content for testing, you can use the "Devel" module. I used it to create 500 users and 10.000 test pages on my demo installation. Even though this was performed within a virtual machine running VirtualBox, the system still was very responsive and the creation of the content proceeded amazingly fast! But I did not perform any serious benchmark or load tests (it would not make much sense in a VM anyway).
The number of available Drupal modules is continuing to grow dramatically. Like a lot of other Drupal users, I spend a good deal of time downloading new modules and trying them out to see what they do. Unfortunately, not all contrib modules work as advertised. I may spend several hours working with a new module before realizing there's some small issue with it that prevents it from solving my problem.
Similarly, there are often modules out there that solve problems I didn't even know I had, but I'm simply not aware they exist.
What I want is a resource that leverages the experience of thousands of Drupal administrators. I want to know that I shouldn't even bother with a module because it's too buggy. I want to know what modules other users find useful in specific areas (such as multimedia, file handling, cache issues, etc.).
Other large OSS communities often solve this need for a shared knowledge base by providing user reviews. Mozilla, Thunderbird, Joomla and other modular systems provide user reviews and ratings. It is time that the Drupal community have one too.
When I first started using drupal about three years ago, it was not all that difficult to simply be aware of most modules and how effective they were because there just weren't that many. Now there are multiple new modules released on a daily basis, and I just can't keep up anymore.
Why do we, the Drupal community, not have a shared review/rating system? It's certainly not due to lack of demand. A search for "module ratings" on Drupal.org reveals a great deal of interest in this functionality.
As far as I can tell, the primary reason for not having a rating system for modules is fear. Module developers in particular are concerned with the fairness of ratings. They are concerned with "gaming" of ratings. They are concerned that inexperienced or "dumb" end users may unfairly give a bad review of a module simply because they don't understand how to use it. These are all reasonable concerns. But they are concerns shared by other OSS projects as well. Sure you will see "bad" reviews, giving a module the lowest possible rating along with some inane review such as "tis modules sukcs BEWARES" :) But who cares, it's just noise that will be drowned out by valid reviews. It works for other OSS projects, and it can work for Drupal.
John Forsythe has released what I believe is the first site dedicated to rating and reviewing Drupal modules drupalmodules.com. No doubt this site will be a source of controversy as developers voice their concerns. But we need this resource now.
I encourage my entire audience (hi, mom!) to register at drupalmodules.com and to submit reviews for both your favorite and most hated Drupal contributions. This is a great way for non-techies to contribute to the community. The site is young, and there is naturally a shortage of ratings on the site now, but that will change as the site brings on more users.
Maybe this database will eventually make its way to Drupal.org. For now we can show our support for this type of system by helping build out the database at drupalmodules.com.
Views bulk operations is ready for some beta testers.
It is essentially the admin nodes page on steroids. It enables you to perform node operations as well as actions from a custom view.
If you want to quickly check it out, install it, then go to the views overview page. Select 'add' for the 'admin_content' view, configure it and save it. When you first go to the view, you will be prompted to enable actions and/or operations.
For the full effect, install the actions module as well.
If you have any problems using it, please submit a bug!
Drupal books are a great way to organize content. Unfortunately, there is no way to control access to individual books by default. Like default forums, it's all or nothing.
The Book Access module adds the ability to set view, edit and delete access control for individual books and all pages therein.
This module has no official release as it needs to be tested. The development snapshot is ready for testing though.
If you're interested in such functionality, install this module and please submit feedback and bug reports.
Thanks to LifeWire for sponsoring development of this module.
I began the Devbee website back in March as a way to help others by way of documenting what I have learned about Drupal and also to drum up a little bit of business for myself. The content of this site is extremely targeted, and I don't ever expect to see more than a few hundred visits a day. This definitely does not reflect the expectations, or at least hopes, of most website owners. It's typically all about bringing in as many visitors as possible to generate money through advertising or purchases. Sites interested in bringing in large numbers of visitors typically do this by spending a lot of time focusing on "search engine optimization" (SEO). Absolutely nothing can drive traffic to a site like a top placement in the search results on one of the major search engines.
Back in the day (way back during the last millennium), all one needed to do was have a simple HTML page containing relevant words or phrases and he was fairly likely to make a decent showing in results pages. In fact, this is exactly how I shifted from studying literature to building websites. I built my first homepage (don't laugh!) for fun. It was found by an employer, and I got a cool job at a major search engine. Today, it is not so simple.
Fortunately for us, as Drupal users, we have a secret weapon, Drupal itself. Drupal SEO does not require any witchcraft or elaborate HTML trickery. It's simple, and in this article, I'm going to explain how I get consistent premium search placement with very little effort.
Stumbling upon Drupal SEO
Today I discovered that an article I wrote recently is the top result for the query "opcode cache" on Google. I almost feel guilty about it. There are countless pages out there with much more information on the topic than my article, yet I'm at the top. I guess I'll just have to deal with it.
This is not unusual. I find myself on "the first page" of many searches for terms relevant to my site. And when I'm not seeing a premium placement (top-ten), it's either because the search term is very broad (e.g. "Drupal") or there are simply much more relevant pages pushing my placement down. Just like the old days.
And more than half of my very modest traffic comes through these search results.
What's the Secret?
Now comes the mysterious part. I make no claims of expertise in the area of SEO. It's mostly voodoo as far as I'm concerned. The search engines are necessarily very secretive about their methods, trying to stay ahead of search engine spammers. And what works today may be detrimental tomorrow. What I'm going to describe below is entirely based on my own, very subjective, experience with various techniques and modules. These are the things that I believe are resulting in my accidental SEO success.
Drupal SEO
Drupal itself is well-known for its search-engine friendliness. Its markup is clean and standards-compliant. It creates all the tags the engines are looking for. And unlike so many other CMSs, Drupal creates search engine friendly URLs. Using Drupal is the first step in this process, but presumably you're already doing this, so let's move on.
The Right Path
Here's an example of the URL to a Joomla forum topic: http://forum.joomla.org/index.php/topic,65.0.html
And here's an example of a URL to a Drupal forum topic: http://drupal.org/drupal-5.0-beta1
Do you notice a difference? Can you tell me anything about the Joomla article without going to the page? In fact you can, sort of: you might conclude that the page covers a topic, a fact of dubious value. The URL really provides no useful information to you. Nor does it provide anything useful to a search engine. This is key. Unless you're searching for "index topic 65.0 html", this URL isn't going to help you find the information on this page.
Looking at the Drupal URL is another story. Based on that URL, one can assume that it has something to do with "drupal 5.0 beta1", and so can a search engine. If that's what you're looking for, this page will come up #1.
Most SEO "experts" agree that the search-engine-friendly URLs are critical to a page's search ranking.
Drupal allows you complete control of the path of any page. Creating short, clean and informative paths will improve your rankings. And the Pathauto module automates the process of generating relevant paths. But be extremely careful when experimenting with Pathauto, particularly on sites with existing content. Using Pathauto without first understanding how to use it properly can result in all of the URLs on your site changing, and thereby breaking existing links to your content. If you are going to introduce Pathauto on an existing site, play it safe and enable the Create a new alias in addition to the old alias option in Pathauto's settings. But keep in mind that having multiple URLs pointing to the same page on your site may result in a search engine penalty for "duplicate content".
SitemapsSitemaps are an easy way for webmasters to inform search engines about pages on their sites that are available for crawling. In its simplest form, a Sitemap is an XML file that lists URLs for a site along with additional meta data about each URL (when it was last updated, how often it usually changes, and how important it is, relative to other URLs in the site) so that search engines can more intelligently crawl the site.
I've seen no solid evidence that implementing a sitemap will directly improve search rankings. However, even if search engines do not use your sitemap to to adjust the ranking of your pages (which I doubt), it does help them more efficiently index your site, thereby increasing the likelihood of your pages being included in search results. This one's a no-brainer.
Sitemaps would be virtually impossible to maintain by hand. And this is where the excellent XML Sitemap (formerly Google sitmeap) module comes in. Installing this module is simple and comes with reasonable default settings that don't require changing unless you want to fine tune your sitemap. After you've installed and enabled this module, you'll need to tell search engines about your sitemap. At this point, I'm only familiar with Google Sitemaps, Though other major companies are beginning to adopt this concept as an new open standard.
Leaving Comments
Another common method used by search engines to determine the importance of your pages is the number of other sites that link to them. A simple way to continually promote your site while helping improve your search rankings is to make regular comments on other sites like Drupal.org. Take the time to create an account on sites similar to yours and complete your public profile. Then leave useful comments where appropriate. Do not post comments simply to include a link back to your site. This is in very poor taste and may get you blocked. Instead, post comments where you have something to contribute to the topic being discussed. If you have nothing useful to add, don't post a comment. I'm a regular participant over at Drupal.org, and I'm confident this helps the "relevance" of my own site.
Page Title
By default, Drupal will use the title of your node as the page HTML title (the bit that appears in the <title></title> tags of the HTML and shows up in the title bar of your browser). This is very reasonable behavior. However, if you want to give your page that extra SEO boost, you may want to allow for two different page titles, one that appears at the top of the page in <h1> tags and the other that appears in the head of the HTML document in the <title> tag. the <h1> and <title> tags are both pieces that search engines will consider when reviewing your page. If they are identical, you're missing out on an opportunity to further promote the page!
So how do you manage to control the <title> tag contents if Drupal automatically sets it based on the node title? The Page Title module does this. Install and enable this module, and you will see an additional field on the node edit form called "page title". Use this field to configure the phrase that you think will most likely attract users to the page. Use something eye catching and alluring, something the user will feel he has to read. If you're writing about an article you found on another site, don't title the page "cool link!", instead, something more enticing: "Fascinating study of the Indonesian spotted tadpole". Follow that up with a relevant <h1> title: "National Geographic looks at one of nature's most mis-understood wonders".
The Prophecy
Search result placement was not a top concern of mine when I built this site. But it has become a bit of an obsession now. I have no need to drive thousands of visitors seeking information on opcode caching to my site, but hitting that number one position for a query is a bit of a rush! Thanks Drupal!
Lastly, I asked myself a question as I wrote this article: Is there anything at all to what I'm saying? Well, I think there is, and I'm willing to make a bold prediction based on this belief. Within three days of posting this article, I believe it will appear in the top-ten search results for "Drupal SEO" on Google. If I'm right, that should serve as some pretty solid evidence that there's something to all this. There are currently 1,090,000 pages competing for placement in this results page. The odds of making it into the top-ten by shear luck are 1 in 109000.
And if I'm wrong, well, I can always come back and edit out this prediction to save face %^)
The Revelation
Update: Mon Nov 27 23:19:42 2006
A search for "Drupal SEO" now shows this article as the second result out of 1,080,000 pages. I come in just below an article on Drupal.org.
So as you now see, there is not a lot of work involved in getting premium search placement if you are using Drupal. Of course, the broader your topic, the more difficult it will be to hit the top-ten. While you can almost certainly hit number one for surfers searching for a certain rare antiquity, your less likely to see much success attracting surfers hunting for the term "sex".
Until the mid 90s, spam was a non-issue. It was exciting to get email. The web was also virtually spam-free. Netizens respected one another and everything was very pleasant. Those days are long gone. Fortunately, there are some pretty amazing tools out there for fighting email spam. I use a combination of SpamAssassin on the server side and Thunderbird (with its wonderful built in junkmail filters) on the desktop. I am sent thousands of spam messages a day that I never see thanks to these tools.
But approximately five years ago, a new type of spam emerged which exploited not email but the web. Among this new wave of abuse, my personal favorite, comment spam.
I love getting comments on my blog. I also like reading comments on other blogs. However, it's not practical to simply allow anyone who wants to leave a comment, as within a very short period of time, blog comments will be overrun with spam generated by scripts that exploit sites with permissive comment privileges. To prevent this, most sites require that you log in to post a comment. But this may be too much to ask of someone who just wants to post a quick comment as they pass through. I often come across blog postings which I would like to contribute to, but I simply don't bother because the site requires me to create an account (which I'd likely only use once) before posting a comment. Not worth it. Another common practice is the use of "captchas" which require a user enter some bit of information to prove they are human and not a script. This works fairly well, however, it is still a hurdle that must be jumped before a user can post a comment. And as I've personally learned, captchas, particularly those that are image based, are prone to problems which may leave users unable to post a comment at all.
As email spam grew, there were various efforts to implement similar types of protection, requiring by the sender to somehow verify he was not a spammer (typically by resending the email with some special text in the subject line). None of these solutions are around anymore because they were just plain annoying. SpamAssassin and other similar tools are now used on most mail servers. Savvy email users will typically have some sort of junkmail filter built into their email client or perhaps as part of an anti-virus package. And spam is much less a nuisance as a result.
What we need for comment spam is a similar solution. One that works without getting in the way of the commenter or causing a lot of work for the blog owner. Turn it on, and it works. I've recently come across just such a solution for blogs which also happens to have a very nice Drupal module so you can quickly and easily put this solution to work on your own Drupal site.
Enter Akismet
It's called Akismet, and it works similarly to junkmail filters. After a comment (or virtually any piece of content) has been submitted, the Akismet module passes it to a server where it is analyzed. Content labeled as potential spam is then saved for review by the site admin and not posted to the blog.
Akismet follows my absolute favorite pricing model. It's free for workaday Joes like me and costs money only if you're a large company that will be pumping lots of bits through the service. They realize that most small bloggers are not making any money on their sites, and they price their service accordingly. Very cool.
In order to use Akismet, you need to obtain a Wordpress API key. I'm not entirely sure why, but it is free and having a collection of API keys is fun. So get one if you have not already.
The Akismet Drupal module is appropriately named Akismet. It's not currently hosted on Drupal.org, but hopefully the author will eventually host it there as that is where most people find their Drupal modules. Instead, you will need to download the Akismet module from the author's own site. The installation process is standard. Unzip the contents into your site's modules directory, go to your admin/modules page and enable it. There is no need for additional Akismet code as all the spam checking is done on Akismet's servers.
After installing Akismet, I was immediately impressed at how professional the module is. There were absolutely no problems after installation. Configuration options are powerful and very well explained. The spam queue is very nice and lets you quickly mark content as "ham" (ie not spam) and delete actual spam. As you build up a level of trust with the spam detection, you can configure the module to automatically delete spam after a period of time.
Spam filtering can be enabled on a per node type basis, allowing you to turn off filtering for node types submitted by trusted users (such as bloggers) and on for others (eg forums users). Comment filtering is configured separately.
Another sweet feature is the ability to customize responses to detected spammers. In addition to being able to delay response time by a configureable number of seconds, you can also configure an alternate HTTP response to the client, such as 503 (service unavailable) or 403 (access denied). Nice touch.
One small problem
I've only been working with Akismet for several days now. And I'd previously been using captcha, which I imagine got me out of the spammers sights for a while (spammers seem to spend most of their efforts on sites where their scripts can post content successfully). So far, Akismet has detected 12 spams, 2 of which were not actually spam. These were very short comments, and I imagine Akismet takes the length of the content into consideration. I assume that as the Akismet server processes more and more pieces of content, it will become more accurate in picking out spam versus legitimate content. Each time a piece of flagged content is marked as "ham", it is sent to Akismet where it can help refine their rule sets and make the service more accurate.
Perhaps Akismet could provide an additional option that allows users to increase or decrease tolerance for spam. I would prefer to err on the side of caution and let comments through.
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