Mar 06 2015
Mar 06

I took the “Acquia Certified Drupal Site Builder” certification exam last weekend. Cleared the exam with a 90% score.

 

The blueprint of the exam with the usual details like Time Limit, Number of questions etc is available @ https://www.acquia.com/customer-success/learning-services/acquia-certified-drupal-site-builder-exam-blueprint#animated

 

 

This exam is definitely the easiest among the 4 Acquia Certifications available currently. The others being - 1) Acquia Certified Developer 2) Acquia Certified Developer-Back end Specialist and 3) Acquia Certified Developer - Front End Specialist

 

This should be an easy kill for any Drupaler who has good experience building websites with Drupal core and the Contrib Modules available. However I do not remember facing specific questions about any contrib modules other than Views.

 

I believe the exam would be more comprehensive if it also tested on some more contrib module that are very extensively used in building Drupal Sites. Like Rules, Context, Webform, Pathauto, Panels etc

 

When it comes to preparing for the examination, you would need no preparation if you have built at least a couple of medium/large websites using Drupal, leveraging all of the functionalities available in Drupal core and Views.

 

If you were to quickly recep before jumping in for the exam, you could take this approach:

 

Install the latest version of Drupal. Add the module admin_menu. This will make all the admin pages of the site easily accessible. Start with Content, and proceed one by one till the Help tab, exploring all sub-navigation items one by one thoroughly understanding what functionality is achieved from each of these administration pages.

 

Ensure you understand thoroughly:

  • Structure:

    • What are blocks? Why would you use them? Where would you place them? How are they created? What are the various blocks provided by various modules available in core?

    • What are content types and nodes? When would you create a new content type? Check the various configuration options available under each content type.

    • What are menus? How do you create them? How do you place them on the site?

    • What are Vocabularies? What are terms? When would you create a new vocabulary vs When would you create a new content type?

  • Themes:

  • People:

  • Modules:

  • Configuration:

    • What are text formats? What are filters? How are they related? Why would you need them? How do they help you in securing the site?

    • File System. Public and Private. What happens to the uploaded files? How to upload/attach files to content? What are image styles? Why would you need them? How do they help? How do create new image styles?

    • Under account settings, check out the various options related to user accounts. Adding fields to user profile. Configuring who can register on the site. Configuring the various emails sent out to the users at various stages of the registration process.

    • Under ‘Regional and Language’, check out how to configure the locale and timezone settings, the various date formats available and how to add new ones.

    • Configuring the core search, Indexing and Content Ranking Settings.

    • Managing aliases (without Pathauto) as well as basic automation of aliases using Pathauto

    • Configuring Site Information like Site Name, Slogan etc. Configuring Cron.

    • Take a look at the Aggregator module that comes with core. Make sure you are familiar with what the module is for and how to configure it to pull some feeds into your site.

    • Check out the development options available like Various caching options and how they affect the display of the site. What are the various logs accessible from within the Drupal site. The status report page. What is maintenance mode? Controlling display of various type of errors and notices displayed on the site.

  • Views:

    • Apart from being able to build fairly complex views, ensure you understand the following thoroughly:

    • Views Relationships

    • Contextual Filters

    • Views Attachments

    • Rewriting Field output

    • Configuring the format of display of fields

    • Views Cache Configuration

    • Adding Headers and Footers to Views

    • In short, ensure you thoroughly understand each of the options available on the views configuration.


Mainly, the blue print @ https://www.acquia.com/customer-success/learning-services/acquia-certified-drupal-site-builder-exam-blueprint#animated lists various scenarios, like “Given a scenario, identify when a contributed module would be needed." Ensure you are able to answer all of them before attempting the exam.

 

Unlike the other exams in the certification series, this exam would not require much time to complete. I managed to complete the exam with about ~30mins still remaining.

 

Who should take this:

For regular Developers, I would recommend that they take the Acquia Certified Developer exam or Backend Specialist exam first which would be a more powerful showcase of their deep Drupal skills.

 

This exam will be a good value addition if you belong to one of the below categories:

  • Jr Developers starting with Drupal and too early to take the Acquia Certified Developer or Backend Specialist exams

  • Freelancers building websites with Drupal and who are not much into Module Development yet. (The immediate one I had in mind was Miss Jayalakshmi Jayanth. She builds amazing stuff with Drupal though she has not ventured yet into custom module development. This certification will definitely be a good showcase of site building skills of such freelancers)

  • Project Managers and Engagement Managers managing Drupal Projects. Though not essential, I, as a customer would remain very peaceful if I am assure that the manager managing my project knows what is what of Drupal.

 

All you need to know about the exam is here :

https://www.acquia.com/customer-success/learning-services/acquia-certified-drupal-site-builder-exam-blueprint

 

You can schedule the exam by clicking on “Schedule a Test” on the above page.

Mar 05 2015
Mar 05

MidCamp is the Midwest's premier DrupalCamp, where developers, designers, strategists, UX professionals, project managers, and many others gather to share ideas on a variety of topics and technologies. We're excited about the camp for a lot of reasons: our CEO Tiffany Farriss has been asked to give the keynote, members of our team are leading a variety of sessions and providing training, and, of course, simply the opportunity to be in attendance.

Community is the key here. Local community. Technology is grand when it works, but the IRL connections you make with your peers trumps anything on an IRC channel or Google Hangout, so we're giddy with excitement to be social and geek out about the things we love. These kinds of conversations advance things for all of us professionally and personally.

Palantir and MidCamp 2015 = love

As you might suspect, we're up to a lot of things at MidCamp (not to mention helping on an organizational level). In particular, we are absolutely committed both to the Drupal community at large, and on a local level so we've proudly sponsored the camp at a Gold Level this year.

What else? Plenty! We've outlined everything in a handy list for you:

Onsites and Project Kickoffs that Work

In this first of two training sessions. Project Managers Allison Manley and Chad Goodrum will show you how to best utilize the time you have with clients when starting a project. You don't want to miss this, as we'll provide real world examples along with plenty of tools and techniques so you'll leave with a deeper understanding of how to ensure that your projects start and stay strong. We'll also share some sample documents and resources that you can build on as well. Note that registration is required with a cost of $175 per seat, and all trainings include coffee, snacks, and lunch. Sign up early as space is limited.

Date: Thursday Mar 19
Time: 9am - 12pm
Room: SCE Illinois AB

Absolute Beginners Guide to Drupal

Next, Engineer Michelle Krejci and Build a Module founder Chris Shattuck present this learn-at-your-own-pace training, designed to introduce you to Drupal basics and give you a chance to explore the material from Build a Module that meets your needs. Note that registration is required at $49 per seat, and all trainings include coffee, snacks, and lunch. Sign up early as space is limited on this, too.

Date: Thursday Mar 19
Time: 1pm - 5pm

Economics of Drupal Contribution

Palantir CEO Tiffany Farriss is keynoting the camp with this talk where she will explore how other open source communities provide a strategic framework to their communities and how the Drupal Association could provide structural support to balance the needs of contributors and a successful project.

Date: Friday Mar 20
Time: 9am - 10:15am
Room: SCE Illinois AB

Don't Let the Pigeon Drive Your Project!

Palantir founder and CEO George DeMet presents a non-technical talk—inspired by values frequently explored in children's literature—on how building successful Web solutions for other people requires discipline, understanding, and empathy. He'll cover topics that include managing stakeholders, positive negotiation techniques, and keeping budget, timeline, and scope on track.

Date: Friday Mar 20
Time: 12:30pm - 1:30pm
Room: SCE Illinois C

On PhpSpec and Not-the-Drupal-Way: follow the black kitten through the Looking Glass

Engineer Michelle Krejci demos PhpSpec and shows how this tool can help you write better code and modernize your developer skills.

Date: Friday Mar 20
Time: 1:45pm - 2:45pm
Room: SCE Ft. Dearborn B

Off with Drupal's Head!

Web Designer Ashley Cyborski and Lead Engineer Steve Persch are part of a panel called Off with Drupal's Head! where they'll discuss a variety of techniques used to implement a “headless Drupal."

Date: Friday Mar 20
Time: 4:30pm - 5:30pm
Room: SCE Ft. Dearborn B

Rendering HTML with Drupal: Past, Present and Future

Steve Persch is also presenting on the mental models used in Drupal theming in recent history and in the future with Rendering HTML with Drupal: Past, Present, and Future.

Date: Saturday Mar 21
Time: 09:00 - 10:15
Room: SCE Illinois C

From Zero to Silex

Larry "Crell" Garfield explores Silex and explains what exactly this ready-made request/response pipeline is (and isn't). A small but functional application file will even be built during the session!

Date: Saturday Mar 21
Time: 3pm - 4pm
Room: SCE White Oak AB

How about you? Attending the camp? Any fun after-hours meetups you're attending? Please do let us know on Twitter @palantir, or by commenting below. Hope to see you there.

Mar 05 2015
Mar 05

Last week, we announced our new interactive video module for Drupal, HubDub. We followed that up with a more detailed under-the-hood look at how HubDub works. Now, I'd like to take a look at a key part of the technology that drives HubDub: jPlayer.

Why Video Overlays?

As a company that specializes both in video production and web development, incorporating video with our work is a natural extension to our web development efforts. One of the more frequently requested features is an HTML overlay that permits the viewer to submit a donation or feedback on the video in question. To that end, we have been developing a Drupal module, Hubdub (sorry Wordpress folks, there are no confirmed plans to create a corresponding plugin, yet), that displays videos as Drupal blocks, with the option of displaying overlays with arbitrary show/hide times. Its a useful project for us, as formerly, this sort of thing had been implemented on a case-by-case basis in template files or custom modules with little to no customization permitted.

jPlayer

For the front-end display, I am using jPlayer to render the video (with preference for HTML5 and Flash as the fallback). I selected jPlayer as a familiar and reliable video library that supports timeupdate events (very helpful for timing overlay displays).  In this current iteration of the module, we are not yet offering any jPlayer option controls on the backend, although that’s coming soon!  For the time being, it offers the bare minimum functionality: title, video URL (at this time this must be an mp4 file or RTMP stream), unlimited overlays with title, markup, and start/end time.

This current iteration does not yet provide full HTML5 cross-browser support. This requires the ability to provide fallback video formats for the video (example: mp4 is required, but webm and ogg files would be permitted to more broadly display video as an HTML5 video).  However, this will also be coming soon.

Finally, this version of the module does not support Youtube streaming, yet.  But, stay tuned.  Numerous new features are planned!

We're always eager to hear your feedback! Please post bug reports, feature requests, and support questions in the HubDub issue queue. Next in our HubDub series, Alexis will have some tips on styling video overlays.

Mar 05 2015
Mar 05

Web accessibility is about making websites accessible to people with disabilities.  Those disabilities include everything from blindness and varying degrees of vision impairment to a broken bone in a dominant hand to cognitive disabilities such as dyslexia.  Making websites usable by those with disabilities is not as difficult as you may have been led to believe. There are things that are considered just plain good practice in building a website that can make a site vastly more accessible to all.  Here are 5 things that can easily be accomplished with most sites:

1. Add a skip to content link

Try navigating your website with just a keyboard. Load a page and just start pressing the tab key. Follow the outline of the content in focus as you tab through the page. Now imagine that you’re on a page with a list of 50 nested menu items down the left side of page and in order to fill out a form in the main content of the page, you have to tab through every single menu item.  That gets old quickly.  There’s a simple solution.  Add a “skip to content” link as the first piece of content in the body section on the page that links to the page’s main content.  This way, when a page is loaded, all a user needs to do is press enter and voila, they’re at the page’s main content. 


    Skip to main content

There is debate over whether this link should be visible or not. My preference is a combination of the two - hide the link until it receives keyboard focus.  That way sighted keyboard users get a visual when they tab to it. Note that it should be hidden by positioning the content off-screen, not by using display:none or visibility:hidden, which hides the link from screen readers.  

#a11y-hidden {
    position:absolute;
    left:-10000px;
    top:auto;
    width:1px;
    height:1px;
    overflow:hidden;
}

Additional information on Skip Navigation links can be found at:

"Skip Navigation" Links
CSS in Action

2. Use descriptive text for links

A common way of navigating through the content of a website with assistive technology is by skimming the list of links by tabbing through them.  However, if the text of all the links in the main content of the page is “Click here” or “more”, this method of scanning content becomes useless. For example, 

Check out the state forest closest to you. View a map of all PA state forests.

or:

Many of the instruments we take in on trade are overhauled and put back into like-new condition and resold.  View our reconditioned instruments for sale.

are much better than:

For more information, click here.

3. Structure your content

Another method by which screen reader users navigate a site is by skipping from heading to heading to get a sense of the topics on the page.  Screen reader software allows a person to bring up a list of all headings on the page to choose from or at the very least, to just tab through them.  If a page is marked up in a logical hierarchical manner using descriptive text in appropriate heading tags (h1, h2, h3, etc.), it becomes much easier to get a sense of what the page is about without having to listen to the entire page’s text content. 

4. Use alt text for images

To a sighted person, images convey a lot of information at a glance.  It’s also quickly apparent to a sighted user whether an image contains content relevant to the page or is just eye candy.  To a blind user, they only know that there is an image on the page.  They don’t know whether they’re missing a great deal of information or whether it can just be ignored.  The use of alternative text with images helps to convey important information about the image to the user.  They also help people who have images turned off due to low bandwidth.  

”A 

Or better yet:

”A  

See Webaim’s article for more in-depth info on how to properly and effectively use the alt text attribute for images.

5. Choose sufficient color contrasts between background and text colors

Make sure there is sufficient contrast between foreground text and background colors.  This will help those with vision impairments, such as color blindness.  To check whether your color contrast is sufficient, use Webaim’s color contrast checker.  Enter the url and then click on the contrast tab.    

Conclusion

While accessibility can get tricky when you get into complex sites like Facebook, the average site would become much more accessible just by implementing these 5 simple suggestions.  And it not only makes the site more accessible to those with disabilities, these improvements also provide better fodder for search engines and often result in a boost in Google ranking!

Additional Resources

A Guide To Drupal Terminology |Mediacurrent Blog Post

Mar 05 2015
Mar 05

Drupal is a great platform for commerce. For simple tasks it’s very easy to get started with the Commerce Kickstart distribution, but there’s no consensus on what to use for more complex features. This means you might need to perform a long research to be able to choose a solution for more complex e-commerce tasks.

In a recent project we needed a solution for recurring payments, so I thought I’d share the results of our research.

When your customers pay for your service or product periodically, you need recurring payments. Subscriptions are a good example.

For recurring payments you need to handle the following:

  • Credit card data
  • Subscription management (subscribing, cancelling, upgrading, downgrading)
  • Refunds
  • Dunning
  • Discounts and coupons
  • Account management
  • Invoice emails
  • Billing

We considered three different approaches when researching recurrent payment solutions. The first 2 only use Drupal modules, and the third one uses a recurring payment service like Recurly or Chargify.

Commerce Recurring Framework

The Commerce Recurring Framework (only dev! 2.x branch is mostly the work of pcambra creates a Recurring entity that stores information on the order, the recurring period, the recurring price, the end date and optionally the trial period and price. Each time a recurring payment is made, a new order is created in the background. Your usual product pricing rules nicely apply to this order.

Using additional commerce modules like Commerce Dunning, Commerce Discount, Commerce Coupon, Commerce Card on File, Commerce Billy and Commerce Return Merchandise Authorization you can get a basic grip on almost all the points from the wishlist above.

Commerce License

Commerce License (mostly written by bojanz from Commerce Guys) is shipped with a License entity. The License entity itself has nothing to do with recurring payments. “The License entity is usually created during order checkout, that holds information about accessing the purchased resource, and it has a status and an optional expiration date”.

It is the Commerce License Billing module that makes recurring billing possible for licenses.

The Commerce License framework is very flexible and it is the recommended way now to do recurring payments with Drupal Commerce. The downside is that you will probably need to code your own License plugin. Currently I could find 2 license plugins on drupal.org: one for user roles (included in Commerce License) and Commerce License OG (now dev).

There is a difference between the approach of Commerce Recurring Framework and Commerce License:

  • Commerce Recurring Framework handles recurring payments, nothing more.
  • Commerce License takes a step back and asks the question: what are recurring payments usually used for? To gain expirable access to a resource. So it strives to create a general framework for managing data related to expiring access.

Chargify and Recurly

Third party services let you outsource the commerce component of your site, so that you don't have to do the theming and maintenance for it. It is a way to deliver commerce functionality at a much lower upfront investment cost, especially if you don't do a deep commerce integration. It does however come with a price: as monthly subscription cost and in terms of ownership. If anything happens with the 3rd party service (in case it would go out of business or change strategy so that it is no longer a good business fit), you might lose data or have to do a complex import scenario. So I think it makes most sense to use a 3rd party service when you are investigating new products where you need to get up and running fast, and need to learn from expedited customer interaction.

From a Drupal perspective the issue with Chargify and Recurly is that they do not have a Drupal Commerce integration.

  • The Recurly module integrates nicely into Drupal (not Drupal Commerce!) including push notifications from Recurly.com. It also includes built-in pages for users to view invoices, subscriptions, and to upgrade/downgrade their subscription level. It supports Recurly.js which allows you to get rid of the PCI-compliance headache.
  • The Chargify API does much less: it’s just a wrapper for the Chargify php library.

The two services work similarly. You can set up a “Buy” button really fast by just embedding some code on your page. This button redirects you to the service’s so-called “Hosted page” where customers can buy the product. Credit card data, subscription management, dunning, notification emails, refunds, discounts can be easily handled on the merchant’s Chargify/Recurly account. This way however you will miss:

  • Drupal Commerce goodies like:
    • Cart: Customers will only be able to buy stuff one by one.
    • Order, product, discount management: Neither customers nor admins can view orders on the Drupal site. You’ll have to sync your products and discounts on your Drupal site (for display) with those on the service site (for actually paying for them).
  • Proper user account management: Each time you use the Chargify Hosted pages a new Chargify user account gets created which is not the desired behavior for returning customers. Creating two user accounts with the same email is also possible in Recurly. To get around this you will need to use the API.
  • Advanced subscription management: With Chargify customers do not have one page to handle all their subscriptions. Instead, they get a separate link in email for each subscription.
  • Flexibility in general: For example, you cannot fully customize the dunning process in Recurly.

Both services have an excellent API. Using the API can get you most of the above features (like Drupal Commerce goodies). Webhooks enable Drupal to react on events on the service side. But you will lose the benefit of not needing to maintain your code.

3rd party payments services usually have a monthly fee. The simplest package in Chargify costs $65/month, in Recurly $99/month. In addition there is a per transaction and revenue cost.

Opt for the Commerce Recurring Framework, if you

  • only want to handle recurring payments, nothing more
  • want to do that fast
  • need the flexibility of Drupal Commerce
  • don’t want to code
  • have a developer team that can handle the risks of a dev module

We went with this in our project that sparked the research.

Choose Commerce License, if you

  • are more picky about module stability
  • still want to do it your own way with Drupal Commerce
  • are willing to do some coding

It seems there is a preference in the community to use Commerce License for recurring payments.

You should definitely use Recurly or Chargify if you

  • want reliability and maintenance of recurring payment functionality to be somebody else's headache
  • are not scared by the monthly fee
  • need something working fast without Drupal Commerce or you can invest in custom development for its integration
Mar 05 2015
Mar 05

DrupalTour aims at spreading the word to different cities. But the point is not just in that! We are also just having fun :)

It is already a fourth DrupalTour and this time we were heading to Khmelnitsky. Every point of destination is more and more distant from Lutsk, so the crew of Drupal van has to get up early… This time we started our journey at 7:30 AM to arrive to Khmelnitsky at 11 AM.

After finding the location of our event, we headed to a cozy place nearby to have a breakfast. It might have experienced the biggest concentration of drupalists at one table ;)

DrupalTour breakfast

And the team splitted: someone went shopping and the rest was preparing the location to the event. The earlybirds started coming already half an hour before DrupalTour actually hit off, but no one remained bored. It was a nice opportunity to get acquainted and chat.

DrupalTour registration cups

DrupalTour registration visitors

DrupalTour Khmelnitsky was like a real IT-conference — there was 5 reports delivered! The first one was by Andrii Sakhaniuk. He told about Drupal in general. This information was especially useful for those, who just want to start developing on Drupal or hesitate choosing a CMS.

DrupalTour reporter Andrii Sakhaniuk

The second report dealt with React.js and the advantages it gives the developers. Olexandr Bondarenko wore a head light — very useful tool to eliminate the distracting factors during the report ;) Seriously though Olexandr was going to auto quest to another city right after his report, so it was requisite for the quest.

DrupalTour reporter Olexandr Bondarenko

The following report was delivered by Viktor Voloshyn and dealt with e-Commerce for Internet business newbies. The topic never loses its importance!

DrupalTour reporter Viktor Voloshyn

We’ve had a lot to discuss and consider new information, so we made a break. The visitors enjoyed communicating with each other and drinking beer!

DrupalTour visitors break

Timur Bolotiukh started his report right after the break. He told about Ember.js, another Javascript framework. He paid attention to all aspects of Ember.js, highlighted its pros and cons. The visitors really enjoyed the report!

DrupalTour reporter Timur Bolotiukh

The last but not least — Olexandr Kuzava with report about creating a blog site on Drupal. It was particularly cool because it included not just theoretical, but also practical part. Olexander created a simple blog site on Drupal right there! Nice experience for all Drupal newbies.

DrupalTour reporter Olexandr Kuzava

We really enjoyed the company of our visitors and speakers, that’s why we went to another place to have few beers and chat in informal atmosphere.

DrupalTour afterparty

The time passed really quickly and soon we had to leave for Lutsk. And the preparations for DrupalTour never stop! Soon we will announce the next city!

P.S.: we alreaady added photos from the event in social media. Come and take a look!

Mar 04 2015
Mar 04

Drupal comprises several layers of execution and it obviously consumes pretty much time to render content from dynamic PHP code. Caching is a key technique to maximize the performance of Drupal. Before adopting a caching mechanism in Drupal, one must consider the type of site and the type of users coming to the site. Not all sites could have same caching mechanism.

 

Caching techniques could be classified at various levels depending on type of data being cached and the user affected. Drupal can have broadly two kinds of users.

  1. Anonymous Users

  2. Authenticated Users

HTML pages delivered for anonymous users are all same but the HTML pages delivered to authenticated users has personalized content (Ex. Welcome ). Essentially, very high speed can be achieved by caching HTML output for anonymous users. Now let us see various methods of caching in Drupal.

Drupal Internal Caching

Drupal internally has a caching mechanism that we could leverage easily. Data stored in cache tables can be fetched at higher speed. Drupal internal caching can be integrated with a  preferred caching backend instead of default cache DB table. Drupal cache settings are listed in its performance page. It contains the following options:

  • Cache pages for anonymous users: Enable this to activate full page caching for anonymous users.
  • Cache blocks: Enable this to cache Drupal blocks (also remember that block cache will be disregarded by page cache).
  • Minimum cache lifetime: This value is often misunderstood. It not just indicate the time after which the cache should be deleted. It should be accompanied by a cache clearing event.
  • Expiration of cached pages: This refers to the maximum time an external cache can use an older version of a page. This is not related to Drupal’s internal cache tables.

It is always recommended to enable Drupal internal caching in your production site.

Custom Cache using Drupal’s Cache API

Drupal core provides cache API to save data in cache tables. This helps us to save data directly from PHP code. Large amounts of data can be stored in a dedicated cache table. For instance, views module uses cache_views and cache_views_data to store data.

The predominant functions of cache API:

cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT)
cache_get($cid, $bin = 'cache')
cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE)

The $cid (cache ID) uniquely identify a cached element in a {cache} table. If the $wildcard boolean is set to TRUE, all cache IDs starting with $cid (string) are deleted.

Drupal views cache:

Drupal’s views module stores data in its own dedicated tables {cache_views} and {cache_views_data}. Caching is off by default and it can be enabled under Advanced options for each individual view display. It allows us to cache query results and rendered output for each view display. If you generate a block, you can expose it to Drupal’s built-in block caching. It also uncovers the Drupal block caching types such as caching per user, per page, per role, etc.

Memcache

Memcache is a technique in which the objects from external data source (database or API) are cached in RAM. It helps reduce database load and is generally much faster. Memcache is generally helpful to speed up the site for authenticated users.

It requires a daemon/service called ‘memcached’ (see memcached.org) and also a PHP extension to use this service. There are two PHP extensions available to use this service ‘memcache’ and ‘memcached’ (don’t get confused with previously said memcached daemon). Memcache is not recommended for shared hosting servers.

Drupal’s memcache module provides integration between Drupal and memcached. Additionally, you need to set memcached as cache-backend for Drupal to start integrating memcached with Drupal’s caching system. This is done with the following snippet of code in Drupal’s settings.php

$conf['cache_backends'][] = 'sites/all/modules/memcache/memcache.inc';
$conf['cache_default_class'] = 'MemCacheDrupal';
$conf['cache_class_cache_form'] = 'DrupalDatabaseCache';
$conf['memcache_key_prefix'] = 'unique_key'; /*Multisite installation*/

Opcode Cache

There are several add-ons for PHP that will convert program code to memory (bytecode). This bytecode can be cached to skip parsing and compilation for the next request. It will improve load time and reduce CPU usage. This technique is known as Opcode Caching.

APC (Alternative PHP Cache) is a familiar add-on for PHP to perform opcode caching. It also supports user cache. It operates at the server level and cannot be run on shared hosting servers.

Zend Opcache is another such add-on for PHP. It is compiled by default on PHP v5.5+. It has more advanced features than APC but does not support user cache. If you want to take advantage of APC’s user cache, you can install an extension named APCu.

Reverse Proxy - Varnish

Varnish is an advanced and very fast reverse-proxy system. (see this StackOverflow question to know what reverse-proxy is)

Varnish acts as an intermediary between the users and the web server. When Varnish receives a page request from a user, it will first check its own internal cache for that particular page. If found it can serve faster from its own cache otherwise it forwards the request to original web server.

Varnish could handle serving static files and anonymous page-views only. Drupal’s varnish module provides integration between Drupal and Varnish HTTP Accelerator. Additionally, you need to set Varnish as cache-backend for Drupal (Refer varnish project page). Also you need to configure Varnish to tell where it should listen to your web server. This is done with the following snippet of code in /etc/varnish/default.vcl

backend default {
  .host = "127.0.0.1";
  .port = "8000";
}

Note: The option ‘Page cache lifetime’ in Drupal’s Performance page is used to define Varnish cache expiration date. Drupal’s expire module can be used to expire URLs from Varnish cache.

Boost

Drupal’s boost module provides static page caching, similar to Varnish. On user request, instead of regenerating pages from PHP, it can serve .html or .html.gz pages directly from static disk files. It achieves this by modified .htaccess and robots.txt files. Pages that are served directly from boost will contain a short markup information at the end of the html code like

  

Boost module supports crawler (automatically regenerates URLs for expired pages). It works well in shared hosting environment. Many Drupal users are reporting success using Memcached (for authenticated page-views) and Boost (for anonymous page-views) together.

Content Delivery Networks (CDN)

CDN is a Geo-dispersed network that stores content closer to the user. It essentially reduces the latency between the end user and the server.

Drupal’s cdn module provides easy Content Delivery Network integration for Drupal sites. It alters file URLs so that files are downloaded from a CDN instead of your web server.

Unlike the other caching options, a CDN will always involve an additional financial cost.

Final words:

There are several techniques to perform caching in Drupal. Efficient use of these methods could improve your site performance. A poor cache configuration could cause negative effects. Generally, one can figure out best possible caching configuration with the server resources available by trying them out for that particular website.

You can leverage full page caching for anonymous users using Varnish if you are having a dedicated server or Boost if on a shared server. APC (OpCode cache) generally does help with better low level performance tweaks. Cache for authenticated users can use Memcache reducing load on database.

Drupal 8 performance gain: In Drupal 7, it is just possible to delete a specific cache item, or clear an entire cache bin, or use prefix-based invalidation. It means if you modify a node, you cannot precisely target all the cache items that contain this node. But, Drupal 8 (with the introduction of cache tags) has more precise cache invalidation. Each cache item can have number of cache tags. This helps us to target our cache items more precisely for deletion, and an obvious gain in the cache hit ratio. Also, see the changes in cache API here.

Mar 04 2015
Mar 04

The Views Exposed Filter functionality helps users select or filter data on the display. In our example, we are going to cover the basic steps involved to use the Views Exposed Filter.

Here, we are going to create a views display with content titles by setting an exposed filter for the content types. The resulting display will look similar to the one below:

Views Exposed Filter screen

For achieving this, we need to do the following steps.

  1. Create a View

Click "Structure" [Manage >> Structure] on the administration menu or go to the path "admin/structure".

Click Structure

Then click "Views" or go to the path "admin/structure/views".

Click Views

Click "Add new view" or go to the path "admin/structure/views/add".

Add new view

In the new form, type in Views Exposed Filter  in the "Views name" field. Tick the box against the "Create a page" field.

Provide a value to the "Path" field. Here we are providing the path views-exposed-filter.

Under "Display format", select Unformatted list  and titles from the dropdowns. Click "Save and edit". Refer the following picture for more details.

Configure the View

2. Add the filter field to be exposed

In the Views Display settings page, click "Add" in the "FILTER CRITERIA" section. 

Add the filter

You will get a configuration page similar to the one shown below:

Click Apply

Scroll down and select "Content: Type". Click "Apply (all displays)". You will get the "Configure filter criterion: Content: Type" box as shown below:

Tick the Expose filter box

Tick the box against "Expose this filter to visitors, to allow them to change it" and click "Apply". Save the view and go to the path earlier defined by you (views-exposed-filter). Your display will be similar to the one below:

Final screen

Mar 04 2015
Mar 04

Learning to love the “touch-base”

One of the core skills of our client services team is the ability to communicate clearly, efficiently, and humanely to each other and to our clients. It’s this communication that gets us through gnarly project roadblocks and beyond the purely technical solutions. Unfortunately, this can lead to the dreaded wave of “calls”, “syncs”, “touch-bases”, and “meetings” which eat up our calendar hours.

As much as these terms can make our stomachs collectively turn, they are a critical component of the success of our projects. How do we turn this communication from something we avoid into something we look forward to?

Min-maxing participants and empowerment

The first step is to define the participants in a meeting. Each participant should be able to provide a unique perspective to the topic at hand. On many projects, there are multiple developers, designers, testers, and project managers, and in many cases only one person from each group is actually required for the weekly syncs.

It’s easy to default attendance to whoever has “senior”, or “lead”, or “manager” somewhere in their title. But in a balanced and capable team, it is often better to share the load of decision making among the greater team, especially as projects move on and individuals develop areas of expertise. In some cases, it can work well to simply round-robin participation from different subgroups. This helps to prevent one person from being overloaded with calls and meetings while giving the whole team a chance to drive the project direction.

A meeting should end up with a small group of individuals attending. I find it works best with no more than 4 people. Each person should have distinct contributions to make, and together the group should be empowered to make decisions. Sometimes discussion reveals further dependencies to resolutions, but ideally a meeting is a chance to show your team that you trust them and their expertise.

Action items and responsibilities

“What did we decide on the last call?” is one of the most frustrating ways for teams to start a meeting. Rehashing discussions and decisions leaves participants feeling like their time was wasted and that no progress was made. With a bit of guidance (typically from project managers), meetings can be made more effective with some documentation.

I find the best meeting notes are those that are distributed to the whole team and indexed, such as in an app like Basecamp or Google Groups. Each note should contain the participants, one-line summaries of the discussion, and action items at the end. Every action item should have a clear owner and notes of any dependencies, along with any external constraints. For example:

“Investigate why drush is broken.”

is significantly less useful than

“Angus will talk to the multifield maintainer on why drush updatedb broke on the last build. This needs to be fixed before Tuesday so we can do our next production deployment.”

Having action items and clear responsibilities documented solves a whole host of communication problems, while keeping the rest of the team up to date. Reading is so much faster than listening and speaking, so it allows the rest of the team to keep up to date without the same time commitment.

Iteration, Evaluation, and Communication

Standing meetings can be useful to force communication, but beyond daily standups, they should only be used as a last resort. Early in a project they can really help with architectural discovery, or in bootstrapping new teams. As time goes on, standing meetings can often become longer and have more and more people invited to them. It’s important to continually evaluate a meeting, and to willingly burn it to the ground to refocus and rebuild.

Every meeting participant should be empowered to call the existence of a meeting into question. When team members start grumbling about a recurring call, they should be able to discuss their feelings openly and honestly.

Just as we never stop aiming to make ourselves better developers, as teams we must never stop trying to improve and optimize our communication. By following these steps, your teams will be well on the path towards meeting nirvana.

Senior Drupal Architect

Want Andrew Berry to speak at your event? Contact us with the details and we’ll be in touch soon.

Mar 04 2015
Mar 04

Since the last Drupal Core Update, the Seventh Beta of Drupal 8.0 was released (and Drush 7.0.0-alpha9 was released to coincide with it), and Mink and Goutte were added to core to support behavioural testing!

Some other highlights of the month were:

How can I help get Drupal 8 done?

See Help get Drupal 8 released! for updated information on the current state of the release and more information on how you can help.

We're also looking for more contributors to help compile these posts. Contact mparker17 if you'd like to help!

Drupal 8 In Real Life

  • DrupalSouth Melbourne is happening March 5—7 at the Melbourne Convention and Exhibition Centre in Melbourne, Victoria, Australia, featuring sprinting and lots of speakers.
  • DrupalCamp Hyderabad will be on March 7th and 8th in Hyderabad, Telangana, India.
  • DrupalCamp China will be held on March 14th in the famous Pudong district of Shanghai, China, featuring a session on open-source e-commerce by Ryan Szrama, VP of Community Development at Commerce Guys.
  • European Drupal Days will be March 19—21 in Milan, Italy. The 19th will have sessions on Drupal 8 theming, the future of commerce in Drupal 8, #d8rules; the 20th will have workshops on continuous integration, Symfony, dependency injection and theming, and the 21st will be lots of sprinting!
  • MidCamp is coming up on March 19—22 at the University of Illinois in Chicago, Illinois, USA. There will be training, speakers, and lots of sprinting! Tickets are still available, but hurry before they're sold out!

Also, don't forget to vote for your Drupal Association Community Director — voting is open March 9th through 20th!

Whew! That's a wrap!

Do you follow Drupal Planet with devotion, or keep a close eye on the Drupal event calendar, or git pull origin 8.0.x every morning without fail before your coffee? We're looking for more contributors to help compile these posts. You could either take a few hours once every six weeks or so to put together a whole post, or help with one section more regularly. If you'd like to volunteer for helping to draft these posts, please follow the steps here!

Mar 04 2015
Mar 04

Voting for the Drupal Association Board’s Director At Large position opens this Monday, March 9th. My two main reasons for seeking this role, why I feel I am a qualified candidate, and a discussion on the responsibilities of this position are outlined in the following post.

My Main Reasons For Running

First, the “Director At Large” position is representing the whole Drupal Community inside the board. Therefore the person holding the board position should need to know and understand the community in all it’s facets. I believe I am one of those individuals who reaches across a wide spectrum of the community and can offer a higher representation. I help organize DrupalCons and Camps, speak at different Drupal events all over the world, give trainings, along with mentoring new users at sprints. I meet with other CxO’s and interested high level business associates to teach them how to contribute back to Drupal, and still maintain steady code contributions to core via the Drupal 8 Multilingual Initiative and contrib modules.

A Note Regarding Board Responsibilities

One really important piece of information I want to stop and make sure is understood, is what it REALLY means to be on a board of this nature. The Drupal Association Board is a strategic board, meaning the Board defines the strategic direction and policies of the Drupal Association. The execution of these goals is then in the hands of the Executive Director (Holly Ross) and her staff within the Drupal Association. My personal experience with this structure comes from being on the Board of Amazee Labs Zurich, where we define strategies and directions for the CEO. I feel I should explain and offer further definition of the role of a strategic board member. Often on a strategic board you are faced with wonderful ideas you would like to execute immediately or at times even execute yourself as the board. It is important to keep the responsibilities clear however, that you are there as a strategic guide and must let the company executives figure out how best to pursue and execute strategies.

This same distinction of responsibilities applies to the Drupal Association Board, and it’s candidates are signing onto a role within a structured system. The ‘Director at Large’ role gives an insight into the Drupal community’s general needs and stress points. The role does not include actions like the power to give direct orders to Drupal Association staff. While many may understand this distinction, it is important to make sure voters expectations are managed and candidates are reminded what they are stepping forward to take part in. This might sound overly structured (especially for a volunteer based community), but in the end the Drupal Association is a nonprofit with goals and budgets to follow. In fact budgets are more important than many realize. The Drupal Association Board is actually responsible for the financial oversight of the Drupal Association. What does this mean? It translates in legal terms to direct financial responsibility by all board members should the Association financially fault. That responsibility translates to a great deal of deep budgetary spreadsheet analysis conducted by members, both a very important and very tedious task. It’s like the issue queue: Someone has to review the code and mark it RTBC!

Thank you for taking the time to read where I stand on important issues and my public service announcement around what the responsibility of this candidacy truly means. I’m really looking forward to the upcoming vote beginning March 9th and ending March 20th. Until then, I strongly suggest everyone in the community check out all the passionate Drupal candidates keeping in mind not only their vision but experience in this type of role.

Should you have any further questions for me, I will be conducting a Reddit AMA this Thursday March the 5th starting at 5pm CET (11am ET).

Mar 04 2015
Mar 04

INTRODUCTION

The websites we build often require accepting a payment for something that isn't a product. For example, service payments, down payments or donations. There are different ways to handle this with Drupal Commerce and here we’ll outline the method we've adopted for use and explain how to implement it yourself.

CREATE A CUSTOM MODULE

To accept payments of varying amounts in Drupal Commerce you will need a custom line item type as well as a few other customizations. Although you can achieve this with contrib modules like Commerce Custom Line Item Types, we prefer to create our own module that will contain all of the logic needed for our payments. This not only provides a more concise way to achieve our goal, but it also allows us to put all of the pieces needed into one module, which is great for organization.

First, let’s create our custom module. For this example, we’ll call our module custom_commerce. If you’re not familiar with creating a custom module for Drupal yet it’s actually quite easy. There are many resources available to help you get started, our quick start article is Creating a Basic Drupal 7 Module.

Your module will start with the following two files: custom_commerce.info and custom_commerce.module. Please these two files into a folder called customer_commerce.

.INFO file

The .info file should contain something like:

name = Custom Commerce Code
description = Handles varying payments, etc.
core = 7.x
package = Commerce (custom)

dependencies[] = commerce

.MODULE file

The first step is to tell Drupal Commerce about our new, custom line item type. We'll do this by using hook_commerce_line_item_type_info() as shown below. You can adjust the names and description as needed for your situation.

function custom_commerce_commerce_line_item_type_info() {
 
$line_item_types = array();
 
$line_item_types['payment'] = array(
   
'type' => 'payment',
   
'name' => t('Payment'),
   
'description' => t('A payment or Donation'),
   
'product' => TRUE,
   
'add_form_submit_value' => t('Add Payment'),
   
'base' => 'commerce_product_line_item',
  );
  return
$line_item_types;
}
?>

That's all there is to creating a new custom line item type. Once you save this code and enable your new module you will see your new line item type under STORE->CONFIGURATION->LINE ITEM TYPES

Drupal Commerce Donation / Payment Custom Line Item

Now, from the Line Item Types configuration screen, click the Manage Fields link for your new Line Item Type and add a new Decimal type field. You can name this field Donation, Payment, or whatever is relevant for your situation.

Drupal Commerce Donation Payment Line Item Field

CREATE A PRODUCT

Now create a new Commerce "Product" for your Payment or Donation by navigating to STORE->Add a Product. Give your new Product a SKU (such as PAYMENT) a title and a price of $0. After saving your new Product take note of its Product ID number as you'll use this in your custom module below.

Note that you can create a custom product type for your Donations or Payments if you'd like. In our case, we're not selling any products at all so we removed the default Product product type and added a new Payment product type in instead. We then used this new product type to create our Payment product to be used for our payments.

PRODUCT PROCESSING

In this next step, modify (as needed) and add the following code into your custom_commerce.module file. This function is the callback from our second menu item we created. This function is called when our custom Add to Cart form (created in a following step) is submitted. This function will create a new Order object for the current user and then create a new line item in the order using your product and custom line item. It will then direct the user directly to the checkout page.

/*
 * Menu call back to add customer payment amount to cart, create order and direct to checkout
 */
 
function custom_commerce_cart_line_item_add() {
  global
$user;
 
$product_id = 1; // this is the product id number of your payment/donation product
 
if ($product = commerce_product_load($product_id)) {    
   
// Create and save new order object for user
   
$order = commerce_order_new($user->uid, 'checkout_checkout');
   
commerce_order_save($order);           
   
   
// Create a new line item using our custom line item type and attach it to our order
   
$line_item = commerce_product_line_item_new($product, 1, $order->order_id, array(), 'payment'); // "payment" is the name of our custom line item type.
   
commerce_line_item_save($line_item);
   
$line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
   
$line_item_wrapper->field_payment_amount->set($amount);      
   
$line_item_wrapper->save();  
   
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
   
$order_wrapper->commerce_line_items[] = $line_item;          
   
commerce_order_save($order);

   

drupal_set_message('A customer message can be displayed if desired.');   
   
// Redirect to checkout page now
   
drupal_goto('checkout/' . $order->order_id);
  } 
}
?>

Form API

Now we could create a Commerce Display Node to handle the displaying of our Add to Cart form but we're going to create our own form instead using Drupal's Form API (FAPI). This will allow us to have complete control over the Add to Cart form and functionality as well as negating the need for a Node to display our Add to Cart.

The first step is to use hook_menu to create two menu links. Insert code similar to the following into your custom_commerce module. This will create two menu router items. The first one (user/payment) is to display the form. The second (add-payment) is to process the payment/donation. Of course, adjust this code as needed for your situation.

/**
 * Implementation of hook_menu().
 */
function custom_commerce_menu() {
 
$items['user/payment'] = array(
   
'title' => 'Make a payment',
   
'file' => 'custom_commerce_payment.inc',
   
'page callback' => 'drupal_get_form',
   
'page arguments' => array('custom_commerce_payment_form'),
   
'access arguments' => array('access checkout'),
   
'type' => MENU_NORMAL_ITEM,
   ); 
  
$items['add-payment'] = array(
   
'type' => MENU_CALLBACK,  
   
'page callback' => 'custom_commerce_cart_line_item_add',       
   
'access arguments' => array('access checkout'),
  );
  return
$items;
}
?>

Now, create a new file in your custom_commerce module called, custom_commerce_payment.inc. This file will contain your custom Add to Cart form code. In this new file place your form code similar to the following:

function custom_commerce_payment_form($form, &$form_state) { 
 
$form['amount'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Enter Payment Amount'),
   
'#required' => TRUE,
   
'#default_value' => 0, // Add a default value here if desired   
   
'#size' => 20,
   
'#maxlength' => 20,
   
'#attributes'=> array('placeholder' => '$'),
  );
 
 
$form['submit'] = array(
   
'#type' => 'submit',
   
'#value' => 'Proceed to the next step',
  ); 
  return
$form;
}
// Here we'll validate the payment amount. First we'll strip any dollar signs and then make sure the value is a number larger than 0
function custom_commerce_payment_form_validate($form, &$form_state) {
   
$values = $form_state['values'];   
   
$str = str_replace('$', '', $values['amount']);
   
    if (!
is_numeric($str)){
     
form_set_error('amount', 'Please enter a valid payment amount.');
    }
    if (
$str 0){
     
form_set_error('amount', 'Please enter a valid payment amount.');
    }
   
$form_state['values']['amount'] = $str;  
}
// Menu callback to add payment to cart
function custom_commerce_payment_form_submit($form, &$form_state) {    
 
$amount = $form_state['values']['amount']; 
 
drupal_goto('add-payment/' .$amount); // This is our menu callback used to handle the payment
}
?>

There is extensive documentation for Drupal's Form API online. You can use this API to customize your form, validation and submit function as needed for your situation. This will allow you a great amount of control and flexibility over your Payment or Donation's functionality.

RULES

The last step is to create a Rule to Calculate the Sell Price of our new payment or donation. Our new Rule will contain something similar to:

  • EVENT: Calculation the Sell price of a product
  • CONDITION: Entity has field
    • Set the field to the field you created in your Custom Line Type
  • Actions:
    • Calculate a value, using the custom Line Item field times (*) 100 and set the variable name to Result
    • Set the unit price to a specific amount, using the Result variable

We've made an export of our Rule available for download here. You can import and use this Rule on your site if the Custom Line Item Type's payment field name is "field_payment_amount". Otherwise, Rules will give you a validation error when trying to import it.

NOTE:

As of this writing, there is an issue with the latest release of Rules (2.8) that causes the price calculations to fail. You must use the 2.7 version of Rules, or, once released, a version past 2.8 (more info)

PUTTING IT ALL TOGETHER

This may seem a bit complicated but in actuality, once you understand the basics, we were able to use a few lines of code in our custom Drupal module to create a self-contained payment or donation system that allows us complete control over the Add to Cart form and processing logic. Once you've adapted and used the above steps you should now have an Add to Cart form available at the URL you specified in your hook_menu (user/payment). You can adjust this URL as needed, including limiting access. Our completed custom Add to Cart form looks like this:

Drupal Commerce Custom Payment Donation

And clicking the "Next Step" button performs our custom form validation and submit functions, creating the custom line item, adding it to the cart and then redirecting the user to the checkout page. We've also created a one page checkout to make the process as quick and simple as possible for our customers.

Mar 04 2015
Mar 04

We're kicking off a new series on Drupal Multisite, presented by Addison Berry. In this series you'll learn why you might want to create a multisite Drupal installation and how to configure it—from the domain names and Apache virtual hosts side to the Drupal side of your installation. You'll also learn how to use Drush in a multisite context.

This week, we're releasing the first three videos of Working with Drupal Multisite, which will give you an overview of working with multiple Drupal sites and what problems are posed, what needs to happen with the domain names and Apache vhosts file, and how Drupal multisite operates.

Also this week, we're releasing a free video presented by Joe Shindelar about how to install Drush with Composer, which is now the recommended method for installing this handy command line utility for Drupal. Need a primer on Composer? Watch The Wonderful World of Composer here on Drupalize.Me presented by our friends at KnpUniversity. New to the command line or need a refresher? Check out our Command Line Basics series.

Next week, we'll wrap up Working with Drupal Multisite series by walking through a three-site multisite installation for a university site, and learning to work with Drush and multisite. Until then, happy learning!

Mar 04 2015
Mar 04

I want to share some exciting things I'm only just finding out about Platform.sh (the “Develop, Deploy, Rinse, Repeat” continuous delivery cloud platform for Drupal, Symfony and PHP based projects) that look as if they might have a lot to do with folks finding a straightforward way of enabling a truly Lean process applied to website and web application projects. We'll cover five things I didn't know about Platform.sh:

  1. The Standard Platform Workflow is just what modern, serious PHP, Symfony and Drupal developers might expect and can easily be set up for all team members.

  2. The Standard Platform Architecture is container based and scales tremendously well for most use cases.

  3. They don't use Varnish! They use CDNs (content delivery networks)!

  4. There's an Enterprise Platform with its own truly scalable architecture and unique benefits

  5. A chance to get a first-hand report from someone actually using the Platform.sh Enterprise Platform.

1) Standard Platform Workflow

Note: People have been asking me about Platform.sh for some time now. Frankly I haven't had much time to investigate in my usual “put it through its paces and write some articles” fashion. But I did ask Robert for a dev account and got some exposure to a month or so ago. And since then it's popped up a number of times, at DrupalCon Latin America, and since I've been back. I've learned a few things that really got my attention and really want to share, so when Commerce Guys Robert Douglass suggested sponsoring an article to make that happen now, I jumped at the opportunity (disclaimer :) ) .

So what would be the first thing any designer or developer needs to do when they join a team working on a project? Clone the current development branch (called, for example, Sprint 2) and get it working. Well, with the Standard Platform, the first thing you do is just that. And once you do you don't just get the code; you get the whole environment, visible to you as a working site.

And what's the second thing any team member needs to do once they find themselves assigned to any job of work? Well, create a feature branch, get it working, make changes, test them, then sync down changes other developers have made in the meantime before then merging in their own tested changes. Now, with Platform.sh, these are simply basic automated operations that form a natural part of the workflow action repertoire. So, first, when you create that feature branch, a matching environment is automatically created, so as work is performed and changes made, they can be run tested in that self-contained site. Once the work is complete and fully tested, you sync down changes others have made, test again, then merge up your work.

This concept of “sync down” and “merge up” is natural to anyone using development best practices on the basis of a distributed version control system like Git. It has nothing to do with Platform.sh per se. Which is why when you join a team using Platform.sh everything works exactly as modern, serious designers and developers would expect. That's because in Platform.sh you are not limited to any hard-coded scheme created a priori. You create the hierarchy of branches and matching environments as needed, and name them anything you like. When you first create a project, you start off with the master branch, just like on GitHub. The corresponding running environment is what will be the live production site, once it's enabled. But then, in terms of child branches, it's totally up to the team how to proceed. You can create a child branch for each Sprint, and children for each developer, and they can make their own feature, topic and bug fixing branches + environments at will. Or any other scheme that naturally matches your adopted process, or the special characteristics of the project.

Not only that, but the project owner or whoever is managing the project can create different sets of permissions over Platform.sh actions for each branch and their children. Where appropriate, read only permissions could be granted, or full permissions but only on a given sprint branch or only on the individual developer branch under the sprint branches in which they will be participating. It's a very flexible system.

More examples, and the nuts and bolts of how this works and the details of the tools actually used, both on the command line as well as with the Web UI for each team member, can be found in the documentation overview. Plus Ori Pekelman of the Commerce Guys just published this great article How the platform.sh PaaS works. I'm planning on doing more articles on Platform.sh drilling down to a non-trivial level of detail.

One of the main points I was trying to make at my DrupalCon Latin America presentation on Lean DevOps and UX for Drupal development was that Agile and Lean are just words, pure sophistry, when it comes to web development unless the walls isolating the various discipline silos common to it can be broken down and the whole team can work in an atmosphere that encourages constant cross-collaboration. Now, for this to happen, there has to be a real-world and fully functional Lean UX and DevOps process in place. Without a smooth, tailored provisioning process in place for the whole team, there won't really be cross-collaboration. And without continuous build and delivery workflows tailored to special team and project needs, knowledge sharing and constant feedback and frequent user and client validation (without which Lean degenerates to just a buzzword and Waterfall rears its ugly default head) just will not happen. As I say, I plan on testing this all out with real world examples I'll be publishing here, but it does look like Platform.sh goes a long way towards providing all of this right off the shelf, for a variety of (for the present only) PHP based toolstacks (Symfony, Drupal, more on the way).

Apart from the full-stack environment for every Git branch, developers can build sites on the server with a combination of Drush Make and your own custom code using a dedicated REST API and CLI tool support, which also allows for full continuous integration automation. Again, more articles to follow as these features are put through their paces!

2) Scaling with the standard container based architecture

The development process briefly described above certainly sets Platform.sh apart as being different. But what about performance? Well, the architecture is based on micro-containers for each system component. For example, the Http server, a database instance, or in memory object store or Solr, for example, are each micro-containers. This architecture supports very flexible and straightforward scaling by simply plugging in additional micro-containers as needed.

Then, if that proves insufficient, what really sets Platform.sh apart is the option to migrate to an exclusive enterprise architecture (see point 4 for details). While I haven't had a chance to test out the scaling and to carry out tests of my own on Standard Platform performance, Robert also gave me a demo of performance on the enterprise architecture, profiling real-world high traffic sites, all of which gave response times of under one second without exception. To be used when 3 second page loads are unacceptable.

3) CDNs instead of Varnish

To be honest I was really curious about this one. Everyone and his cat uses Varnish. As part of the demo I requested I took the opportunity of asking about this. The explanation I received is that CDN is actually the best choice as HTTP cache, because it is made the port of entry for all requests. Using Cloudflare by default and Fastly in some cases, sub-100 ms speeds are a matter of course, with 45 edge locations all around the world. This is extremely innovative, and I owe it to myself to take a closer look at this one also. The timing is perfect too, what with Varnish putting all of Drupal-land into a tizzy recently when it bifurcated its project into the paid Varnish Plus, on the one hand, and the Community edition (shades of Fedora / Red Hat?), on the other. In any case, the CDN HTTP fronting certainly saves us from the royal pain of setting it up with Drupal, as well as from the high rate of non-trivial anomalies associated with it when it is working.

4) Enterprise platform architecture and benefits

When single-second page loads and true high-availability and Zero-downtime scalability are a must for mission critical sites, we can't go on with business as usual and one size fits all. But as a matter of course. Because in most cases, a costly special custom engineering effort is becomes necessary. Here we are talking about the option of an off-the-shelf true enterprise deployment solution. And before I saw the demo, I truly had no idea such a thing existed.

What I didn't know is that the architecture for Enterprise Platform is not container based at all, since that would simply mean additional and unwarranted overhead and deployment updating, once we are fully aware of the scope of scalability required. As mentioned before, the DNS setup routes all HTTP requests to the CDN being used, from which it is handed off to an Elastic Load Balancer which distributes the traffic after performing a health check on available Nginx/PHP-FPM based Drupal (or other app) instances (three by default). Further load balancing distributes DB queries over three MariaDB instances in the form of a Galera cluster (you learn something new every day: https://mariadb.com/kb/en/mariadb/what-is-mariadb-galera-cluster/). Writes go to a single Master. What's interesting is that all three instances are synchronous Masters, with the Load Balancer electing which instance carries the role of Master in case of failure.

The default of three stack instances can be scaled out to n instances as needed.

From there the architecture is rounded out by a single Solr Cloud and an SSD-based network file system.

And in the demo, I was able to confirm first-hand less-than-a-second page loads on actual running sites.

OK, can't wait to get my hands on that! Large-scale project improvements anybody?

5) First-hand account of what it's like to use the full-support high availability Enterprise platform

The benefits of worry-free seamless scalability, from highly performance container based architecture, to truly high availability enterprise architecture using the same development and deployment platform interface are impressive.

While I was at DrupalCon Latin America I actually got the chance to speak to Yeny Paola Mariño Parra, Systems Manager for Editorial La Patria S.A. in Colombia, who have recently migrated their 3-million page-views a day media-rich online newspaper to the Platform.sh Enterprise Platform. Even though it was made clear from the start that their experience with Platform.sh is only a few months old, she was kind enough to share her experience with me:

“Once the site was developed, it went live on our own dedicated servers. We were satisfied with the results. But we immediately saw we had a problem: We just don't have time to be fiddling with server configurations and scaling problems, and the site was taking up all our time and then some. We needed a quick solution which wasn't going to break our budget,” Yeny explained. “And one of our biggest problem as we searched for solutions was that nobody understood what we were looking for, regular hosting had no special knowledge of Drupal and its specialized needs, and failed to understand the fact that we had an extremely tight schedule as well as a limited budget and a specialized workflow, and that we simply could not be left to our own devices. We needed understanding and technical insight and help. And that is what interested us in Platform.sh.”

What La Patria needed was nothing less than migrating their deployment target to a proper platform that would relieve them of all worry and concern, respect their workflow, and at the same time do it all in a month. And it was nothing less than the Christmas holiday season, and the plan called for them to prepare, migrate, learn how to transplant their editorial workflow and become productive in time for the early January 2015 launch date. Platform.sh understood their situation and made a reasonable proposal that La Patria could grow into as they learned and became familiar with the platform over time. The newly migrated site, and the daily workflow, launched on time.

“The folks at Platform.sh showed superior technical knowledge and understood our special needs and workflow immediately. They gave us excellent advice and provided a support team that also realized on a human level that there were real people behind our project, despite the geographical distance. Real people with a tight schedule, and with limited resources.”

I'm looking forward to checking in with Yeny and the people at La Patria to see how that goes.

Knowing that you have a true high availability enterprise architecture option open and being able to migrate to that option with full support whenever growth makes that necessary will surely bring peace-of-mind to many companies and organizations.

At the risk of repeating myself, I can't wait to try all that out on a project soon.

Please use the hashtag #FiveThingsAboutPlatformSH with any questions or comments!

Bookmark/Search this post with

Mar 04 2015
Mar 04

Checkout part 1 and part 2 for understanding the concept of plugins.
In this installment, we will be

  1. Implementing a new plugin from existing plugin types.
  2. Implementing a new plugin type using the annotation based discovery mechanism.

As an exercise, let's first construct an imaginary scenario where the user of your Drupal site wants choose what they want for breakfast from a list of breakfast menu items. To add a dash of variety, all the breakfast items in the code are of South Indian culinary. You can checkout the code and suit yourself, change the breakfast items etc.

For this exercise, checkout the module code first and enable it.

$ git clone [email protected]:badri/breakfast.git

In order to select their breakfast item of choice, the user needs to be presented with a list of choices in their profile. The lame way is to create a list field in the user profile and add all the breakfast choices. This offers limited functionality and is not pluggable. We can do better than that. So, let's ahead and create a custom field called breakfast choice.

This functionality is there in the custom-field-no-plugin tag of the code you previously checked out. You can switch to that tag by:

$ git checkout -f custom-field-no-plugin

After you enable the breakfast module, go to the user profile and create a new field of type "breakfast choice". As the tag says, we haven't created any custom plugin type yet. But we do create a new plugin from the existing plugin types for our custom field. In fact, we create 3 new plugins(one each for the field type, field formatter and field widget). Our directory structure looks like this:

Custom field

All the breakfast menu items come from a single location, your custom field widget, the BreakfastWidget.php file.

  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $value = isset($items[$delta]->value) ? $items[$delta]->value : '';
      $options = array(
        'idly' => 'Idly',
        'dosa' => 'Dosa',
        'uppuma' => 'Uppuma',
      );

    $element = array(
      '#type' => 'select',
      '#options' => $options,
      '#default_value' => $value,
      '#multiple' => FALSE,
    );

    return array('value' => $element);
  }

Though it works, this is not a good design for 2 reasons:

  1. You are hardcoding in the presentation layer. Widgets define the way you present the input element in a form. You can't define your data there.
  2. It is not pluggable. Other developers have to open BreakfastWidget.php to add new Breakfast items.
  3. It cannot be extended. What if I want to add additional properties to my breakfast items, like images, ingradients or price? I cannot do this in the current setup.

We will address problems 1 and 2 for now. i.e., we add the ability to create new breakfast items outside of the Breakfast Widget file. We make breakfast items "pluggable". Other modules can add new breakfast items it were a plugin, which is exactly what we do next.

To get the plugin version of the module, do:

$ git checkout -f plugin-default-annotation

Now, our directory structure looks like this:

New plugin type structure

The BreakfastPluginManager is, as the name says, a service used to manage various breakfast plugins across modules.
The plugin manager's constructor class deserves some explanation.

  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
    $subdir = 'Plugin/Breakfast';

The $subdir tells the plugin manager where to look for Breakfast plugins in a module.

    $plugin_definition_annotation_name = 'Drupal\Component\Annotation\Plugin';

The $plugin_definition_annotation_name is the namespaced name of the annotation class which is used to annotate all Breakfast plugins. Plugin is the default annotation. We can define custom annotations as well, which will be the subject of the next installment in this series.

    parent::__construct($subdir, $namespaces, $module_handler, $plugin_definition_annotation_name);

    $this->alterInfo('breakfast_info');

    $this->setCacheBackend($cache_backend, 'breakfast_choice');
  }

alterInfo tells us that this plugin definition can be altered by implementing hook_breakfast_info_alter.

Plugin definitions are cached, which is why we need to run drush cr(the equivalent of drush cc all in D8) every time we alter the plugin definitions. The setCacheBackend defines the cache backend for our plugin. In the current context, we are not customizing it too much.

Another major change is the new file breakfast.services.yml. It contains metadata about the breakfast plugin manager service which we discussed above.

services:  
  plugin.manager.breakfast:
    class: Drupal\breakfast\BreakfastPluginManager
    arguments: ['@container.namespaces', '@cache.default', '@language_manager', '@module_handler']

One or more services can be defined in the services.yml file. Each entry contains a machine name of the service, the class that implements the service and dependencies(if any) can be passed as arguments. The @ prefix for the arguments indicates that the corresponding argument is in itself a service.

The field type we added earlier hasn't changed, but the widget has been revamped. We no longer hardcode any breakfast items. Instead, we dynamically pull all plugin instances of type Breakfast.

Here's how:

    $options = array();
    $breakfast_items = \Drupal::service('plugin.manager.breakfast')->getDefinitions();
    foreach($breakfast_items as $plugin_id => $breakfast_item) {
      $options[$plugin_id] = $breakfast_item['label'];
    }

Any module can now define a new breakfast menu item and expect it to show up in the user profile's breakfast field dropdown. We've created 3 breakfast items in our module to illustrate this. Let's pick an example breakfast plugin, my favorite. Masala dosa.

masala dosa pluginImage courtesy

err, I meant:

/**
 * Adds Masala Dosa to your Breakfast menu.
 *
 *
 * @Plugin(
 *   id = "masala_dosa",
 *   label = @Translation("Masala Dosa")
 * )
 */
class MasalaDosa extends PluginBase {  
  // Nothing here yet. Just a placeholder class for a plugin
}

Nothing fancy there. Just a placeholder class and some metadata in the @Plugin annotation.

Phew! It took more time to add a masala dosa plugin that to make a masala dosa. Each breakfast item being a unique plugin instance sounds a bit like an overkill. We will address this and problem #3 detailed above(plugins having different properties like picture) in the next post!

Mar 04 2015
Mar 04

I have been thinking awhile about why the Backdrop fork bothers me so much. At first I thought it would just be the fact that it will be splitting the community some or taking resources away from the Drupal project. But lots of projects I have worked with have been forked in the past, and it is almost aways a good thing, so why would this be different?

Thinking about it more, it dawned on me that Backdrop is the easy way out. People can put all sorts of spin on it, but at the end of the day Backdrop is going to cater to developers who don’t want to learn the new development methods in Drupal 8. I understand that mentality, why learn something new when what you know has served you so well for so long. If you jumped on Drupal at version 5, you have had 8 years where you can build awesome web sites and just learn how to develop things the Drupal way.

The thing is, lots has changed in the last 8 years outside of Drupal. I personally think Drupal 8 is a great thing. It is bringing more modern development practices, like object-oriented programming and test-driven development, into the project. It is also doing this by not reinventing the wheel, but by using an established framework in Symfony These are all really good things, not only for the project, but for Drupal developers as well.

Right now, a Drupal developer who just knows Drupal 7 or earlier has limited job opportunities outside of the Drupal community. If they have not kept up on things like MVC frameworks or how to write tests for code, they are behind a lot of other developers. 1

Letting developers live in this world longer, Backdrop does a disservice by having their skills fall further and further behind. I realize, no one is making anyone use Backdrop but by advertising it as “the comprehensive CMS for small to medium sized businesses and non-profits” and talking about how it is easy to convert from Drupal 7, I feel it is making it too easy to suck developers in without thinking about the potential consequences to their careers.

  1. This is just for back-end development, not front-end coding but some of this applies there too ?
Mar 03 2015
Mar 03

To start..

This tutorial involves hacking core. If you aren't comfortable with doing that, you're probably in the wrong place :).  I created a dropbucket.org drop called Memory profiling in hooks which has all the code details in case you want to dig in yourself.  You'll need to modify includes/module.inc and also have devel module enabled for this to work.

Background

I've been trying to do some low-level tuning while developing a course site in ELMSLN. As part of the project I'm constantly trying to push as many users into one system as I can prior to scaling resources. You can read about past efforts to push drupal core in this and other linked posts: Drupal speed tuning: analyzing and further optimizing Pressflow

Today, I wanted to get a better sense of why a page was taking 17.75megs of ram to render. The better we can understand what's running to accomplish page delivery, the better we can dig in and help drop that number.  The lower that number per page load, the more users we can support on the same resources and the more we can keep costs down while increasing service offering to our users.

Identifying Bottlenecks

Image showing the memory usage of each hook fired in this example drupal page loadAfter applying the code from dropbucket, you'll see something like this whenever you load any page (see right). The hook modification monitors the memory in use at the start and end of every call to module_invoke_all. This tells you how much memory was required to fire off that hook.

It does the same thing for each function invoking that hook and then repeats the same thing for drupal_alter statements as well. This gives you a ton of data to sort through but as you do, you can start to get a clearer picture of both what it takes to deliver the page as well as where bottlenecks in RAM usage might be.

XDebug is a php library that can also be useful for finding bottlenecks if you are interested in digging even deeper. I wanted per page load stats and to start to do so per role so that's why I went the modifying drupal core route (this time).

We know what's bloated, now what?

In my testing I was looking for a few things specifically; what was slow but more importantly, was it anything custom I had written. Because a major library that I use in ELMSLN has a lot of potential performance implications, I was looking for memory usage by functions starting with "cis".

As it turns out, memory usage was pretty low because I followed this great lullabot article by Jeff Eaton while developing the calls that happen quite often. I put in the artificial metric that if it was a function under 50KB I didn't care about it so that I got less data (otherwise you get things that are like 48 bytes all over the place).

I did find a few functions that I need to do some additional tuning on / make decisions about as a result of this test. The functions in question were:

  • book_node_view (584 KB)
  • special_menu_items_init (514 KB)
  • og_context_init (475 KB)
  • context_init (448 KB)
  • token_module_implements_alter (262 KB )
  • feeds_forms (145 KB)
  • regions_page_alter (116 KB)
  • stream_wrappers (115 KB)
  • boxes_page_alter (110 KB)

In total, this is telling me that of my 17.75 MB page load, around 2.7 MBs can be attributed to 9 functions. There are hundreds / thousands of functions that build any given page and now I know that 9 of those account for 15% of the memory required to deliver any given page.

Decisions, decisions

From here, I have some decisions to make now that I have this information. First, I have to look at the low hanging fruit functions that I can get rid of.  Feeds (in the MOOC distribution) is only used to initially import content, after that it's there for convenience but that convenience is apparently (feeds_forms) adding 145 KB to every page for every user regardless of if they are using feeds. That's a bit ridiculous right?  So, when in production, turn off Feeds (or at least I can). We also only user Boxes module for 1 block at the footer of the page; is that really worth having Boxes load on every page for one block to be loaded and be exportable. special_menu_items is used to prettify one menu system, which definitely can't be justified with it's half a meg footprint so it will most likely be dropped from the core supported package.

What can't I really change?

The second decision. Well, all systems in ELMSLN are built on top of Context, OG, Tokens, and (MOOC at least) the Book module. This makes it rather difficult to get rid of og_context, context_init, book_node_view, and token_module_implements_alter.  Steam_wrappers is also something built into core which just takes time to run so I don't have much of a choice there.

I may have to live with book_node_view or look and see if I'm invoking it to load in such a way that it's called when it doesn't have to be. If you look at the API docs, it's basically just adding previous / next navigation to the bottom of pages and styling it. Maybe we can write a custom replacement to cache this call in memory so that after it initially builds previous / next links that it just has access to this data in memory.  It might seem like a lot of effort, but to save .5 megs per page load it could be a big win.

What can I fix without much effort?

regions_page_alter is provided as part of the Regions module, one of my own. I can either fix this or, as we're starting to do in MOOC / the new ELMSLN UX; transition away from it (for the most part). This is something I have total control over though so it might be worth investigating if I can fix it quickly or at least reduce its footprint.  I may also just have to remove some modules like boxes, regions, and feeds which are all sure to drop the page load.

What should I explore "fixing" if its even possible?

Well, my top for calls account for almost 2 megs on every page load, those are obviously where I have to start. The problem I may find though is that Context and OG are heavily used by a ton of people. I doubt I'll find inefficiencies there but it's possible.  Special Menu Items is worth investigation though it might be better served to just remove it from the core package. Book links I already outlined a work around which would be to cache the call to the data needed from it. As book is core and we're this late in the game I'm not going to see a patch accepted to core to fix this in my life time :).

What's 2 megs in the grand scheme of life?

Let's say I have 4 GB of ram on my server, 2 GB set aside for Apache transactions. From there we can do some simple math to see how many concurrent connections we can support. Again, the goal here is do as much as possible with as little as possible (yes pushing this into the cloud / NGINX / advanced caching techniques for auth'ed traffic can drop it even more).

Me logged in

2048 Megs / 17.75 MB/user = 115 users

I'm not the target audience though, so me logged in as a student (when giving the role ability to view devel output)

2048 Megs / 16.75 MB/user = 122 users

Right there, by switching roles and analyzing I was able to drop 1 meg which translated to 7 additional users on the same resources. Now let's factor in a theoretical reduction of that bloated 2.7 MB.

2048 Megs / 14.05 MB/user = 146 users

This is where low level performance tuning can have big impact. If I can clean up just 2.7 megs from the page load this would increase out load potential by 24 users or a 16% gain in scale without actually scaling up our systems.

By tuning for the least common demoninator, when we start to scale up and get into distributed memcache servers or adding a more realistic amount of RAM, these percentages all can add up to a lot more users on a lot less resources. With a theoretical 16 GB of RAM allocated to Apache we could serve 1,166 concurrent users.  As past numbers have shown though, even with 2,200 - 3,500 students a semester, we're never anywhere close to this number of concurrent users.

Mar 03 2015
Mar 03

Knuth is a pretty smart person

A long time ago, in a galaxy right here, Donald Knuth wrote “premature optimization is the root of all evil”. This was in his 1974 paper “Structured Programming With Go To Statements”, yet this issue is still with us in various forms.

Performance optimization is a technique for improving a system’s effectiveness pertaining to running time or memory usage. Optimization should be done after there is a working system which needs its effectiveness improved. If optimization is performed during the initial implementation, it is by definition premature as there is nothing yet to improve.

We encounter this problem regularly because Knuth’s quote is taken out of context. The full quote starts off “Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered.”

In other words, this is not an inherent problem with programming; we actually cause this problem ourselves due to how we think about programming. 

We’re spending precious time needed for optimization and debugging (time that will be needed once the project is completed) at a point in time when we do not have any assurances that the work being done is useful. Furthermore, we can easily make mistakes while optimizing. An optimized system is also more complex to debug and maintain than the same non-optimized system.

The impetus for present rambling

Story time!

Our team recently encountered a quite bothersome performance issue with a client’s site occurring in a system that, given the amount of performance related modules installed, made little sense.

This system was designed and implemented before we ever got to look at it and had been running for some time. These modules were installed for “performance reasons”, according to the documentation: boostadvagg, entitycache, memcache, and CDN. While these modules do all have their place and usefulness, they were mostly not a good fit for this project.

These modules make the system more complex compared to a plain Drupal setup, especially regarding stack tracing and profiling. These modules each implement optimization techniques and all come with side effects which make debugging and maintenance more complex.

It was only after removing almost all of these elements from the system (and still experiencing the performance issue) that a colleague was able to determine that the bottleneck we were looking for was in an area completely unaffected by any of these modules and fix the problem.

In other words, the optimization performed by all of these modules, which were ostensibly installed to deal with performance, was a myth. They were all instances of premature optimization. This site functions well without them, and leaving them in place made discovering the actual performance problem exceedingly difficult.

How to win

In closing, finding the underlying problem was a big improvement for the project, but it should have been a less painful process.

To get to a path to happiness, we all need to recognize our own thoughts that lead to premature optimization while they are happening and avoid acting on them. Once a working system is in place it can be examined using tools designed for the task and then optimization techniques can be applied where they are needed most to ensure the effective operation of the system.

Don't spend time on premature optimization, and actual optimization will cost less. It's a win-win for clients and developers.

Bonus feature: “Stop doing that.” --Douglas Crockford

Premature optimization can also take another slightly less obvious form.

Not performance related at all, and still common, is the desire to write “clever” code or “save keystrokes” by writing expressions very tersely. This is most definitely not what we should be spending time thinking about and yet it does happen (and has spurred endless debate, more wasted time). It is for this reason that I beleive it is imperative to work with a coding standard for your team and stick to it rigourously through peer code reviews (and internalizing the standard as much as possible). Doing so can systematically eradicate this particular form of the problem.

Additional Resources

Code Review for Non-Technical Folks | Mediacurrent Blog Post
Mediacurrent Dropcast, Episode 1 | Podcast

Mar 03 2015
Mar 03

So you are planning to visit LA for DrupalCon? Want to site see or enjoy local flavors but not sure where to focus your efforts? I polled the team at Urban Insight, and we collected ected a few of our own favorites that will, hopefully, become some of your favorites as well.

#10 LA Metro

http://www.metro.net/

First off, lets get you out of your car mobile. The various metro lines (both bus and light rail) give you access to much of the surrounding area. I recommend purchasing a day or week pass and enjoying the freedom of being able to see the many sites LA has to offer. Before you arrive it is best to familiarize yourself with the various http://santamonicapier.org/

What visit to the West Coast would be complete without at least dipping your toes in the sand? The iconic Santa Monica Pier might seem touristy but is still a great spot for sightseeing and shopping.

*While there is no light rail access to Santa Monica yet, it is possible to take the bus (Metro Rapid Line 720) from Downtown to within a couple blocks of the pier.

#8 Shangri-La Hotel

http://www.shangrila-hotel.com/Dining-Nightlife/Suite-700

If you took our advice on #9 and ended up at the Santa Monica Pier, you should certainly enjoy the sunset at the open-air bar and lounge of Shangra-La Hotel's Suite 700.

#7 Griffith Observatory

http://www.griffithobservatory.org/programs/soplanetarium.html

Visit Griffith Observatory to see LA from above or hike the surrounding hills. The planetarium shows are spectacular to check out.

*There is also a free shuttle on the weekends that leaves from the Sunset/Vermont Metro Station that will take you to directly to the observatory.

#6 Olvera Street

http://www.olvera-street.com/

Conveniently, right off Union Station, this is a great place to buy souvenirs and enjoy local restaurants.

*From the 7th Street Metro Center Station take the Red or Purple Line subway to Union Station which is only a couple stops away.

#5 Spring Street Bar

http://springstla.com/

A small downtown hangout whose beer selection is rivaled only by it's hipster-watching potential.

#4 The Getty

http://www.getty.edu/

If you have time to make it across town, the Getty offers not just a world-class collection, but also frequently has bands and other interesting events, including tours about how it was built. If your spouse/kids are coming with you to DrupalCon, the Getty Museum also has a special hands-on area for kids a big grassy hill and great lunch options. You can easily spend the better portion of a day there.

#3 The Original Pantry Cafe

http://www.pantrycafe.com/

Located just a few blocks from the Convention Center, be sure to get up early and enjoy standing in line for some amazing breakfast.

#2 The Standard Hotel

http://www.standardhotels.com/downtown-la

The Standard Hotel in downtown LA has a very swanky pool and bar on the top floor. It's definitely worth a visit after a day at DrupalCon.

#1 Perch

http://perchla.com/

Perch restaurant in downtown LA is set near the top of a hotel, and offers amazing city views and one of the 10 best bars in LA.

Have any other suggestions? Feel free to add them in the comments below.

Mar 03 2015
Mar 03
mike-anello

Are you looking for a job? Have you considered working in the Drupal world?

Several OSTraining members have. They wondered about the skills they would need and the income level they could expect.

To give you an overview of what it takes to make a living in the Drupal world, we spoke with Mike Anello. Mike is a long-time Drupal contributor, based near us in Orlando, Florida. If you've ever seen a Dries keynote address at a Drupal, Mike is often the person asking Dries questions at the end.

One of my key takeaways from talking with Mike -  the Drupal jobs are out there, but companies are now expecting applicants to bring more than just Drupal knowledge.

Getting-a-job-in-Drupal

Welcome Mike. Can you introduce yourself?

I’m the co-founder and vice president of DrupalEasy, a Drupal training and consulting firm based in Central Florida. I specialize in Drupal training and development, and I’ve developed one of the first and longest running long-form Drupal career training programs around. I’ve been one of the main organizers of the Florida Drupal Users' Group and Florida DrupalCamp for over five years, and I help manage the Drupal Association's Community Cultivation Grants program. Also, I just celebrated the 9-year anniversary of my drupal.org user account!

I hear people say there’s a talent shortage in Drupal. Do you think that’s true?

Yes and no. I think there is a senior-level Drupal developer talent shortage - mainly because that’s all that most organizations are looking for. I think the solution to this has to come from both directions: increased training opportunities as well as organizations using Drupal making a concerted effort to develop an internal talent pipeline. Organizations with more than a handful of developers should be focusing on building an internal mechanism to hire junior developer and grow them into more advanced positions. There are plenty of junior-level Drupal developers just looking for the opportunity to contribute to an organization and learn from more seasoned developers. We just need to develop the mechanisms to make it happen.

With many CMS’s, people can build a career from selling products. That’s not really possible in Drupal. What kind of careers are available in Drupal?

Well, I wouldn’t necessarily agree that building a career from selling Drupal products isn’t possible, it just isn’t very common. That being said, there are plenty of careers in the Drupal ecosystem. There’s the obvious ones like site developers and themers, but there’s also project management, performance, content strategy, quality assurance, support, and many, many more.

A couple of years ago we looked at jobs on Drupal.org and found that about 80% of jobs were for developers and only 10% for designers. Do you think it’s still true that developers are still the most likely to find work?

I think that it depends on your definition of the word designer. I think it’s better to talk about front-end versus back-end developers. There’s clearly a renaissance going on in front-end development - one that isn’t limited to the Drupal universe. Take a look at jobs.drupal.org today and I think you’ll find that there’s almost as many positions for front-end developers as there are back-end developers. From my experience, designers that also know how to create a Drupal theme and know modern front-end tools are some of the best-compensated contractors I’ve seen.

I also think that while having strong site-building skills is key to get a developer job in Drupal, it seems like most employers are looking for site-building plus something. Whether that something is coding or data migration or project management or QA or outstanding customer-facing skills or SEO, being more than a one-trick pony can certainly pay off.

If someone is starting from scratch, how long would it take them get employable experience in Drupal?

Well, I’m biased, here, but I think it totally depends on the type of training the person participates in. If they sit at home and read Drupal books and don’t interact with the community, then it could be a very long time. I think that structured long-form training combined with a healthy dose of community involvement is probably the best way to compress the time necessary to be employable. We’ve had students completely new to Drupal take our 12-week Drupal Career Online program and land Drupal contracting jobs almost immediately after graduation. A lot of that depends on the students involvement in the community as well as their networking and sales skills.

What kind of starting salary could a junior Drupal developer expect?

In general, I tell our graduates that if they get a contracting gig right after graduation the minimum hourly rate they should expect in the U.S. is $25 unless there are significant learning and mentoring opportunities as part of the gig. Graduates with more than just site-building skills can (and should) expect more. I think it is safe to say that after 6-12 months of solid experience, the hourly rate should be at least double that.

I think it should also be noted that knowing just Drupal isn’t enough any more. I think it is reasonable for organizations to expect that all levels of Drupal developers have a working knowledge of basic Drush and Git commands.

How do people find Drupal jobs? Do they just visit jobs.drupal.org, or are there other resources?

I feel like this is a softball question! The single best resource I’ve ever known is the Drupal community. Get involved in local meetups, give presentations, position yourself as an expert. The Drupal community is a gift, it’s okay to be a little selfish as long as you’re giving back. We have some great resources on the Drupal Career Resources page at our Career Center for people who are looking to get a better idea of what kinds of opportunities and options a Drupal career has to offer.

Mike's Panel at DrupalCon Austin

Mike was part of a really interesting panel on Drupal careers at DrupalCon Austin last year. The panel was called "Drupal Career Trailhead". If you're interested in this topic, it's well worth watching the following two videos. Here's Part 1 of the panel:

[embedded content]

And here's Part 2 of the panel:

[embedded content]

Mar 03 2015
Mar 03

GTD logoAs many of you know, Global Training Day was this weekend, and it was a great one. We had 29 trainings in 20 countries around the world, showing once again that our community is second to none in passion and enthusiasm.

It's so exciting and humbling to help make GTD a reality. Watching the tweets pour in from around the world is truly awe-inspiring. Here's a selection of a few of our favorites from this year.

For those of you who didn't participate this time around but want to join in next quarter, check our Global Training Day page and sign up to host a training in your community. Again, thank you to everyone who helped make this GTD a reality.

150 new Drupalistas in the last #Drupal Global Trainind Day in Barcelona http://t.co/7nmqhtVPxC . Thanks @DrupalAssoc @lsheydrupal !

— Atenea tech (@ateneatech) March 2, 2015

After 8 hours of #Drupal_Global_Training Days at #EPI Sousse #Tunisia #Drupal #DrupalGTD @lsheydrupal pic.twitter.com/eNhx0g5Bih

— Ward Marzouki (@digitives4ward) February 28, 2015

Drupal Global Training Day concludes at @drupakpakistan #Peshawar #Pakistan #DrupalGTD @lsheydrupal pic.twitter.com/6oS9T1siFF

— Drupak (@drupakpakistan) February 28, 2015
Mar 03 2015
Mar 03

I have settled on using Udemy as my exclusive platform for delivering Drupal education. I'm so excited to start taking advantage of all the great tools the platform offers and I am laying the groundwork for engaging extensively with my students. I've got four challenges I'll be issuing to my students during the month of March, with a prize for each one as well as a Grand Prize at the end. It would be great to have you play along!

Join for free!

56
Mar 03 2015
Mar 03

A review of the open source tools created and/or used by the Drupal development team at Promet Source.

Part I highlighted the challenges of deployments, defined good deployments, and introduced the tools for developing the Promet way. If you haven’t already, you should probably read Part I now.

Part II covered the tools used to set up the framework for developing a Drupal site. These tools download modules, themes, and libraries, place all the pieces in the correct Drupal structure, and create a settings file based on the environment. Check out Part II if you haven’t already.

Part III covers Drupal Drop Ship - a tool for deployment.


What is it?

Drupal Drop Ship “uses (a fork of) kw_manifests to provide a reusable deployment composed of manifests” (from the project README). Under the hood it runs updates, ensures that only the proper modules are enabled, and reverts all features to match the state which was defined in code.

Advantages

Kraftwagen Manifests. “Kraftwagen Manifests is a Drupal module that provides the means to register and execute idempotent migrations” (from the project README). This means that a set of actions (called Manifests in Kraftwagen) should have the same results every time.

Environment variables. Drupal Drop Ship uses environment variables to define behaviors and configuration based on the operating environment (for example, enabling modules that aid development on development environments only). Keeping environment-specific configuration out of code potentially increases security by reducing the amount of sensitive information transferred. Environment variables are also more reliable than using Features to manage environment specific configuration.

Greater standardization. Drupal Drop Ship centrally defines a deployment and prevents developers from using varying deployments across projects. This makes it easier for other developers (or even sysadmins) to jump in and deploy a project they have not worked on before.

Forces smaller, more manageable releases. Drupal Drop Ship performs updates once. This prevents the case where there are so many version changes that performing updates has to happen multiple times. Only running updates once also encourages more frequent updating, which can increase application security and stability. Likewise, feature reversion only happens once and forces a changeset that is small enough for full feature reversion. Smaller, more manageable releases decrease the time necessary to test and actually deploy;  smaller releases also reduce the chance of errors - allowing for a more rapid, “sane” release cycle.


Dependency definition. Since Drupal Drop Ship builds a dependency tree based on the project’s top-level module, feature dependencies must be thought through and clearly defined. Rather than a list of modules to enable (whether programmatically or manually), each feature defines the packages it requires. This makes it easier to identify and uninstall unused modules. In fact, Drupal Drop Ship disables and uninstalls modules not in the dependency tree.

For example, take a feature called Events Calendar that requires Views, Calendar, and the Event content type and is defined as a dependency of the Foo project. If Calendar and the Event content type are only used by Events Calendar and Events Calendar is removed from the Foo dependency list, Calendar and the Event content type will be also be uninstalled without requiring any additional actions.

Conclusion

The Promet Drupal 7 Framework pulls together tools open source tools created and/or used by the Drupal development team at Promet Source. Together, the tools set up the framework for developing a Drupal site and provide a reusable deployment.


You’ve now learned how to develop the “Promet way!” Let nail biting, hair pulling, and obscenity screaming be no more!

Mar 03 2015
Mar 03

The goal of the design brief was to inspire potential visitors, while still informing them of key information and the colorful variety of events on offer. Another goal was to draw attention to other Bath & North East Somerset Council Heritage Services venues on offer. A key design goal was that each venue should have its own distinct look and feel, while still remaining part of a clear family of sites.

Design and Development Collaboration

The project followed a clear Waterfall structure. Responsibility for the project passed from Torchbox to Microserve after the UX and Design phase was marked as complete.

One of the reasons the project was so successful was that Torchbox delivered an in-browser design that provided a reference based on the Drupal StyleGuide module. Because of their static nature, PSD designs frequently lead to a large amount of tweaks and changes at the end of the development process. However, using an in-browser, working design cut down the tweaks and changes required at the end of the design process, as changes could be made on the go.

Six Site Approach

Torchbox’s final solution showcased six similar designs, each made unique by its own branding and colors. Each attraction has its own content administration team and a unique set of features; however, all six websites also share much of the same functionality, which made a Drupal Multisite approach the most sensible option.

The Roman Baths site was the first website to be launched, so by building this with a heavy emphasis on Feature-driven development, deployment to the remaining five websites was much more efficient and painless. Although there was a lot of common functionality, each website had its own specific requirements, so all functionality was built in a modular way to easily allow each site to use only what it requires. This has also allowed each site to be easily scalable at any time the client decides to integrate other functionality used on any of the other websites.

A Heritage Services custom theme was built from the Sasson base theme, with each site using its own sub-theme to apply its own specific branding. This was achieved using SASS color variables and mixins; these were set with fallbacks within the Heritage Services sub-theme, and then variable overrides were set within each site specific theme.

One of the trickier parts of the six-site approach was Events, as each of the websites required the ability to publish its own events and share that information across all six websites. To achieve this, six Feeds were set up to automatically pull all Events published by the other content administrators. Since the content administration teams were concerned about volumes of external events saturating their own site's events, External Events and Events were set up as separate content types to give content administrators finer control over their site's calendars.

Pantheon Enterprise

The original hosting plan for the six websites changed mid-project, so Microserve recommended using their hosting partners Pantheon and their multi-site solution "Pantheon Enterprise" as an alternative.

Pantheon Enterprise provides a separate environment per site and treats each environment as its own ‘container.’ That way, problems on one site never affect all the others. Each environment pulls updates from a single repository, allowing code to be developed, tested and committed through an external Bitbucket repository. The repositories use the Git flow technique before deploying updates in each environment.
In addition to the benefits as described by Pantheon here, Heritage Services benefited from the option to select a different level of hosting for each website, and Microserve was able to set different access restrictions for deployment on each website.

Content Refresh

After Torchbox carried out the UX phase it became clear that a content refresh was needed, since most of the existing content was quite outdated.

One of the largest challenges of this was providing all six content management teams with a method of staging their new content. The project was subject to strict deadlines and both the development team and content administration teams had plenty of work to do. Since the content administration team couldn’t afford to wait until the build had been complete before adding content, we decided to use GatherContent as a staging platform.

GatherContent provides an external platform for content editors to populate, review and approve content without relying on the progress of the website build. Once Torchbox had finished the UX and requirements gathering process, Microserve was able to populate GatherContent with the required content types so that the content administration teams to begin writing. GatherContent provides a Drupal integration module that allows users to easily import and map all content to the content types setup within Drupal.

Though they had heard about the CMS, the Heritage Services content team had never used Drupal before, and one of the initial anxieties within the team was the ease and usability of the final solution. Because the content administrators had spent plenty of time with GatherContent, they found it surprisingly easy to move to Drupal, saying that the interface felt very familiar and similar to GatherContent. This was an added (and unexpected) benefit.

Summary

The project has been a huge success and all parties are thoroughly happy with the end result.

Everybody involved has done a grand job on these sites and the project has been highly successful. We very much appreciate Microserve and Torchbox's professionalism and expertise, and all of our team have found both parties a pleasure to work with!

Patricia Dunlop - Commercial Manager, Heritage Services

Mar 03 2015
Mar 03

Getting started

Luckily, we have only hit a few minor snags in the process so far. For the most part, these first steps in rebuilding our website have been fairly simple, but we will still present them in detail. Any problems we had in this beginning stage were solved relatively easily.

There are a few prerequisite steps you must take to begin working with Drupal 8. We usually use drush and make files to deploy our sites and we want to keep using this method with the new Drupal 8 site too.

Upgrade drush

The first thing we learned was that we had to upgrade our drush to version 7 because only drush 7 is compatible with Drupal 8. It is backward compatible with Drupal 6 and 7 so you can safely upgrade. We found two very helpful articles here and here.

Download Drupal 8

After upgrading drush we created a webroot folder and put in a project-core.make.yml file with the content below:

  1. api: 2
    
  2. core: 8.x
    
  3. projects: 
    
  4.   drupal:
    
  5.     type: "core" 
    
  6.     version: "8.0.0-beta6"
    

Then in terminal just type: drush make project-core.make.yml and it will pull the given version of Drupal 8 to the current directory.

Add Install Profile

We decided to make the Cheppers install profile on the base of the standard profile.

We added a profiles/cheppers folder to the webroot and copied the content of the core/profiles/standard folder to it. The following files were renamed to cheppers:

standard.info.yml ? cheppers.info.yml
standard.install ? cheppers.install
standard.profile ? cheppers.profile

We learned a very important lesson through trial and error after extensive googling with no results. Within the [profile_name].info.yml file add the name of your desired default theme to the themes section. If you don’t do this, your theme will appear among uninstalled themes.
So .info.yml should look like this:

  1. name: Cheppers
    
  2. type: profile
    
  3. description: Install Cheppers site.
    
  4. # version: 8.x-1.x-dev
    
  5. core: 8.x
    
  6. dependencies:
    
  7. (...)
    
  8. themes:
    
  9.   - "your_theme"
    
  10.   - seven
    

Although we wouldn’t do this in a Drupal 7 project, in this case we decided to use the Bartik theme as the starting point for our own custom theme because it is the default theme of Drupal 8 and is guaranteed to follow best practices. In the profiles/cheppers/config/install folder, we renamed all files with the name bartik to our theme and modified their content accordingly.

In system.theme.yml we replaced default theme to ours:

  1. admin: seven
    
  2. default: "your_theme"
    

As a result, while installing your site you will have, besides the minimal and standard profile, an additional option to select.

Create content during install

The configuration files (.yml) do not store content so one of the very first issues we faced was how to create blocks with content during the install process. We needed to solve this because we want to make developers’ collaboration easier by having a fully functional and configured site right after installation.

Initially, we only had vague ideas about a solution but then we have received a tip from Gábor Hojtsy, who sent us this link: http://cgit.drupalcode.org/multilingual_demo/tree/multilingual_demo.install#n306

After that, it was an easy task to accomplish, so thank you to Gábor for the help.

Our first blocks’ aim was to display contact data in the footer. Let’s see how to do that in Drupal 8.

Create block content

In our profile folder we created a content subfolder to keep things together.
In this folder we created the following files:

  • content-block.csv
  1. "Id","yaml","Title","Body","Language"
    
  2. "0","_footer_address","Cheppers address","49 Dessewffy Str.
    Budapest, 1066
    Hungary"
    ,"en"
  3. "1","_footer_email","Cheppers e-mail","info[at]cheppers[dot]com","en"
    
  4. "2","_footer_powered","Cheppers powered by","© Cheppers Ltd. 2015. Powered by "https://www.drupal.org/drupal-8.0"" target=""_blank"">Drupal 8","en"
    

This file stores content for 3 blocks. We could have put it all in one block, but we wanted to make it more flexible.

  • block.block._footer_email.yml
  • block.block._footer_powered.yml
  • block.block._footer_address.yml

block.block._footer_address.yml

  1. langcode: en
    
  2. status: true
    
  3. dependencies:
    
  4.   module:
    
  5.     - block_content
    
  6.   theme:
    
  7.     - ""
    
  8. id: "_footer_address"
    
  9. theme: ""
    
  10. region: footer_cheppers_address
    
  11. weight: -5
    
  12. provider: null
    
  13. plugin: 'block_content:REPLACEME'
    
  14. settings:
    
  15.   id: 'block_content:REPLACEME'
    
  16.   label: 'Footer address'
    
  17.   provider: block_content
    
  18.   label_display: '0'
    
  19.   cache:
    
  20.     max_age: -1
    
  21.     contexts: {  }
    
  22.   status: true
    
  23.   info: ''
    
  24.   view_mode: full
    
  25. visibility: {  }
    

In case you were wondering why there are apostrophes around some values, but not all of them, it is simply because one word values don’t need apostrophes.

As you can see, we set the region to a custom one called footer_cheppers_address because we would like our blocks to be shown in a new custom region. We’ll skip the other two blocks’ .yml files because I’m sure you get the idea, let’s move on instead and add our new regions in the .info.yml file within your theme folder:

.info.yml

  1. name: Cheppers Theme
    
  2. type: theme
    
  3. base theme: classy
    
  4. description: 'A flexible, recolorable theme with many regions and a responsive, mobile-first layout.'
    
  5. package: Cheppers
    
  6. version: 8.x-1.0
    
  7. core: 8.x
    
  8. logo:
    
  9.   logo_path: logo.png
    
  10. libraries:
    
  11.   - "/global-styling"
    
  12. ckeditor_stylesheets:
    
  13.   - css/base/elements.css
    
  14.   - css/base/typography.css
    
  15.   - css/components/captions.css
    
  16.   - css/components/content.css
    
  17.   - css/components/table.css
    
  18. regions:
    
  19.   header: Header
    
  20.   primary_menu: 'Primary menu'
    
  21.   help: Help
    
  22.   content: Content
    
  23.   footer_cheppers_address: 'Footer Cheppers address'
    
  24.   footer_cheppers_email: 'Footer Cheppers email'
    
  25.   footer_message: 'Footer message'
    
  26.   footer_socialmenu: 'Footer social menu'
    

We have added two regions, footer_cheppers_address and footer_cheppers_email. For the block _footer_powered we will simply use the already existing footer_message region. You can, of course, configure this as you wish. It’s just an example of how to add a custom region to your theme.

Ok, so now we have created custom regions for our blocks in the footer. Now, let’s move on to how to modify the .install file in our profiles/ folder in order to add the content to this block during installation.

.install

  1. **
    
  2.  * Implements hook_install().
    
  3.  *
    
  4.  * Perform actions to set up the site for this profile.
    
  5.  *
    
  6.  * @see system_install()
    
  7.  */
    
  8. function your_profile>_install() {
    
  9.   (...)
    
  10.  
    
  11.   // Add custom blocks.
    
  12.  your_profile>_add_blocks_with_contents(__DIR__ .'/content/content-block.csv');
    
  13. }
    

.install::_add_blocks_with_contents

  1. /**
    
  2.  * Adds custom blocks with contents taken from $file_name
    
  3.  *
    
  4.  * @param type $file_name
    
  5.  * The name of .csv file to process
    
  6.  */
    
  7. function your_profile>_add_blocks_with_contents($file_name) { 
    
  8.   /** @var Drupal\block_content\Entity\BlockContent[] $blocks */
    
  9.   $blocks = array();
    
  10.   $keys = (object)array_flip(array('id', 'yaml_file', 'title', 'body', 'lang',));
    
  11.   $yaml_files = array();
    
  12.   $handle = fopen($file_name, 'r');
    
  13.   // Read the first row with column titles.
    
  14.   $line = fgetcsv($handle);
    
  15.   while ($line = fgetcsv($handle)) {
    
  16.     if ($line[$keys->lang] == 'en') {
    
  17.       $item = BlockContent::create(
    
  18.        array(
    
  19.          'info' => $line[$keys->title],
    
  20.          'type' => 'basic',
    
  21.          'body' => array('value' => $line[$keys->body], 'format' => 'restricted_html'),
    
  22.          'langcode' => $line[$keys->lang],
    
  23.        )
    
  24.       );
    
  25.       $item->save();
    
  26.       $blocks[$line[$keys->id]] = $item;
    
  27.       $yaml_files[$line[$keys->id]] = $line[$keys->yaml_file];
    
  28.     }
    
  29.   }
    
  30.   fclose($handle);
    
  31.   // Read block yaml files and add blocks to regions.
    
  32.   your_profile>_add_blocks_to_regions($blocks, $yaml_files);
    
  33. }
    

.install::_add_blocks_to_regions

  1. /**
    
  2.  * Adds blocks to regions defined in yaml_files
    
  3.  *
    
  4.  * @param type $blocks
    
  5.  * @param type $yaml_files
    
  6.  */
    
  7. function your_profile>_add_blocks_to_regions($blocks, $yaml_files = array()) {
    
  8.   // The custom block placements need to be adjusted with the content UUID. 
    
  9.   while (list($block_id, $item) = each($yaml_files)) {
    
  10.     if (isset($blocks[$block_id])) {
    
  11.       $input = __DIR__ . '/content/block.block.' . $item . '.yml';
    
  12.       $yaml = Yaml::parse($input);
    
  13.       $yaml['plugin'] = $yaml['settings']['id'] = 'block_content:' . $blocks[$block_id]->uuid();
    
  14.       $block_placement = Block::create($yaml);
    
  15.       $block_placement->save();
    
  16.     }
    
  17.   }
    
  18. }
    

You can see the result in the next two pictures.

To edit the contents of the blocks we have just created go to admin/structure/block/block-content page and click the [Edit] button.

Create footer menu links

Creating footer menu links is even easier than creating blocks, just add content-menu.csv to the content folder mentioned above and a new function into .install file.

content-menu.csv

  1. Id,Title,Menu,Path,Language,Weight
    
  2. 0,Drupal account,footer,https://www.drupal.org/drupal-8.0,en,20
    
  3. 1,Facebook account,footer,https://www.facebook.com/cheppers.hu?fref=ts,en,30
    
  4. 2,LinkedIn account,footer,http://www.linkedin.com/company/cheppers,en,40
    
  5. 3,Twitter account,footer,https://twitter.com/cheppers,en,50
    
  6. 4,Google+ account,footer,https://plus.google.com/103371252165927373857,en,60
    

.install

  1. /**
    
  2.  * Implements hook_install().
    
  3.  *
    
  4.  * Perform actions to set up the site for this profile.
    
  5.  *
    
  6.  * @see system_install()
    
  7.  */
    
  8. function your_profile>_install() {
    
  9. (...)
    
  10.  // Add footer menu items.
    
  11.  your_profile>_add_footer_menu_items(__DIR__ . '/content/content-menu.csv');
    
  12. }
    

.install::_add_footer_menu_items

  1. /**
    
  2.  * Creates menu items based on the CSV.
    
  3.  *
    
  4.  * @param type $file_name
    
  5.  * The name of CSV file
    
  6.  */
    
  7. function your_profile>_add_footer_menu_items($file_name) {
    
  8.   /** @var \Drupal\menu_link_content\Entity\MenuLinkContent[] $menus */
    
  9.   $menus = array();
    
  10.   $handle = fopen($file_name, 'r');
    
  11.   /** @var \Drupal\Core\Path\PathValidatorInterface $path_validator */
    
  12.   $path_validator = \Drupal::service('path.validator');
    
  13.   $keys = (object)array_flip(array('id', 'title', 'menu', 'path', 'lang', 'weight',));
    
  14.   // Read the column titles.
    
  15.   $line = fgetcsv($handle);
    
  16.   while ($line = fgetcsv($handle)) {
    
  17.     if ($line[$keys->lang] == 'en') {
    
  18.       $route = $path_validator->getUrlIfValid($line[$keys->path]);
    
  19.       // For more parameters see:
    
  20.       // \Drupal\menu_link_content\Entity\MenuLinkContent.php#getPluginDefinition
    
  21.       $item = MenuLinkContent::create(
    
  22.         array(
    
  23.           'title' => $line[$keys->title],
    
  24.           'menu_name' => $line[$keys->menu],
    
  25.           'url' => $line[$keys->path],
    
  26.           'options' => array('target' => '_blank'),
    
  27.           'langcode' => $line[$keys->lang],
    
  28.           'weight' => $line[$keys->weight],
    
  29.           'bundle' => 'menu_link_content'
    
  30.          )
    
  31.       );
    
  32.       $item->save();
    
  33.       $menus[$line[$id]] = $item;
    
  34.     }
    
  35.   }
    
  36.   fclose($handle);
    
  37. }
    

Now you have footer menu links with the content given in your content-menu.csv file:

admin/structure/menu/manage/footer

Did you notice that there is one more link on the footer menu?
The first item, Contact, isn’t in our csv file. By default, the contact module creates this menu item in the footer menu, but what if we need this in the main menu, not the footer menu? Just create a .yml file in your config/install directory with the name:

core.menu.static_menu_link_overrides.yml,

then override menu_name, like this:

  1. definitions:
    
  2.   contact__site_page:
    
  3.     enabled: true
    
  4.     weight: 0
    
  5.     expanded: false
    
  6.     menu_name: main
    
  7.     parent: ''
    

The main achievement of this method is that you can add any new block with content by modifying/adding only .yml files and .csv files.

So far, we have only presented you with the easier parts of this beginning stage. Please share any ideas you might have about how we could have improved our methods, and, of course, questions are always welcome.

Mar 03 2015
Mar 03

TL;DR: Watch the full series here for FREE!

If you're serious about building your Drupal site right, you'll find yourself looking into command line tools like Git and Drush.

If you don't work in the command line on a regular basis, that might be intimidating. Well, not any more!

This series is designed to be a primer on the command line basics, to get you comfortable enough with the command line that you can utilize command line tools without hesitation.

Once you've watched the series, you can move on to the Drush series to improve your Drupal-fu, and will be ready for the upcoming Git series (which will be awesome, by the way!)

When you're ready, you can watch the entire series, for free.

When you do, let me know if you have any questions or comments!

Mar 03 2015
Mar 03

As we announced previously, 4Site has just released HubDub, a Drupal module that leverages the jPlayer framework and Popcorn JS to overlay web content—such as social media, maps, or web forms—directly onto a video as it plays. So... how does it work?

Storing the Data

The Drupal end of HubDub is relatively straightforward. All of the information about a video is stored in a fieldable custom entity, called HubDub Video. Apart from the usual metadata like title, description, author and a unique identifier, what do we need to keep track of? First, we need the location of the video itself. HubDub needs direct access to an M4V video file (or a live RTMP stream), so we store its location in the URL field. A planned enhancement will let this URL be the actual Vimeo (and eventually YouTube) sharing URL, which is a lot easier for end users to find. The module would then parse out the actual video file location.

For each overlay, we need to track the start time, end time, and the content of the overlay. We could have used Drupal’s built-in field types inside a field group for this, but that can get messy for unlimited fields, so we decided to create a custom HubDub Overlay field type. As a former TV engineer, my first instinct was to use something like SMPTE timecode for the time fields. But jPlayer can’t place overlays with anything approaching frame accuracy, so we went with two simple integer fields, representing the elapsed time in seconds since the start of the video. To make it easier to deal with overlays in longer videos, especially now that HubDub supports live RTMP streaming, we’ll probably use a field formatter (such as the HMS Field module) to display these fields in hours:minutes:seconds.

The overlay field is a textarea, using Drupal core’s Filter module to format the text for display. Allowing custom CSS, Javascript, and jQuery inside overlays opens up some awesome possibilities… and also some not-insignificant security issues. So by default we allow only the Filtered HTML text format, but the administrator can change this for trusted users.

Finally, to declutter the edit form, we provide an administrative title for each overlay, and collapse the field by default.

Displaying a Video

Okay, we’ve now got all of the information about a video stored in Drupal’s database. Now how do we display a video? Well, first of all, where do we display it? By using Drupal’s Entity API we get a page display for each video (almost) for free, but we wanted to give site owners the flexibility to place videos wherever they wanted, so automatically creating a block for each video was a no-brainer.

I’ve created lots of blocks in code before, but I’d never done so dynamically for all instances of an entity type before. It was a lot easier than I expected, as I learned from looking through the Views module. In the hook_block_info() implementation I load all the HubDub Video entities, then iterate through them with a foreach and add each video to the array. Then, in the hook_block_view() implementation, it’s just a matter of calling the callback with the right delta. There are still a few to-dos here, namely dealing with entity titles longer than 32 characters, and adding some caching for performance.

The page callback and block callback are almost identical. Pages need a title, so the page callback sets it, then it and the block callback each call the same display function, hubdub_view_video(). That function loads the HubDub Video entity, then dumps all of the metadata fields for that entity into Drupal's Javascript Settings array. Next, it iterates through all the values of the Overlay field and adds each overlay to the Settings array. Then everything gets passed to a theme function, which loads the tpl.php file that contains the div structure that jPlayer needs, and creates a series of hidden divs with the contents of each overlay. Finally, we attach some CSS, and the Javascript, which is where all the real magic happens. Look for a follow-up post in the coming days on the Javascript side of HubDub.

What’s Next?

The initial release of HubDub is our “minimum viable product.” It works, but there’s so much more we have planned. A few of the things on our roadmap:

  • More granular access control for CRUD operations. Right now, all HubDub actions are controlled through one global “administer hubdub” permission. We’ll soon be adding the Drupal standard edit/delete own/any permissions.
  • Support for additional video providers, including YouTube, and non-m4v file formats.
  • Greater cross-browser HTML5 support.
  • Additional jPlayer options, configurable through the admin UI.
  • Media module support.
  • More user-friendly support for skipping to another point in the same video, or branching to another video, from within an overlay.
  • Better support for overlays on live streams. Right now, overlays are timed from the start of playback, but this doesn’t make sense for live streams. We’re considering just using the server time in hours:minutes:seconds, but we’d love to hear potential use cases and their requirements.
  • Eventually, a more user-friendly way of adding overlays. We’re considering a video player on the edit form, with a button in the player controls to add an overlay at the current playback point.

We're eager to hear your feedback! Please post bug reports, feature requests, and support questions in the HubDub issue queue.

We have even more details to share on how HubDub works under the hood, so stay tuned over the coming days. If you'll be attending the Nonprofit Technology Conference next week in Austin, stop by our booth (#214)! We'd love to chat and give you a demo. If you’re interested in a custom HubDub solution, integration with your CRM or AMS, or video production or editing services, please contact us.

Mar 03 2015
Mar 03

Google is trying to make the web faster! Every site owner should be aware on the Google Pagespeed tool (and YSlow) to make sure that the website they are running is as fast as it can be. The optimization tools they offer are great for anyone working with Drupal. But they have taken it one step further by introducing Pagespeed modules for you webserver that does a lot of optimization on the fly. The question is - does it make sense for Drupal?

First off - if you haven't used downloaded Google Pagespeed or YSlow, please do it now. Also run the WebPageTest to see how much you actually can speed up. It will help you find many small optimization tips that you might or not might be able to implement, that all put together will speed up your website with valuable microseconds. You might not think that microseconds matter, but it does, both from conversion rate and SEO point-of-view. If you are running a Drupal Commerce site, the page speed is most likely in direct correlation to your sales.

To help you do many of those optimizations Google also released a Pagespeed module and a, for the time being - free, Pagespeed service that both will help you optimize without having to put to much effort into it. I will take a closer look at the Pagespeed module.

Installation of the Pagespeed module

For all you Apache users out there. Please use Nginx :) But if not - the module is available to install using most famous package managers, so it should be pretty straightforward if you have done a little bit of apt-get or yum before. 

If you are using Nginx though you will have to build it yourself. For some (younger) developers/freelancers this might be a nightmare or even gibberish since you always been used to use package managers. But you should really learning how to build Nginx yourself, and understand what it is you are doing. The reasons for learning this are that you can create an optimized version without modules that you don't need and also with Nginx modules and 3rd party developer modules that are awesome to have. Pagespeed is one of the later.

What does Pagespeed module do?

So what Pagespeed module does is basically that it will interject the page that you are serving and modify it to optimize it for speed. And it does it really fast. Many of the optimizations though can already be done by Drupal and what I'm trying to figure out with this article is if it's worth installing the module or if we are better of with Drupals modules. I will compare the functionality head to head and see where it makes sense to use the Pagespeed module and where it makes sense just to use a contributed module. As I'm writing this though the Pagespeed module is still in beta mode as well as some of the modules, so please take this article for what it is - a snapshot of the current state. It might not be that up-to-date next month.

Note also that it does some other optimization outside of the filters, but I will just focus on the filters in this post.

Comparison between Pagespeed module filters vs. Drupal (contributed) modules?

Add head

This you control via your theme, so it has no usage for you whatsoever as long as you know theming.

Result: Drupal does this already

Add instrumentation

This lets you add controls how fast your page renders. Drupal does not have any tool that I know of that does this, but there exists javascripts that can do this. 

Result: Drupal can't do this (yet)

Async Google Analytics

Just use the Google Analytics module and you will have better control and it does handle Asynchronous load.

Result: Drupal does this better

Canonicalize Javascript Libraries

This makes sure to use external hosted open source javascript libraries when you are hosting them locally. This might not always make sense, but what it will give you is the possibility that someone has a browser cached version of for instance jQuery or Bootstrap, meaning faster load time. It also fetches the correct protocol depending on how your site is loaded (http/https), which can save some time when you load without SSL. JavaScript Libraries module gives you the possibillity somewhat to do this, but it's not as automatic. 

Result: Drupal does this worse

Collapse Whitespace

This removes whitespace that is not needed. Minify module does this better (better as in less bytes).

Result: Drupal does this better

Combine CSS

Drupal does this natively. If you use the module Advanced CSS/JS Aggregation it does it better since it also removes whitespace.

Result: Drupal does this better

Combine Javascripts

Drupal does this natively. If you use the module Advanced CSS/JS Aggregation it does it better since it also removes whitespace and minifies.

Result: Drupal does this better

Combine Heads

I might be oblivious here, but when do you make two

tags? Anyway this is controlled with your normal theme layer.

Result: Drupal does this already

Convert Meta Tags

This takes old style meta tags and make http-equiv attitributes of them. This can be controlled in the theme layers.

Result: Drupal does this already.

Deduplicate Inlined Images

If you don't know what inlined images are I wrote about it. This will take images that are shown multiple times on a page an load it as javascript inline images instead to make the page faster. The problem - when I tried this it didn't work. That's maybe the beta part of it or me not understanding how to implement this.

Result: Drupal does this worse - if the actual Pagespeed filter worked :)

Defer Javascript

This takes a javascript and makes it load after the full page is loaded. The can be done in Drupal with some javascript magic and anyway requires careful planing on what you can load after the page is loaded. AFAIK there does not exist a Drupal module that helps you with this.

Result: Drupal does this already

Elide Attributes

This will remove unnecessary attributes in tags. Click on the link to understand more. This can be done in Drupal, but can be hard to control everywhere so it totally makes sense to use this filter.

Result: Drupal does this already

Extend Cache

This automatically rewrites expiry headers on static files that does not have it. This can be controlled with the webserver. But this Pagespeed filter can even work in tango with webserver so you have automatically on some resources, and manully on the ones that you choose. The only thing Drupal controlls is the header for the PHP content, so it does not concern Drupal so much.

Result: Your webserver can do this already, but it's a nice feature.

Extend Cache PDF

Read above, but for PDF

Result: Your webserver can do this already, but it's a nice feature if you have many PDF's

Flatten CSS imports

This minifies and links together CSS files up to a certain size and puts it inline. This does not really make sense to do since it will take people longer time to see the actual content of your web page. And even though most people claims that this is unlikely to affect SEO, are you willing to take the chance? Anyway, AFAIK this can't be done automagically in Drupal.

Result: Drupal does this worse

Include JavaScript Source Maps

Source Maps is basically a way to keep all the client-side code readable in the same time as you make it performant. This can be done manully in Drupal of course, but is a help of a job. If you use LESS, they are working to support it in a module.

Result: Drupal does this worse

Inline @import to link

This take @import and make it to links. This is to be used together with other filters. Can be done already in Drupal

Result: Drupal does this already

Inline CSS

Similiar to Flatten CSS imports. Does not make sense, but Drupal can't do it.

Result: Drupal does this worse

Inline Google Fonts CSS

Takes the css for Google fonts and inlines them. Something that is imposible to do otherwise. This saves you one call per font.

Result: Drupal does this worse

Inline JavaScript

Similiar to Flatten CSS imports, but for JavaScript. Drupal can't do this.

Result: Drupal does this worse

Inline Preview Images

This takes all images on your page that are inline and large and makes a smaller copy of them that is loaded before the larger copy. Smart as hell. Image Lazyloader can do this.

Result: Drupal does this already

Insert Google Analytics

As written earlier, use Google Analytics module instead.

Result: Drupal does this better

Lazyload Images

This takes all images that is not in the viewport and wait to load them until they are seen. Image Lazyloader module does this already.

Result: Drupal does this already

Local Storage Cache

This takes inline resources and save it to the clients storage using HTML5. This requires Inline CSS and Inline Javascript to be enabled. This filter is experimental, so be careful with it. This can be done in the theme layer in Drupal. Note that this makes the pages slower for browsers not using HTML5.

Result: Drupal does this already

Minify JavaScript

Very basic - it minifies the JavaScript. I compared with Advanced CSS/JS Aggregation and it does it better (fewer bytes). 

Result: Drupal does this better

Move CSS Above Scripts

Does what it says - moves the CSS above the JavaScripts so they are not blocking rendering. Can be done in the theme layer of Drupal.

Result: Drupal does this already

Move CSS to Head

Also does exactly what is says - moves all the CSS inside the

. Can be done in the theme layer in Drupal.

Result: Drupal does this already

Optimize Images

This takes images and checks if they can be optimized and then does it. Fairly simple. ImageCache Actions gives you flexibility to edit images, but it will not always be optimized for size. ImageAPI Optimize does this though.

Result: Drupal does this already

Outline CSS

This does the opposite of inline CSS. This can of course be controlled with hook_css_alter but it's not the simplest of solutions.

Result: Drupal does this already

Outline JavaScript

As the above but for JavaScript - Drupal does this via hook_js_alter, but it's hard to do.

Result: Drupal does this already

Pedantic

Does your page more HTML4 compliant if you only focussed on HTML5. You can do this in the theme layer.

Result: Drupal does this already

Pre-Resolve DNS

Also pretty self-explanatory. Adds headers to pre-resolve the domain names before fetching images etc. Can speed up on hard-to-fetch DNS servers. You can do this in the theme layer.

Result: Drupal does this already

Prioritze Critical CSS

This checks through the webpage and loads all CSS needed for the intial rendering first and then the CSS that is not needed on that specific page. If you are anal retentive you can do this in the theme layer. Don't :)

Result: In theory Drupal does this already

Remove Comments

This removes all inline comments from the code. This can be done in the theme layer. I don't actually know of a module that does this, but it should exist :)

Result: Drupal does this already

Remove quotes

This removes non-essantial quotes from the html to save a few bytes. This can be done in the theme layer.

Result: Drupal does this already

Rewrite CSS

Takes the CSS and minifies it and removes whitespaces. Advanced CSS/JS Aggregation can do this even better.

Result: Drupal does this better

Rewrite Domain

So this tells which domains to do rewrites for and which not. It's only a helper function.

Result: Just helper function

Rewrite Style Attributes

This makes sure to rewrite things that are inside inline style="" arguments as well. Only a helper function

Result: Just helper function

Run Experiments

This enables you to run A/B testing between different filter settings. A/B testing can be done via various modules/JavaScript in Drupal, but of course not on the Pagespeed filters. But I'll say that this is only a helper function as well.

Result: Just helper function

Sprite Images

Awesome filter. Takes all gifs/pngs in CSS and combine them automatically to a spritemap. Spritesheets does this for Drupal.

Result: Drupal does this already

Trim URLs

This takes absolut URL's and make them relative where it's possible. This is done pretty well automatically by the l function in Drupal so you probably don't need this.

Result: Drupal does this already

Conclussions

So basically this rocks! If you take all the places where it says that "Drupal does this already", most of them mean - Drupal does this, but it's a pain in the ass to implement. So unless you really want 100% control of every line of PHP code on your site (Why did you choose Drupal then?), it totally makes sense to run the Pagespeed module on your server.

Also note that since the modules are written in a compiled language it will of course do anything that Drupal can do, but faster.

There are some exemptions though being:

  • Use Google Analytics module instead of the Analytics filter. It gives much more control.
  • Between Advanced CSS/JS Aggregation module and the filters it's a tight race depending on your needs. The Drupal module is easier to implement though.

Anyway the Pagespeed module is still in beta so be a little bit careful with it, but if you dare - use it with Drupal!

The top picture was shot by Eric Fisher and is shown under CC 2.0 License.

Mar 03 2015
Mar 03

Google is trying to make the web faster! Every site owner should be aware off the Google Pagespeed tool (and YSlow) to make sure that the website they are running is as fast as it can be. The optimization tools they offer are great for anyone working with Drupal. But Google have taken it one step further by introducing Google Pagespeed module for you webserver that does a lot of optimization on the fly. The question is - does it make sense for Drupal?

First off - if you haven't downloaded Google Pagespeed or YSlow, please do it now. Also run the WebPageTest to see how much you actually can speed up. It will help you find many small optimization tips that you might or not might be able to implement, that all put together will speed up your website with valuable microseconds. You might not think that microseconds matter, but it does, both from conversion rate and SEO point-of-view. If you are running a Drupal Commerce site, the page speed is most likely in direct correlation to your sales.

To help you do many of those optimizations Google also released a Pagespeed module and a, for the time being - free, Pagespeed service that both will help you optimize without having to put to much effort into it. I will take a closer look at the Google Pagespeed module.

Installation of the Pagespeed module

For all you Apache users out there. Please use Nginx :) But if not - the module is available to install using most famous package managers, so it should be pretty straightforward if you have done a little bit of apt-get or yum before. 

If you are using Nginx though you will have to build it yourself. For some (younger) developers/freelancers this might be a nightmare or even gibberish since you always been used to use package managers. But you should really start learning how to build Nginx yourself, and understand what it is you are doing. The reasons for learning this are that you can create an optimized version without modules that you don't need and also with Nginx modules and 3rd party developer modules that are awesome to have. Pagespeed is one of the later.

What does Pagespeed module do?

So what Pagespeed module does is basically that it will interject the page that you are serving and modify it to optimize it for speed. And it does it really fast. Many of the optimizations though can already be done by Drupal and what I'm trying to figure out with this article is if it's worth installing the module or if we are better of with Drupals modules. I will compare the functionality head to head and see where it makes sense to use the Pagespeed module and where it makes sense just to use a contributed module. As I'm writing this though the Pagespeed module is still in beta mode as well as some of the modules, so please take this article for what it is - a snapshot of the current state. It might not be that up-to-date next month.

Note also that it does some other optimization outside of the filters, but I will just focus on the filters in this post.

Comparison between Pagespeed module filters vs. Drupal (contributed) modules?

Add head

This you control via your theme, so it has no usage for you whatsoever as long as you know theming.

Result: Drupal does this already

Add instrumentation

This lets you add controls how fast your page renders. Drupal does not have any tool that I know of that does this, but there exists javascripts that can do this. 

Result: Drupal can't do this (yet)

Async Google Analytics

Just use the Google Analytics module and you will have better control and it does handle Asynchronous load.

Result: Drupal does this better

Canonicalize Javascript Libraries

This makes sure to use external hosted open source javascript libraries when you are hosting them locally. This might not always make sense, but what it will give you is the possibility that someone has a browser cached version of for instance jQuery or Bootstrap, meaning faster load time. It also fetches the correct protocol depending on how your site is loaded (http/https), which can save some time when you load without SSL. JavaScript Libraries module gives you the possibillity somewhat to do this, but it's not as automatic. 

Result: Drupal does this worse

Collapse Whitespace

This removes whitespace that is not needed. Minify module does this better (better as in less bytes).

Result: Drupal does this better

Combine CSS

Drupal does this natively. If you use the module Advanced CSS/JS Aggregation it does it better since it also removes whitespace.

Result: Drupal does this better

Combine Javascripts

Drupal does this natively. If you use the module Advanced CSS/JS Aggregation it does it better since it also removes whitespace and minifies.

Result: Drupal does this better

Combine Heads

I might be oblivious here, but when do you make two

tags? Anyway this is controlled with your normal theme layer.

Result: Drupal does this already

Convert Meta Tags

This takes old style meta tags and make http-equiv attitributes of them. This can be controlled in the theme layers.

Result: Drupal does this already.

Deduplicate Inlined Images

If you don't know what inlined images are I wrote about it. This will take images that are shown multiple times on a page an load it as javascript inline images instead to make the page faster. The problem - when I tried this it didn't work. That's maybe the beta part of it or me not understanding how to implement this.

Result: Drupal does this worse - if the actual Pagespeed filter worked :)

Defer Javascript

This takes a javascript and makes it load after the full page is loaded. The can be done in Drupal with some javascript magic and anyway requires careful planing on what you can load after the page is loaded. AFAIK there does not exist a Drupal module that helps you with this.

Result: Drupal does this already

Elide Attributes

This will remove unnecessary attributes in tags. Click on the link to understand more. This can be done in Drupal, but can be hard to control everywhere so it totally makes sense to use this filter.

Result: Drupal does this already

Extend Cache

This automatically rewrites expiry headers on static files that does not have it. This can be controlled with the webserver. But this Pagespeed filter can even work in tango with webserver so you have automatically on some resources, and manully on the ones that you choose. The only thing Drupal controlls is the header for the PHP content, so it does not concern Drupal so much.

Result: Your webserver can do this already, but it's a nice feature.

Extend Cache PDF

Read above, but for PDF

Result: Your webserver can do this already, but it's a nice feature if you have many PDF's

Flatten CSS imports

This minifies and links together CSS files up to a certain size and puts it inline. This does not really make sense to do since it will take people longer time to see the actual content of your web page. And even though most people claims that this is unlikely to affect SEO, are you willing to take the chance? Anyway, AFAIK this can't be done automagically in Drupal.

Result: Drupal does this worse

Include JavaScript Source Maps

Source Maps is basically a way to keep all the client-side code readable in the same time as you make it performant. This can be done manully in Drupal of course, but is a help of a job. If you use LESS, they are working to support it in a module.

Result: Drupal does this worse

Inline @import to link

This take @import and make it to links. This is to be used together with other filters. Can be done already in Drupal

Result: Drupal does this already

Inline CSS

Similiar to Flatten CSS imports. Does not make sense, but Drupal can't do it.

Result: Drupal does this worse

Inline Google Fonts CSS

Takes the css for Google fonts and inlines them. Something that is imposible to do otherwise. This saves you one call per font.

Result: Drupal does this worse

Inline JavaScript

Similiar to Flatten CSS imports, but for JavaScript. Drupal can't do this.

Result: Drupal does this worse

Inline Preview Images

This takes all images on your page that are inline and large and makes a smaller copy of them that is loaded before the larger copy. Smart as hell. Image Lazyloader can do this.

Result: Drupal does this already

Insert Google Analytics

As written earlier, use Google Analytics module instead.

Result: Drupal does this better

Lazyload Images

This takes all images that is not in the viewport and wait to load them until they are seen. Image Lazyloader module does this already.

Result: Drupal does this already

Local Storage Cache

This takes inline resources and save it to the clients storage using HTML5. This requires Inline CSS and Inline Javascript to be enabled. This filter is experimental, so be careful with it. This can be done in the theme layer in Drupal. Note that this makes the pages slower for browsers not using HTML5.

Result: Drupal does this already

Minify JavaScript

Very basic - it minifies the JavaScript. I compared with Advanced CSS/JS Aggregation and it does it better (fewer bytes). 

Result: Drupal does this better

Move CSS Above Scripts

Does what it says - moves the CSS above the JavaScripts so they are not blocking rendering. Can be done in the theme layer of Drupal.

Result: Drupal does this already

Move CSS to Head

Also does exactly what is says - moves all the CSS inside the

. Can be done in the theme layer in Drupal.

Result: Drupal does this already

Optimize Images

This takes images and checks if they can be optimized and then does it. Fairly simple. ImageCache Actions gives you flexibility to edit images, but it will not always be optimized for size. ImageAPI Optimize does this though.

Result: Drupal does this already

Outline CSS

This does the opposite of inline CSS. This can of course be controlled with hook_css_alter but it's not the simplest of solutions.

Result: Drupal does this already

Outline JavaScript

As the above but for JavaScript - Drupal does this via hook_js_alter, but it's hard to do.

Result: Drupal does this already

Pedantic

Does your page more HTML4 compliant if you only focussed on HTML5. You can do this in the theme layer.

Result: Drupal does this already

Pre-Resolve DNS

Also pretty self-explanatory. Adds headers to pre-resolve the domain names before fetching images etc. Can speed up on hard-to-fetch DNS servers. You can do this in the theme layer.

Result: Drupal does this already

Prioritze Critical CSS

This checks through the webpage and loads all CSS needed for the intial rendering first and then the CSS that is not needed on that specific page. If you are anal retentive you can do this in the theme layer. Don't :)

Result: In theory Drupal does this already

Remove Comments

This removes all inline comments from the code. This can be done in the theme layer. I don't actually know of a module that does this, but it should exist :)

Result: Drupal does this already

Remove quotes

This removes non-essantial quotes from the html to save a few bytes. This can be done in the theme layer.

Result: Drupal does this already

Rewrite CSS

Takes the CSS and minifies it and removes whitespaces. Advanced CSS/JS Aggregation can do this even better.

Result: Drupal does this better

Rewrite Domain

So this tells which domains to do rewrites for and which not. It's only a helper function.

Result: Just helper function

Rewrite Style Attributes

This makes sure to rewrite things that are inside inline style="" arguments as well. Only a helper function

Result: Just helper function

Run Experiments

This enables you to run A/B testing between different filter settings. A/B testing can be done via various modules/JavaScript in Drupal, but of course not on the Pagespeed filters. But I'll say that this is only a helper function as well.

Result: Just helper function

Sprite Images

Awesome filter. Takes all gifs/pngs in CSS and combine them automatically to a spritemap. Spritesheets does this for Drupal.

Result: Drupal does this already

Trim URLs

This takes absolut URL's and make them relative where it's possible. This is done pretty well automatically by the l function in Drupal so you probably don't need this.

Result: Drupal does this already

Conclussions

So basically this rocks! If you take all the places where it says that "Drupal does this already", most of them basically mean - Drupal does this, but it's a pain in the ass to implement. So unless you really want 100% control of every line of PHP code on your site (Why did you choose Drupal then?), it totally makes sense to run the Pagespeed module on your server.

Also note that since the Google Pagespeed module is written in a compiled language it will of course do anything that Drupal/PHP can do, but much faster.

There are some exemptions though - mainly being:

  • Use Google Analytics module instead of the Analytics filter. It gives much more control.
  • Between Advanced CSS/JS Aggregation module and the filters it's a tight race depending on your needs. The Drupal module is easier to implement though.

Anyway the Pagespeed module is still in beta so be a little bit careful with it, but if you dare - use it with Drupal!

The top picture was shot by Eric Fisher and is shown under CC 2.0 License.

Mar 03 2015
Mar 03

1. Service links module

Service links module simplifies attaching additional social links or javascript buttons into the content. It grants advantages to the developers who can add more buttons and rearrange them. It is created on Drupal and for Drupal so that doesn’t include any commercials or spyware.

It supports a wide range of services: del.icio.us, Digg, Facebook/Facebook Share/Facebook Like, Furl, Google Bookmark/Google Plus One, IceRocket, LinkedIn/LinkedIn button counter, MySpace, Newsvine, Reddit, StumbleUpon, Technorati, Twitter/Twitterwidget, Yahoo Bookmark and many others. It also supports various language collections: Basque, Dutch, Farsi, German, Hungarian, Italian, Polish, Russian, Spanish and Swedish.

Some additional features could be found in module’s extended version.

The module is able:

  • to display the links as text or image;
  • to be displayed in view mode, user roles, content type or taxonomy;
  • to sort the services;
  • to display chosen icons in different folders;
  • to add bookmarks in different browsers (Firefox, IE, Opera, Chrome);
  • to support short links;
  • to support widgets;
  • to change the style of links;
  • to display the tag of header as a link;
  • to display links as XHTML code;
  • to support Sprite icons (via Links Sprites plugin).

Set it up:

Drupal versions support: 4.6.x, 4.7.x, 5.x, 6.x, 7.x.

The module: https://www.drupal.org/project/service_links

The settings: http://servicelinks.altervista.org/?q=about

Translation into Ukrainian is inavailable.

After installation enable the module and select the “service” option.

To configure it go to Home > Administration > Configuration > Web services and choose the data you need.

Example: Service Links Drupal module

2. ShareBar module

This module allows including to website the floating block with Facebook, Twitter and Google+ share buttons. The module includes possibility to attach the following social buttons: Twitter, Facebook Like and Share Button, LinkedIn, Google+, Reddit, StumbleUpon, Digg, Dzone, DesignFloat, share via Email option and many others.

Working with this module you will be able to:

  • add, edit or remove any social media buttons. You can add small or large buttons (small ones could be moved under the title of node in case if the page size is less than X and this option is enabled);
  • set it up for IE exclusively;
  • add switchers for enabling and disabling the Sharebar for any content type available at your Drupal website (blogs, articles etc.);
  • choose certain display options (display resized buttons horizontally if the page is less then X pixels wide; display the buttons regardless of the page width);
  • move the buttons to the left, right or up according to the position order.

Set it up:

Drupal versions support: 6.x, 7.x, 8.x.

Download the module: https://www.drupal.org/project/sharebar

To configure it go to Home > Administration > Configuration > Sharebar and select the actions you need.

ShareBar Drupal module

3. Easy Social module

This module allows adding the social media like and share buttons to certain document. Having them you can add or share this document via your social networks. Twitter, Facebook, Google+ and LinkedIn are available by default. You can add more having edited the template.

You can add those buttons to any content type, comment or Views field or add your own custom buttons.

Set it up:

Drupal versions support: 6.x, 7.x, 8.x.

Download the module: https://www.drupal.org/project/easy_social

Read the documentation: https://www.drupal.org/node/1347350

Requirements: Variable module.

To enable display of the buttons at content pages or comments, choose correspondent option at content type editing page (go to “Easy social Settings” tab).

Example: Easy Social Drupal module

4. Social media presence On The Web module

This module allows creating the block with popular social media icons. Having clicked the icon, user is redirected to the link you have set.

Includes the icons for Twitter, Facebook, Pinterest, Google+, YouTube, Flickr, MySpace, LinkedIn, Delicious, FriendFeed, iTunes, RSS.

The module allows displaying the most popular social media, but the icons won’t appear unless you set their address. You can apply the changes on the module setting page.

Drupal version support: 6.x, 7.x, 8.x.

Download the module: https://www.drupal.org/project/on_the_web

Read the documentation: http://cgit.drupalcode.org/on_the_web/tree/README.txt?id=HEAD

Settings: Admin > Structure > Blocks Adding the links to the icons: Admin > Configure > Web services > On the Web.

Social Presence on the web Drupal module

5. Social Media Links Block

The module allows creating and configuring the block displaying the links (icons) to your pages on the most popular social networking services. Using this module you can also add “Subscribe” functional to your website. You can make it accessible for registered users only (they would also be able to configure this block in their profiles).

Supports a wide range of social networks by default: Facebook, Twitter, Youtube, Google+ and many others.

The module provides extended configuration options for icons and their size, supports panels. You can make changes right in the block itself or in the interface. New social media or icons can be added via hooks.

Drupal version support: 7.x, 8.x.

Download the module: https://www.drupal.org/project/social_media_links

It is partially translated into Ukrainian.

To configure it go to Admin > Structure > Blocks.

Example:

Social Media Links Block Drupal module

6. FB likebox

The module provides integration with Facebook like page. It is a social plugin attracting Facebook users. It encourages them to like your website.

The module indicates how many users like the page, allows reading the newest posts of the page and liking them without redirecting the user to his Facebook page. The users with admin access rights can set different Facebook attributes in the block settings.

Set it up:

Drupal version support: 6.x, 7.x, 8.x.

Download the module: https://www.drupal.org/project/fb_likebox

Read the documentation: https://www.drupal.org/node/1285218

To configure it go to Admin > Structure > Blocks > “Theme” > Configure.

FB likebox Drupal module

7. Twitter module

Allows integrating the website API with Twitter microblogging and similar API-compatible variants. It allows users to attach one or few Twitter accounts with user’s account in Drupal. After that it shows their tweets in a side bar of a block and in user’s profile. You would be able to tweet to your account or other ones anytime, when the users create new material.

Set it up:

Drupal versions support: 5.x, 6.x, 7.x, 8.x.

Download the module: https://www.drupal.org/project/twitter

Read documentation: https://www.drupal.org/node/430658

Requires OAuth module installation to connect to Twitter API.

Twitter Drupal module

Soon we will share some more Drupal modules for social media integration!
Mar 03 2015
Mar 03

I gave a talk at Drupal Camp London this year, focusing on the UX of CMS users a.k.a the forgottten Drupal user. Below are the slides and a few notes to accompany them.

Things to consider

When creating a new site user experience is usually focused on the end users, their goals and tasks. This is evident from the vast popularity of the topic as well as the number of software and tools available to aid this purpose (such as eye tracking software, user testing labs etc). Often CMS users are left with only the basic tools to manage their site. A few simple modifications and modules can be used to make their job quicker and easier.

The first thing to consider is who will be using the site. Are they a single user, a group of people, do they work alone or as part of a team. This will affect how the site is used and interactions should be accounted for.

The next step is what. What do they need to achieve on a daily, weekly or monthly basis? What do they want to get out of the site? Tasks that need to be performed frequently should be the easiest or else they simply won’t be done as often as they should, or even worse, at all.

The third thing to consider is the priority of the site to the user(s). If managing or using the site is only a small part of their role it’s more likely to be neglected if tasks are difficult to accomplish. On the other hand if the website is their only task and it’s difficult to use they’ll dread each time they’ll need to log in.

Theme and navigation

My personal go-to theme is Adminimal, giving users a cleaner, clearer experience with subtle changes across the site such as colouring buttons, highlighting tables and making important text stand out more. Check out the theme for yourself here: http://adminimal.netsite.gr

Replacing Drupals core toolbar with Navbar is an infinite improvement. Responsive out of the box it allows navigation on tablets and mobiles to be a breeze meaning that updating configuration or content whilst away from a desk is more likely to be done.

Content Management

The most basic need to CMS users is to manage their content overview page. Admin views makes use of views and vbo to override the default overview to allow filtering/searching and retain the mass action functionality. Being a view it’s easily configured to suit the needs of the person/company. As a bonus it also overrides the overview pages of comments and people.

Another option is Workbench. A better (imo) version of the core dashboard screen it provides configurable views on a summary page. The views can be modified or removed/added to using the available workbench hooks.

With the addition of Workbench Moderation content can be revisioned and placed in various states before being published. States and transitions can be modified and it’s all based on permissions and roles meaning you can have as much or as little power as you need. The CMS user will be able to see clearly what state content is at and modify it easily by viewing the content itself or the overview page.

Webforms

Webform is a widely used module and there’s a few additional modules that allow you to extend it further.

Default fields allows you to set up default fields per webform enabled content type, meaning that a CMS user doesn’t need to create needed fields each time – perfect for event or other sign up forms.

Options element makes creating select lists easier, stripping the need to enter keys and separating out each option into its own text field.

A spam filter, such as honeypot, saves the user time having to delete any results that would otherwise clog up the system. There are of course other options for helping with spam, honeypot is simply my preferred choice.

Using hook_webform_select_options_info the default select lists available can be added to, including any taxonomies on the site.

File Management

This is one area Drupal has always struggled with. Adding the media module means you can reuse files that have been uploaded elsewhere around the site. An overview page is added allowing users to mass delete media as needed as well as bulk upload files. It's by no means perfect, but it's a great step forward for file management in Drupal.

Fields

Entering content can be a time consuming task, a few tips to help users out.

Select lists

With select lists there are a wide range of options, I've written about a few of my favourites before, below is a short summary of each.

Multiselect changes the standard dropdown into two boxes, with selected options appearing on the right. Options can be moved by double clicking or by selecting and clicking the arrow button(s).

Term reference tree has a butt load of options, including being able to force the user to only select child elements, select parents automatically when child terms are selected. This works fantastically for nested trees.

Select with style gives a visual edge to select lists, and can include custom images and css.

Simple hierarchical select There are fewer options available, but allows users the option to create new terms as well as force selection of only child terms. 

Images

As well as using media a couple of additional ways of helping users is allowing them to crop images after they’ve been uploaded. A good comparison list can be seen online. Focal point provides a way for you to change the automatic focus of Drupals core cropping. Uploading multiple images at once is also a great time saver and can be done with an imagefield widget.

Other fields

A few additional options including setting up conditional fields. This allows the user to only see the fields they need to, making forms look cleaner.

Gmap allows the user to pick co-ords from a map, using for geo-location modules.

Linkit is great for linking to internal content, allowing the user to search for content on the site.

One of the most basic things you can do is include help text! Clearly informing the user what content you expect them to enter and how can save a great deal of headaches later on.

Additional modules and tips

A few others shared modules and tips they had for improving the experience of CMS users.

Paragraphs allows users to create blocks of content, selecting types of content along the way.

Beautytips moves help descriptions into mouse overs helping to make forms look cleaner.

Field groups allows you to place forms in collapsible groups that can be hidden and shown as needed, meaning you can initially hide fields that are infrequently changed.

A similar session covered this topic before, Tasty Backend had other tips on improving the lives of CMS users with an excellent write-up by Vicky Teinaki.

The end bit

I'd like to thank those that came and the people that tweeted nice things. If you have any experience, help or advice to share please do! Until next time.

Mar 02 2015
Mar 02

For cause-driven organizations, a website is a place to highlight impact, share resources, and build support. While a blog or brochure site can achieve some of these goals, it rarely does it all. Unfortunately, we all too often find organizations confined by the free and low-cost online platforms accessible to them. With that in mind, we’ve built OpenAid. It’s a free and open-source website starter kit developed for nonprofits and grassroots organizations. Its feature set is robust, its architecture flexible, and it can be installed in minutes.

We worked with activists, community organizers, and aid workers to build a platform that serves their organizations’ needs. Here are some of the features we’ve built to allow groups to inspire and connect with others on a scale that truly reflects their impact in the world.

  • Project mapping. Each project or program you add to the site is displayed on dynamic maps, allowing users to see the full scope of your work. Because OpenAid is flexible, you can easily adjust a project to instead be a city or chapter and still take advantage of all of the mapping features.
  • Blog and news. There are subtle but important differences between a News section and a blog, so we decided to build both for ultimate flexibility. Associate authors with your posts to create dynamic profile pages and allow users to track their favorite writer’s work. Reference a project with a post and it will display on a project’s page, creating almost a mini website for that project.
  • Resource library. Share the resources you’ve created with the rest of the world in an easy-to-find way. We’ve added metadata fields such as Resource Type and Topics and provided a filter set and search interface to allow users to quickly discover the tools and materials relevant to them, even if your library has grown to hundreds of documents.
  • Image galleries. Pictures are key to telling your stories and connecting with your supporters. Associate a gallery with one or more projects to highlight events, volunteers, and initiatives specific to that project’s work.
  • Beautiful, responsive design. Design is important and we want your website to look great regardless of device. A color picker allows you to easily adapt OpenAid to reflect your organization’s identity. We’ve also developed it with flexibility in mind so if you add new pages to the site or add fields to a content type, your site will retain that same great look and feel.

You can dig further into OpenAid’s feature set by spinning up a free sandbox site on Pantheon. Or download the distribution at https://drupal.org/project/openaid to install on any server. If you have further questions or would like assistance getting set up with OpenAid, feel free to reach out to me at [email protected].

Mar 02 2015
Mar 02

Last week was awesome, sort of. I hit all the numbers on my guide launch I was hoping for, and then promptly got the stomach flu. After two years (lots of running in circles) of working through this process of launching I did it!

Now it could have just been being sick, but I ended the launch wanting something more. And the reality is this isn't the first time I've been down after a success.

Does that ever happen to you? You get so excited about something and launch it? Then the next day you wonder if you could have done better, or you aren't sure where to go next. It's happened with our clients, we work so hard, we push the code, we launch on time, and then the question of "Now what?" lingers.

So since I have been applying pragmatism to all sorts of problems, here is my solution to dealing with the post launch lows.

Take a little bit of time making your post-launch strategy, preferably before the launch. Having a place to land your feet is critical to keeping the momentum that comes with a deadline and a launch.

In web there's a lot of ways you can handle this, retainers, maintenance plans, continuous integration testing and plans. Whatever works for your client's needs, but whatever you do, don't leave them hanging.

Sure party, sleep, take a break and enjoy the moment of the launch. But know what comes next, what is the content creation pattern, the maintenance schedule, what tests do we run in the future etc. I have a full IceBox list to pull from, but having to dos setup specifically for the day after would have helped make today easier.

The things to make your list should cut down future relaunching costs, and make it easier for you to maintain clients, and for them to maintain their value to their customers and users. The bonus of this is with retainers and continuous integration plans, you are able to keep some cashflow coming in and not be so in trouble with big projects fade away. Planning for the post-launch is definitely going to a part of any consulting that we offer in the future.

Like all good plans it takes some prior planning and setup work to do it well. Do you have post-launch plans for your clients? What do they look like?

Mar 02 2015
Mar 02

This year in Los Angeles, the Higher Ed Summit will be part of the official DrupalCon program for the first time. Along with the Business and Community Summits, the Higher Ed Summit will meet on Monday, May 11.

Drupal summits for higher education, and education in general, are not new. Around 170 of us from 51 colleges and universities gathered for a pre-DrupalCon summit last year at the University of Texas at Austin. We also met for an Education Unconference back in 2012 before DrupalCon Denver. These summits are mainstays at some of the larger DrupalCamps too, such as BADCamp and NYC Camp. Format

We will start with a panel presentation and learn how some of our peers are using Drupal at their institutions. We’ll then break off into small group discussions for the rest of the day. Discussion topics will be decided as the Summit approaches, but will likely include tips for training content editors, managing campus-wide Drupal installations, and maintaining brand consistency across sites. There will also be ample time for BoF-style breakouts. Lunch and snacks will be provided.

Audience

The Higher Ed Summit is intended for anyone who uses Drupal in the context of a college, university, or other post-secondary institution. All skill levels and roles are welcome. You’ll meet site builders, developers, themers, project managers, support specialists, and more.

Register

Although the Higher Ed Summit is part of the DrupalCon program, it (along with the other Summits) is a separate event and requires a separate registration. On your registration form, there is a section to select which topics pique your interest most, as well as an “Other” field where you can -- and should! -- suggest any other topics about which you are interested.

We are looking for folks to serve as topic facilitators, so if there are any topics about which you would feel comfortable leading a discussion (either among the topics listed on the registration form, or those you suggest yourself), please note that on your registration form. Don’t be shy!

A note about ticket price...

Those of you who have attended other higher education Drupal summits have probably noticed that there is a ticket price attached to this event while the others are usually free, or very low cost.

While we wish we could offer everyone a free ticket, there are operational costs associated with including the Summit in the official DrupalCon program and the convenience of meeting at the Convention Center. We hope the price will not dissuade you from coming to what is certain to be an informative, inspiring -- and fun -- event!

Mar 02 2015
Mar 02

Huh? What are we Electing?

In case you missed it, the Drupal community electing one candidate to serve a two-year term on the Drupal Association Board of Directors. There are two At-Large (community elected) seats on the Board. The other seat is currently held by Matthew Saunders. We've got a really global slate of candidates to consider, and we encourage you to get to know them by listening to the Meet the Candidates sessions and asking them questions on their candidate profile pages. 

Who can vote?

Voting is open to all individuals who have a Drupal.org account by the time nominations opened and who have logged in at least once in the past year. These individuals' accounts will be added to the voters list on association.drupal.org and they will have access to the voting.

To vote, you will rank candidates in order of your preference (1st, 2nd, 3rd, etc.). The results will be calculated using an "instant runoff" method. For an accessible explanation of how instant runoff vote tabulation works, see videos linked in this discussion.

Elections process

Voting will be held from 9 March, 2015 through 20 March, 2015. During this period, you can review and comment on candidate profiles on assoc.drupal.org and engage all candidates through posting to the Drupal Association group. We'll also be scheduling and announcing three phone-in all candidates meetings, where community members and candidates can ask questions and get to know each other.

Have questions? Please contact Drupal Association Executive Director Holly Ross. Many thanks to nedjo for pioneering this process and documenting it so well in the past!

Flickr photo: Kodak Views

Mar 02 2015
Mar 02

The Features module helps address the shortcoming in Drupal 7 of how to manage and deploy site configuration data.  There are times when you need to change a Feature.  The Features Override module can help with this, but sometimes doesn’t solve the problem completely.  In this article I will discuss all the different ways to override your Features and the common problems associated with that.  While this has been an issue for years, it’s become more common recently with the advent of Distributions such as Open Atrium and Panopoly which heavily use Features and which expect the users to upgrade to new versions.  Maintaining your site customizations when upgrading a distribution using Features Override has become a more common need.

The Problem

How do I override configuration from an existing Feature  within my site-specific project?

Solutions

Cloning the base module (not recommended)

If you need to make extensive changes you might need to clone the base module and then customize it.  Disable the original module, uninstall it, then enable your site-specific module.

Pros Cons
  1. You have full control over all aspects of the original module.
  2. Keeps the overrides nicely separate in their own modules that can be enabled/disabled/deployed.
  3. The original Features will never be shown “overridden” (because the original is uninstalled!)
  1. Any future bug fixes, improvements, updates to the original module will not be available.
  2. Since future security patches to the original module won’t be available, this might add a security risk to the project or force maintainers to monitor the original module for updates and apply them to the cloned version.

Using settings.php

If you just need to change a variable (from variable_get) you can do this via the $conf[] array in your site settings.php file.  This method is typically used for environment-specific settings, such as databases, search servers, caching settings, etc.  You can also set the $conf[] array within a custom module if you need to deploy the change across all your environment.  Avoid using variable_set() to change the variable since that will update the database directly as mentioned below.

Pros Cons
  1. The original feature containing the variable (via Strongarm) won’t be marked as “overridden”
  1. Only works for Variables (Strongarm Features)
  2. settings.php not typically part of the code repo, so need to ensure it is version controlled some other way.
  3. Sometimes developers forget to check settings.php for variable overrides, making ongoing support tricky.
  4. Best for Environment variables rather than for any generic Drupal variable.

Update the Database directly

You can create an update hook, or other Drupal hook (hook_enable, hook_install) and update the database directly via SQL or other API functions.  For variables you can use variable_set() to save the new value to the database.  This is only recommended as the last resort for configuration not supported by Features Override.

If you must update the database directly, be sure to only do it once and not in a hook such as hook_init that runs with each page load.  Updating the database on each page load can kill the performance of your site.  With variable_set() you can do this by first calling variable_get() and only saving the value if it needs to be changed.

Pros Cons
  1. Sometimes it’s the only way.
  2. Can keep the overrides separate in their own modules
  3. Only applies specific changes and allows future updates to the base Feature to be used.
  1. Reverting the base feature will change the database back to it’s original value, forcing you to re-run whatever SQL is needed to override it. Can be alleviated by Locking the original base Feature to prevent any reverts.
  2. If the original feature is locked, future bug fixes or improvements might not be available.
  3. The original feature will always be marked as “overridden”.
  4. Some configuration is not stored in the DB, such as Views (or other ctools-based components like Panels) that exist purely in code.

Implement an “alter hook” in code

Most configuration has some sort of “alter” hook that allows it to be modified after it is loaded from the database.  For example, Views calls hook_views_default_views_alter(&$data) to allow you to change any part of a view, whether that view comes from the DB or is in code.  You can create a custom module that implements the desired alter hooks and override the data directly.

Pros Cons
  1. Base Feature will not be marked as “overridden”.
  2. Keeps the overrides nicely separate in their own modules that can be enabled/disabled/deployed.
  3. Only applies specific changes and allows future updates to the base Feature to be used.
  1. Not all configuration has the needed hooks.
  2. Each component has a different hook name and different data structure to modify.

Use Features Overrides module

Similar to the above “Implement alter hook” the Features Override module is designed to create the alter hook implementations for you and export those as new Features modules that you can enable, disable, deploy.

Pros Cons
  1. Base Feature will not be marked as “overridden”.
  2. Keeps the overrides nicely separate in their own modules.
  3. Only applies specific changes and allows future updates to the base Feature to be used.
  4. Features Overrides does the work of figuring out which alter hooks can be used and how to override the data.
  5. Provides a UI for inspecting overrides.
  6. Allows an entire component to be altered (e.g. entire view), or just a single change (e.g. just the title of a view)
  7. Works properly with Features. An Override is just another Feature module on the site.
  1. Not all configuration has the needed hooks.
  2. Can be tricky to “override an override”.

Typical Problems

Feature is stuck at being “overridden”

The most common difficulty is a base Feature marked as “overridden” that does not go away when the feature is reverted.  ”Overridden” simply means that the value of the configuration stored in the DB is different from what is stored in the exported Feature code file.  Features literally re-generates the feature export internally from the DB and compares the code with what is stored on disk.  Doing a “drush fd featurename” simply shows the code diff between the code stored on disk (shown in red) with the code generated from the current database (shown in green).

To determine if a Feature is overridden, Features actually takes the generated code, sanitizes it, sorts it, executes it, and then does an md5 checksum on it.  If the two checksum values are different, the Feature is marked as “overridden”.  However, the “drush fd featurename” command shows the actual code difference regardless of if it’s marked as “overridden”.

This behavior means that “drush fd” might output code differences that actually don’t cause the feature to be overridden.  For example, if you change the order of dependencies in your module.info file and then run “drush fd” on the feature, you’ll see it display those changes, even though a “drush fl” won’t show the feature as overridden.

This makes it difficult sometimes to debug why a feature is overridden, since not all of the output of “drush fd” is relevant.  You need to look for actual value changes, rather than just re-ordering changes.

Adding a new module

Sometimes, just enabling a new contrib module will cause your Features (especially field features) to be “overridden”.  If the new module adds some new settings, formatters, widgets, etc then these settings will be active in the DB but not reflected in the code.  So the Feature will be shown overridden.  Reverting the feature won’t have any affect because there is no way to remove the new settings from the DB without uninstalling the new module.

These kinds of overrides are annoying, but not actually that important.  They don’t prevent the feature from being reverted when a new version of the base module is released.  They are not caused by any site-specific change that would be lost by a revert.  Typically it’s best to just document these cases and leave them as overridden.  Just be careful to not become complacent and make a site customization in the future to the same feature and then ignore that it’s overridden and lose your changes when you revert.  You should periodically do a “drush fd” on overridden features just to be sure what is shown is still just from the new module you installed.

A disabled module

Similar to the above, but the opposite case.  If you have disabled a module that was used when the original Feature was exported, then the code might have settings for that module that are no longer in your database.  Once again you won’t be able to remove this by reverting.  Again, you can just document these cases.  But make sure you really need to have the module disabled.  Having a module enabled that you are not using is not a big performance impact.  The time saved in long-term maintenance of the site it typically more important than worrying about an extra module.

A bad override

If you have used some of the not-recommended approaches for overriding a base Feature, such as writing directly to the DB, then you will end up with an overridden feature that cannot be reverted.  Or if the Feature is reverted, you might lose the change that was written to the DB and need to reapply it.  Even if the Feature is locked to prevent reverting, it will still be listed as overridden.

Another type of “bad override” is using the wrong kind of alter-hook to try to modify configuration.  If the alter hook is called in a way that makes it look like a DB change to Features, then Features is going to see a difference between the DB and code and mark it as overridden.

Overridden Views and Panels

Some modules, such as Views and Panels have their own “override” functionality.  These “pure” Features can exist purely in code with nothing in the DB.  When you make a UI change to a View, it gets copied from the code into the DB and your change is made to the DB.  The View is then marked as “overrides code” in the Views listing.  A View that came from code can be “reverted” within the Views UI.  This essentially just deletes the version of the view in the DB so that the code takes affect again.

Sometimes you can get a View stored in the DB that still matches the code.  For example, you change a View in the UI (causing it to be copied to the DB), then you edit the View and undo the change.  Now it matches the code again, but the view is still in the DB.  In this case, the View Feature will not be shown as “overridden”, but in the Views listing it will still say “overrides code”.

When changing a pure Feature like a View via code (like in an alter hook), your changes will take affect immediately, or possible after a cache clear.  No revert will be necessary because there is nothing in the DB to update.  However, in the above case where you have changed a view and then changed it back so it’s stored in the DB, changing the code will not affect the View until you revert the Feature to remove the DB copy of the old view.

In general, if you are having issues with Views, Panels, or other ctools-like pure Features, make sure they are not overridden in their respective UIs.  For example, click the Revert option for the View within the Views listing to ensure it’s actually using the View stored in code.

Wrong version of Features

If the code in the Feature was exported using a different version of Features than what is on your site, there might be changes that cause overrides.  Ensure your version of Features matches the version used to generate the export.  This usually only applies to major version numbers and is not normally a problem.  Normally updates to the Features module are made in backwards-compatible ways to prevent this.  But certainly be sure your version of Features on your site is not older than the version that generated the base code.  Always try the latest version of Features to see if it helps.

Nobody should be using the 1.x branch of Features anymore.  There is no reason for this.  All Drupal 7 sites should be on the 2.x branch.

Unsupported Component

As mentioned, not all configuration components support Features Override, or only support it partially.  For example, Panelizer works with Features, but doesn’t work well with Features Override because it still depends on the specific order of items in it’s config array and when the alter-hook generated by Features Override tries to change something, that array order might not be preserved.  Sometimes in this case you can create your own alter-hook implementation that overrides the code properly.

This might also be an opportunity to help improve Features Override or suggest patches to the module in charge of the configuration to better support Features Override.

Living with Overrides

What if you have tried all of this advice and your Feature is still marked as overridden?  And what if this override represents a specific site change that you need to maintain and ensure never gets reverted?  The solution to this is to “lock” your feature component.  Go to the Structure/Features page and select the Feature that is marked as overridden.  Click the small “lock” icon next to the overridden component in the right column.  The component will still be listed as “overridden” but when you revert your Features the locked component will be skipped, ensuring that your customization remains in place.

When locking your Features, try to only lock the specific component rather than locking the entire Feature.  The downside to locking a component is that any changes to that component from a new version of your distribution won’t take affect.  This is similar to the consequences of the “Update the Database directly” option listed above.  However, sometimes this is the only alternative.

Conclusion

Just keep in mind that both Features and Features Override are just implementing hooks (normal hooks for Features, alter-hooks for Features Override) that are exposed by Drupal or contrib module.  If those hooks don’t exist or don’t work properly there isn’t much Features or Features Override can do about it.  Drupal 7 doesn’t have any sort of configuration management in core, so every contrib module does it differently.  ctools-based modules have more of a standard framework, as does entity API.  Features itself tries to add code to handle core components such as Fields, Content Types, etc that don’t have the needed hooks.  But there is often a limit to how much Features can do and just patching stuff into the DB is not usually a good solution.

Don’t “hate” Features or Features Override.  Life was much worse without them.  They are the best solution to solving configuration management problems in Drupal 7.  They have been developed over years of experience.  Try to help improve them before trying to implement your own configuration or override architecture.

Drupal 8

Don’t count on Drupal 8 magically solving all of these issues.  The Configuration Management Initiative (CMI) within Drupal 8 was focused on handling site configuration, but not on “bundling functionality”.  It provides an API, storage mechanism, and framework for deploying configuration.  CMI helps a lot, but there are still issues around around component granularity and overriding configuration.  In Drupal 8, configuration is owned by the site rather than owned by a module.   This will make bundling functionality (ala Features original intent) more difficult.  We will be working on Features for D8 soon, but this is still mostly unknown territory.  For now, take a look at some existing modules such as config_packager and config_devel.

I’ve submitted a session to DrupalCon Los Angeles on Features in Drupal 8.  Add a comment and support!

Mar 02 2015
Mar 02

The monthly Drupal core bug fix release window is scheduled for this Wednesday. Unfortunately, due to travel, work, and various other scheduling issues, I was not able to find the time to volunteer to get a Drupal 7 release together for this month. There are also a number of important Drupal 7 patches in development that could probably use another month before they are ready.

Since there hasn't been a bug fix release of Drupal 7 since November, the hope is to get one out in the April release window instead.

Upcoming release windows include:

  • Wednesday, March 18 (security release window)
  • Wednesday, April 1 (bug fix release window)

For more information on Drupal core release windows, see the documentation on release timing and security releases, and the discussion that led to this policy being implemented.

Mar 02 2015
Mar 02

Stephanie El HajjIt is with a happy and heavy heart that I share with you the next step in my journey. After three great years, I am leaving the Drupal Association and packing up my worldly possessions and heading south to Texas, where I will be joining the awesome Austin team of Amazee Labs.

My last three years at the Drupal Association have been incredibly rewarding. I’ve learned so much from each of my (many) DrupalCon teams in Denver, Munich, Sydney, Portland, Prague, Austin, and Amsterdam.

To my Los Angeles and Barcelona teams, I’m sorry to leave you mid-planning, but I’m very excited to see where you take DrupalCon this year without me.

To my DrupalCon globals, thank you for helping grow DrupalCon into what it is today.

To the Portland Drupal community, thank you for being welcoming. Thanks for all the beer and pizza and letting me co-work with you at the Lucky Lab.

To all my volunteers, speakers, sprinters, and trainers, it has been a pleasure to work with you. The community is lucky to have such active, dedicated contributors.

To my colleagues at the Drupal Association, you guys are so weird. Seriously. And I’m going to miss you all dearly.

This may be an end but it’s not THE end. I plan to remain active in the Drupal community, and will be at DrupalCon Los Angeles and DrupalCon Barcelona, as well as MidCamp and possibly LinuxFestNW this year. I hope to see you there!

Cheers,
Stephanie El-Hajj
twitter, drupal.org, irc: stephelhajj
LinkedIn: https://www.linkedin.com/in/stephelhajj

Mar 02 2015
Mar 02

Subtitle: Why I'm Encouraging the Drupal Community to Support the IndieGoGo Campaign Posted by Fellow Drupaler Andy Laken Helping a Brave Girl Overcome Addiction. 


When I saw Andy's post about his sister-in-law on Facebook a few nights ago, my heart was immediately moved. I only know the brief summary he explains in his IndieGoGo campaign post, but I knew it was something I HAD ot get behind. Moreover, I had to jump in and see it through. We can't expect Andy and his wife to do it all and carry the full brunt of this load. THIS is where crowdfunding really really shines! :-)

The fact is that many of us are doing swimmingly well with our Drupal careers and our Drupal businesses. For many of us, Drupal has opened up a world of opportunity where demand is high and the supply is low. This is the very recipe for high billable rates. Every year I do my taxes I am faced with the sheer volume of plane tickets, taxis, hotels, & restaurant charges I have racked up. It IS a good, if not hectic, life! :-)


Now turn your attention to the opportunity that we all have to help change the life of a young girl, Carmen, who is taking extraordinary steps to do the right thing. We have 5 days to hit this very small goal. Frankly I'd like to see us double it, but that is up to you.

https://life.indiegogo.com/fundraisers/help-carmen-get-a-fresh-start/x/5200252 

Mar 02 2015
Mar 02
BeachsidePaul's picture

I hope the Camp is actually on April 11 not March 8 :-)

mherchel's picture

Yep! I derped by copying last year's post and not updating it properly :)

Pages