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 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

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 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 :)

Mar 02 2015
Mar 02

During DrupalCamp London I met with Adam Hill and Michael Schmid who are both nominees in the forthcoming Drupal Association At-Large Board Elections.

They took time out to explain to me why it is crucial we all get involved and vote between 9-20 March.

[embedded content]

The At Large Members serve a vital role in providing representation of the community in the Drupal Association Board. As such it is important we all take time to review the candidates and come 9th March vote for our preferred nominee. To help you decide it is worth watching videos of interviews with all the candidates, available on The Drupal Association website.

Mar 02 2015
Mar 02

In a recent project, I had the opportunity to explore the world of REST web services with Drupal 7. It was a really good experience. I used a couple of modules such as "Services" and "Services Views". It took quite some time to configure the settings and end points to get it in views display.

I am glad to say that REST Export is easier to use with Views in Drupal 8. This is because modules such as "RESTful Web Services" and "Serialization" come under a package called "WEB SERVICES" in Drupal 8 core (Views module comes integrated with Drupal 8 core).  

In this article, I will demonstrate how to use REST Export with Views in Drupal 8. We are going to export the "Article" Content type through REST Export within views in Drupal 8. To achieve this, make sure you have content with the Article content type. 

1. Install/Enable the modules

Search for RESTful Web Services in Drupal 8

Click "Manage" in the administration menu bar and click "Extend". 

Once you are on the Modules page, search for "RESTful Web Services" and "Serialization". Enable both these modules.

Enable RESTful Web Services Module

2. Create the REST EXPORT views

Once the module installation is done, click "Structure" on the administration menu:

Click Structure

Then click "Views":

Go to Views

Click "Add new view": 

Add new view

Fill in the form as shown in the screenshot below. I have given the view name as "Article REST Export". Choose "Article" as the content type from the dropdown. Tick the box against "Provide a REST export" under "REST export settings".

Now you have to provide a link under "REST export path". This link is the end point from where you want to fetch the data. Here, in our example, we are going to create the path "rest/export/json/article". 

REST Export path

Click "Save and edit" and you will see the following page.Click "Settings" next to "Format:Serializer". You will get the option to choose the format of output data at the given end point "rest/export/json/article". 

Format Serializer Settings

Tick the box against “json” since the data will be in json format. Click “Apply”. Finally, save the view by clicking the "Save" button.

Set json value

Once you saved the view, you can test the end point using any REST client. Here, we are using "Advanced REST client", an extension of Google Chrome browser. For installing this, type in "https://chrome.google.com/webstore/category/apps" in your Google Chrome browser. Search for "rest client" as shown in the image below. You will find "Advanced REST client". Click "FREE" to install the application. 

Install Advanced REST client from chrome store

After installing the rest client, go to the path "chrome://apps/" on your Google Chrome browser or click the "Apps" icon on the bookmarks bar of your Google-Chrome browser. Then select the "Advanced REST client" application.

Select Advanced REST client

In "Advanced REST client", we need to provide the path of the end point. Here our path is “http://localhost/rest/export/json/article”. Select "GET" and click "Send" as shown in the following picture.

Provide path and select GET

After you send the request, you will get a response "Status Code: 200 - OK", which is a standard response for successful HTTP requests. This is how the successful response looks:

Status Code: 200 - OK

Final output

Mar 02 2015
Mar 02

In a previous article I showed you how to use the usort() and uasort() PHP functions to sort some more complex data using a comparator callback function. How cool was that?

Although powerful, this technique is quite restricting though because all the logic for the sorting happens inside the comparator function. In other words, you cannot pass parameters to this callback except for the actual default values that are being compared. So what's the problem with this?

Say you have an array of objects that have a name property that can be retrieved by a getName() getter method. And let's say they also have an address property retrieved by getAddress(). And you have a listing of this data and you need to allow for sorting by any of these properties both ASC and DESC. And forget for one second about the possibility of ordering them as they come out of your data store.

Implementing this with just the default usort() function means you will need 4 different comparer functions (one for each combination of property and sort direction). And what if you want to add more columns to the listing? Oh no..

As you can imagine, the solution to this problem is having a dynamic sorting function (or method in a class) to which you can pass the items to be sorted, the property by which to sort and the direction of sort. And then not have to worry about creating all these ridiculous comparer functions. So how might this look like?

function sortByObjectProps(&$items, $method, $order) {
  if ( ! is_array($items)) {
    return false;
  }

  return usort($items, function($a, $b) use ($method, $order){
    $cmp = strcmp($a->$method(), $b->$method());
    return $order === 'asc' ? $cmp : -$cmp;
  });
}

So what happens here? First of all, $items is passed by reference so we don't need to return it. The return value will just be a boolean indicating the success or failure of the sort. Additionally, we pass the method name that retrieves the property value ($method) and the direction of the sort ($order).

Then we run usort() on the items but - and here is the kicker - with an anonymous function that can use the passed in method and order values. Then it's just a matter of comparing the return values of the getter methods and negate the integer if the order is DESC. Pretty cool no?

So now you can have as many columns as you need and get them sorted in both directions. And obviously even more complex stuff.

Hope this helps.

Mar 01 2015
Mar 01

DCLondon-2015-01#DCLondon 2015 was nothing short of Epic, Drupal Camp London has in its own right become a mini-Con, with community members flying in from not only across Europe but the US, India, Australia and New Zealand it is hard to call it just a London camp!

London is the centre of the multiverse!
Drupal Camp London 2015It was awesome catching up with old friends, some new ones and finding an engaging audience for my session on using Empathy maps, content touch point analysis to develop a robust content strategy.

Bummed about not being able to catchup with everyone though!!

I’d like to reiterate my two asks from the community this March:

1) Like, Follow and spread the word on Bringing Peace Through Prosperity, it goes hand in glove with our activist nature and desire to make this rock a better place today, tomorrow and beyond.

2) Drupal Camp Tunis needs our support to bring their local community into the wider fold, the organisers at DCTunis are looking for speakers and support.

And a HUGE thank you to everyone who attended my session…

See y’all at the next Camp!
Mar 01 2015
Mar 01
[embedded content]

Graphics in the Terminal, for you geeking pleasure

If you're excited about this, you are most likely a developer - so here's the code.

If this data looks familiar to you, it might be because it's the same data you see via Hedley's Angular client.

Same data pulled into an Angular app

The demo is heavily based on the blessed-contrib repository by Yaron Naveh, with some notable changes:

  • No dummy data! All the data that you see in the terminal is real, and is being pulled from a real Drupal server with the data exposed via RESTful.
  • We are using RamdaJs to iterate over the arrays and objects (This repository was a good excuse to practice our functional Javascript).
  • Inquirer library was used to gather the data from the user.

By default, the demo uses the Hedley demo hosted on Pantheon, but you can easily yo hedley on your local, and set the URL to your local server. This will also let you change the geolocation of the events and see them change on the map in real-time!

So What?

Honestly, I don't know. Are there real life uses for such a dashboard? Maybe. All I know is that exercises like that help re-think our solutions. For us web developers, consuming the data not by a browser surely opens the door for some radical new solutions.

Mar 01 2015
Mar 01

This article is part of the Deploying Drupal Like a Pro series.

Application Files and Content Files

If you have just started playing with Drupal you will have something like this in your site's directory structure:

sites/all/default/files

sites/all/default/files/temp

sites/all/default/files/private

Do you recognize those paths? If so, you are either using symbolic links, or you have not correctly deployed your Drupal application. And that goes for all size and kind of projects.

To start with, you must know that every web application's files can be splited into two basic categories: application and contents.

Application files:

  • They are usually backed by a source control, so if something happens to them in your production environment (not a good thing...) you are fully insured.
  • They do not change frequently, and when they do, it happens in a controlled manner.
  • They do not change as a result of usage of the application. These are "design time" files.
  • Size and disk usage of these files can be easily controlled and forecasted, and is usually so small that size is not a concern.

Content files:

  • They are created as a result of the interaction of users with your application.
  • Size requirements not easy to control and forecast. It can be from the few megabytes to the terabytes scale.
  • Frequently changed, or their changes and growth cannot be forecasted as part of the application's design.
  • Some of this files are meant to be publicly accesible while others not.

Sample Setup

There are many ways to properly deal with that scenario and this is one of them.

Drop your application files (source code) to the system disk, on a path such as

c:\inetpub\wwwroot\www.mywebsite.com\

Drop you content files on a separate data disk, on a path such as

d:\contents?\www.mywebsite.com\

Now create a symbolic link so that the contents directory is mapped to \sites\default

mklink -j "c:\inetpub\wwwroot\www.mywebsite.com\sites\default\files\" "d:\contents?\www.mywebsite.com\files"

?What we have just done is telling the operating system that whenever an application tries to acces the sites\default\files path they should actually access the contents folder you deployed on the data disk.

What about the settings.php file? It does not qualify as application or contents file: it's a hybrid between deployment settings and application configuration. If you have horizontally scaled your application you may have different settings.php files in every server, and probably this file will not be backed in your code repository.

What are the benefits of this setup?

  • Cloud SSD storage is x4 times more expensive than regular disks, so you are saving 3/4 of the storage bill (application file size is usually neglibile when compared to contents). Careful with this statement, you may identify that different parts of your contents have different speed requierements, and you could split them between SSD's and regular disks by also using symlinks.
  • You have an effective separation between contents and application files, so it is now easier to have different backup policies between them. You might indeed not even have regular backups of you application files because they are already backed up by the repository, so you only need to take care to backup up your contents.
  • You have eliminated the risk of a collapsing system disk due to unforcasted contents size growth. Of course you are monitoring disk usage, but the rush is less if you know that what is filling up is not the same disk that is holding the operating system and web server.
  • You have greater flexibilty and reduced downtime when performing server scaling on single server setups. Just dettach the contents drive from the old server and attach it to the new one. This takes less than 15 seconds on rackspace cloud.
  • On cloud deployments, storage blobs and content delivery networks are tightly integrated, so you contents file system can get out-of-the-box CDN capabilities.
  • On cloud deployments frontend machines can be volatile. Your application files can be part of the system disk image, and the contents can be shared accross frontend servers.

We haven't talked yet about security (permissions) and folder visibility.

On a regular setup, Drupal will need to modify files inside the files folder, so you need to grant the fast-cgi process identity full permissions on the "files" folder. This account is usually the IUSR account. PHP should not be able to modify the settings.php or application files.

Folder visibility is also very important here. If you left everything as is, you will be exposing to the whole world the private and temporary directories. These directories are meant to be private, and not visible to the outside world. To solve this issue you need to create a web.config inside the sites/default/files directory with the following contents:


NOTICE: We just placed the web.config file inside a IUSR writable directory. Either move the file a level up (and change it's inners) or only give the IUSR specific permissions to the temp, private and public directories.

Although this is not the recommened deployment for all situations, you have an insight in what are the considerations you need to make and what tools you have at your hands to properly deploy your application's files.

Deploying using the PHP deployment tool

The PHP deployment tool automatically takes care of all the previously described setup. In the global.config define a default application root and a default contents root:

D:\_ContentsD:\_Webs

Now give your application an alias in the application.config.xml file, define any required symlinks and optionaly override the application and content files folder:

prevencionintegral//sites/default/

Use the Site/DeployStructure to:

  • Create the application files folder if it does not exist.
  • Create the contents file folder if it does not exist.
  • Give the IUSR account the correct permissions on both folders.
  • Create the symlinks that will link you contents to you application files folder structure.

This article is part of the Deploying Drupal Like a Pro series.

Mar 01 2015
Mar 01

Building a Drupal site is difficult, developing a Drupal Based application is more difficult but correctly managing, deploying and keeping alive an application who's customer is paying you a 4, 5 or even 6 figure number per month is even more difficult. And if you want to do that one last thing in a cost effective way you must do it yourself.

What? That is wrong! Everyone will tell you to focus on your bussiness. If that is developing applications then it is not maintaining the supporting stack. That is true... until whoever is supporting the stack for you ends up eating your business. I know a business case where a Drupal application was moved away from Acquia, and the customer halved hosting costs saving $5,000/month while increasing the available hardware resources. Yes, their new hosting does not provide all the bells and whistles that come from an all inclusive hosting, but... with $5,000/month and depending on which country you do your business in you can easily get 2 full time senior developers.

And you can still get the most of the business critical parts of the add-ons such as test automation, workflow maganement, stagging and production environments all by your own and by saving thousands of dollars.

And the way to go regarding deployment and automation is not clear after all. A few years ago full cloud was the rage. Now Rackspace has started offering On Metal Servers. These are like private colocated servers but with the flexibility of the cloud (spun up and down in minutes). Of course, with the price to performance ratio of colocated. In the end, it is not so clear in what scenarios it is good to delegate all your deployment to a third party, and when not.

In the Deploying Drupal Like a Pro series of posts we will introduce you to what are (some) best practices for deploying a Drupal application to help you handle in a cost effective way your application supporting stack (managing your own infrastructure, of course).

Remember that every business case and application is unique, and that these series of articles are just "basic" guidelines.

When we talk about deployment we will be dealing with:

  • File structure
    • Application files and content files
    • Sample setup
    • Deploying with the PHP deployment tool
  • WebServer site, FastCGI and PHP configuration
    • ?Sharing a PHP binary set between your applications
    • Completely isolating the PHP runtime between applications (while sharing the binaries)
    • The PHP Virtual Runtime: know and control what logs, data and temporary files belong to what application.
    • PHP settings for optimum performance
  • Tunning Web Server Performance
    • Output Caching
  • Cron Jobs
    • How to properly set them up
  • Development and Production Environments
    • ?From you development box to production: an easy, simple but error proof flow.
    • Patch based testing.
    • ?Using the HOSTS directive of your PHP.ini to realtime debug your production environment with no permformance impact.
  • Server Setup
    • ?The Basics
    • Scaling horizontally is not easy. When should I do it?
  • Caching Backends?
    • Memory based caching
    • Memcache / Couchbase
  • Drush
    • Why you should be using it
    • How to install it
    • Basic usage
  • The PHP  Deployment tool

This table of contents is not definitive, we'll be updating it as the articles are writen! The first article Deploying Drupal Like a Pro - Part 1: File Structure is already available.

Mar 01 2015
Mar 01

It has been statistically proven that nobody likes a slow website. We have all moved on from the days when you’d patiently wait for a page to load over that lovely dial-up modem. Nowadays, people want their pretty content, and they want it loaded instantaneously (or at most by 2 blinks).

One very basic concept I learnt about website performance is: minimise requests to your server. This makes perfect sense to me. Say I had a shopping list with 12 items. If I went to the general store and asked the shopkeeper for each item separately, he’d have to make 12 trips and most likely end up being very pissed at me. It’s much more efficient and faster to get all my stuff in a single trip. So we want the server to send over everything the browser needs to display your website in its full glory in as few trips as possible.

Your new favourite word for today is cache. For users to see one of your pages on their browsers, the browser has to ask the server hosting your website for it. Caching just tells the browser to hold onto their copy of their asset for a while instead of asking for it every time it’s required. Loading from cache doesn’t require a request to the server. Less requests to the server equals faster page load.

There are a myriad of tools and checklists out there that can point you in the right direction when it comes to optimising your Drupal site. Tim Millwood’s article on the Top 15 Drupal performance tips is a good one. I followed most of them to optimise my sites but always wondered how these actions actually worked. So here goes, the newbie’s guide to Drupal site optimisation.

General good practices

  • Keep core and modules up-to-date
    • Although this seems like a no-brainer, I also understand that sometimes updating a module may OCCASIONALLY break something (trust me, I’ve been there). My advice? Always test on your local development environment before deploying.
  • Always disable and uninstall modules before removing them

Drupal performance options

This is available out-of-the-box with any Drupal installation. Go to admin/config/development/performance and you will see these options.

Drupal performance settings

  • Cache pages for anonymous users
    • When an anonymous user visits the site, the generated HTML will be stored in the cache table of the Drupal database.
    • This data will be displayed to all other anonymous users.
    • The page caches will not be cleared unless you say so.
    • This will override any block cache settings for anonymous users, which brings us to the next point.
  • Cache blocks
    • The default block behaviour in Drupal is no cache, so enabling this will cache blocks for both authenticated and anonymous users.
    • If block caching is enabled without enabling page cache, then the block cache settings will be used.
    • Given the default is none, you can use the Block Cache Alter module to change this to something more sensible.

Disclosure note: I had a hard time finding documentation on exactly how block caching works in Drupal 7 so please let me know if I’m wrong

  • Minimum cache lifetime
    • This value applies for all cached objects.
    • It tells the system to show cached content for the designated amount of time.
    • If this value is set to ten minutes, the new content you create on your site will not appear until ten minutes later.
    • For new content to appear, the set amount of time must have elapsed and a cache clearing function must be run.
    • If traffic on your site is not high, it’s better to leave it as none.
  • Expiration of cached pages
    • This sets the header Cache Control to public and the maximum age value in the header to the value selected in the dropdown.
    • This header will tell the caching system to serve their copy of the pages until maximum age, after which, the caching system will check back with the server to see if anything has changed.
  • Aggregate and compress CSS files
    • There are numerous CSS files in a working Drupal site, be it from themes, from modules etc. and this option combines all of them into one single file with white spaces removed.
    • Remember the general store example? One request is faster than many requests.
    • Point to note is that if your CSS contains absolute URLs, this may break your site as the URL will not be handled correctly in the combined file. Use relative URLs to be safe.
  • Aggregate Javascript files
    • Similar to aggregation for CSS, this option combines all the Javascript files from your theme and modules, again, to reduce the number of requests to the server.

Usually, it’s best to just check everything here.

Core modules to avoid

  • Database logging (dblog)
    • dblog will write all log messages to the database. Keyword here is all. Error messages, write. Debugging information, write. Module generated log messages, write. You get the picture.
    • This results in lots of database entries every time a page loads. The busier the database is, the slower your site will be.
    • This module is enabled by default for Drupal 7. Disable it and use syslog instead.
  • Statistics (statistics)
    • This module tracks site statistics on page views and site usage.
    • Unfortunately, it writes all these statistics to the database, and again, results in performance taking a hit.
    • Even Mr Millwood (mentioned at the very top of this post), the maintainer of this module, suggests you use Google Analytics instead.
    • This module is NOT enabled by default, and so just leave it be.
  • PHP filter (php)
    • Although there may be certain occasions when you need to have PHP code in your content, most of the time (if not all), you can put that code in a custom module.
    • Putting PHP code in your content means it has to be retrieved from the database before it can be executed, so it makes more sense to bypass this step by writing that code to a custom module.
    • Your database has better things to do than to fetch PHP code for execution.

That about covers all the low hanging fruit for improving the performance of your site. There is definitely more that can be done, but even if you stop here, you should be able to see performance improvements already.

Sam
Feb 28 2015
Feb 28

At Code Drop we are looking forward to leveraging all of the incredible effort which has gone into the govCMS ecosystem and all which as gone into making Drupal the choice for Government organisations. Developers who work with or are hoping to work with the platform have a lot of stuff to look forward to in 2015.

Planned Features

While govCMS is the name for the overarching project to bring Drupal into government using turnkey solutions, it is powered by the Drupal distribution aGov. Part of the recent work that has gone into the platform is a planned set of features for a new version of aGov (7.x-3.x). These planned features have been posted on Drupal.org and do represent a really positive evolution in the profile, a quick summary of which can be found below.

A Modern Base Theme & Generated Styleguides

Although technology moves fast, it seems that front-end development has been moving at the speed of light recently. The Zen theme and generated styleguides are being lead by senior front-end developer John Albin. This is an exciting evolution that promises to enhance front-end development workflows for developers using govCMS.

Better Markup Validation

Better markup validation will assist users of the govCMS platform in meeting compliance needs. The move has hopefully been made to allow validation without calling out to an external web services. This should allow faster and local validation of markup.

Default Configuration

Features maintains and enforces a specific state of configuration. This isn’t ideal for install profiles because configuration is often the spring-board for further work. By moving to a solution which provides default configuration, it will prevent changes to the config from causing an "overridden" state in the feature modules.

More Granular Projects

By moving custom modules into their own projects, separate from the install profile developers will have the option to reuse useful components from aGov in projects not specifically related to government. As a developer, code reuse is always an exciting prospect.

Paragraphs Based Landing Pages

The "paragraphs" module can be seen as field_collection with bundles. This allows content admins to easily create chunks of content with pre-defined fielded bundles. This will change the way custom layouts are built and populated with content and will hopefully improve the content authoring experience.

Community Talks

Edge of the Web

Edge of the Web is a conference held across Australia (and streamed online). Christopher Harrop from Acquia will be presenting on the govCMS platform. The talk will be focused on "What is govCMS trying to achieve and how will it work?".

Canberra (and online)
March 26th, 2015

Drupal South

Adam Malone from Acquia will be presenting at Drupal South focusing on "the process taken by Acquia in conjunction with the Department of Finance to make govCMS a success".

Melbourne
3rd March, 2015

Birds of a Feather

The Drupal South wiki has a proposed session for "The aGov 3 Roadmap (govCMS, Drupal in government etc)".

Hands on Training

PreviousNext will be running a training day for people who want to learn about using govCMS which is free for Drupal South attendees.

Melbourne
4th March, 2015

Feb 28 2015
Feb 28

February may be the shortest month of the year, but it's certainly been one of the busiest for the Drupal Association, so I apologize for taking more than a week to get this summary post up! What's been keeping us so busy? Our first ever DrupalCon in Latin America and the Drupal Association At-Large Board elections. Both of these events have been huge positive milestones for the Association, and have involved dozens of volunteers from around the globe. In the middle of all that, we managed to sneak in a board meeting on 18 February. If you missed it, you can listen to the recording, read the notes, and peruse the materials. Or feel free to skim this summary!

Operational Update

  • We have a big initiative internally at the Association to reevaluate the metrics we use to illustrate the success of our work. We are also looking at ways to better display these metrics so that you can see more context. So over the next few months, you'll see the metrics in the dashboared shift and change. Just a bit of a heads up, and let us know if you have any feedback along the way.
  • The February board packet covered our January metrics, and things look pretty good one month into the year. We are especially pleased that the Engineering team has been able to bring site performance to our goal levels. 
  • The Engineering Team also took several big steps towards key areas of the Drupal.org roadmap in January. Step 1 of the roadmap is better Account Creation and Login, and several key issues were closed out.
  • The DrupalCon Team and Engineering worked together to launch events.drupal.org in January as well. This shift means that Con sites are all on the same platform now. We no longer have to launch a site from scratch for each Con, which helps make Cons much easier to manage. Most importantly, we've been able to introduce key new features in reegistration for our community. Excited? Go ahead and register now! You can check out the new features yourself!
  • We are really lucky to work with the tireless Drupal 8 Branch Maintainers on the Drupal 8 Accelerate program. The program is picking up steam with a number of grants made and completed already. The next big grant will fund a Drupal CI (testbot) srpint in Portland at the end of March.

Content Strategy Update

Last year, the Content Working Group began a process of building a larger strategy for a reimagination of Drupal.org. Our first work was focused on User Research, and completed that work in the fall, publishing the developed personas. The next phase has focused on developing a content strategy. With over 1.2 MILLION pieces of content on Drupal.org, a strategy for dealing with that content is going to be pretty darn important. You can check out the presentation, as well as the post that's currently one of those pieces of content on Drupal.org.

Drupal.org Advertising Strategy

Finding new revenue streams is vitally important to the Association. For the entire history of the Drupal Association, DrupalCons have been the primary way we have funded other community work. We want to do more to serve our mission: uniting a global open source community to build and promote Drupal. If we're going to do that, we need new revenue streams. The bonus? If we can find new funding sources, it takes the pressure off of DrupalCons to perform financially, which means we can make choices for those events that might not fuel the financial bottom line, but make the events better for the community. 

So how are we doing it? New programs like Drupal Jobs have launched. We are also introducing advertising on Drupal.org and to Drupal.org visitors. We working to develop advertising products that are meaningful for advertisers (enough traffic, good clicks) and also deliver value to our community. We've drawn a few clear lines - we won't advertise on issue queues, for example, and will focus on users who are not logged into the site. We'll also be developing a variety of programs so that small shops can participate alongside bigger firms. 

For all the details, check out the presentation.

The End

Thanks so much for checking in on this board meeting and, as always, please let me know if you have any questions or thoughts.

Feb 27 2015
Feb 27

Grass roots enthusiasm, D8 teen spirit, much needed long absent leadership and community courage facing up to critical issues should overflow into DrupalCon Los Angeles in May

An incredible DrupalCon, DrupalCon Latin America, ended a couple weeks ago and I haven't seen any cool DrupalCon wrap-ups capable of really sharing with the rest of the Drupal community what an extremely well-organized and just plain special community experience it was. I am sure I'm not the only one who felt completely invigorated by it all. Let's take a look at why, and see how we can make it contagious.

Great Venue
Attendees from all over
Quality of presentations
Drupal 8 properly positioned
Now we know when to start switching to D8
Much Needed Drupal leadership
Huge participation in the Sprints and beyond

Great Venue

The venue was well chosen, which gave a great feeling of security, organization and just plain competence all-round. For those of us staying in the hotel on the same premises, we had the feeling of forming part of some kind of Olympic Drupalean village and the foyer was just a natural meeting place for everyone as they arrived each day, and even for a few days after the DrupalCon was all over. Everything just worked, even the WiFi was no more spotty than any other conference (except during the sprints, well what do you expect with record percentages of attendees participating)? One great touch was how Lingotek, a cloud-based translation management system, pitched in to provide live interpretation for presentations ¡Espectacular!

Attendees from all over

It wasn't huge. Yet despite the modest number of people attending (just under 300) those who are never fooled by numbers knew it was truly an international conference and didn't have the flavor of a DrupalCamp at all. It was a Señor DrupalCon! A cursory view of the attendees list shows that all major players knew they had to be there, and 99% knew they had to say something coherent when they did. Latin America is poor, in revolt, with a 500-watt amplified local settings version of the world economic crisis, but we're obviously a firm part of the future, and most presenters (99% as I say) went out of their way to highlight solid and extremely active Latin American participation in the Drupal community and project.

Quality of presentations

Training camps plus DrupalCon prequels...

Not only were the presentations interesting but cut to the core of what people are concerned and anxious about at this critical time in Drupal, and in website and web application development in general. That's why the conference was a success. It had this way of facing up to stuff with courage as a community.

There was a proper debate among the keynotes. Something for everybody? A lot of wishful thinking? Time will tell. But a “pushy” Big Tech rerun by Dries (rerun because big data aggregation (“Netflix... Google... development efforts will shift towards using contextual data collected through passive user behaviors”, and the like, in fact already being implemented on drupal.org – do people realize that?) was roundly countered by a slogan that figured prominently in “the other keynote” (see following section): “Drupal 8 – For everyone, out of the box”.

See the full list of presentation videos https://www.youtube.com/playlist?list=PLpeDXSh4nHjQUcahLMrBws9OAaNrJf07z .

My own picks:

So, facing up to stuff that worries and concerns people who actually work for a living and need to exercise their right to access Free Software. That's what needs to be replicated in the Drupal Community time and time again and that's what made for the high quality of the presentations.

Drupal 8 properly positioned

For too long now there's been a widespread tendency awash in the Drupal Community according to which Drupal 8, and hence the Drupal Project in general, has turned somehow into something reserved only for Big Drupal: big shops, big agencies, big companies with huge resources. That Drupal 8 is out of range, too difficult and too big and maybe even cumbersome for single developers, small shops, for companies on a budget. Once said, this impression has been left floating there for quite some time. However, this DrupalCon absolutely smashed these misconceptions, many of which I myself have shared for some time, and provided a much clearer view of what's going on:

  1. Even if you stick with Drupal 7, you still have to learn a bunch of new stuff to learn in this day and age (front-end stuff in terms of javascript frameworks and SASS, backported stuff from Drupal 8, REST, distributed apps, etc.) so get used to learning new stuff. Learning new stuff is good.

  2. The best route is to stick with progress and the industrial mainstream, development fellowship with what's really moving. For those who feel PHP is being superceded by a new generation of programming languages and their attendant frameworks, there exist many new fast-moving eco-systems, in the Javascript world, in the Scala and Java world, in the Go world; too fast-moving some would say and they have their fair share of framework choice panic themselves. Most of these can be used perfectly well in conjunction with modern Drupal 8 distributed approaches. But for many it's all about the PHP renaissance, and one area that's definitely moving is the Symfony eco-system, so strong in itself it's a safe bet for many, independently of the fortunes to be faced by Drupal in the future.

  3. Hear this: Drupal 8 is for everybody:

Larry Garfield, in his presentation at DrupalCon Latin America 2015 in Bogotá summed up the benefits of Drupal 8 in startling fashion (see [video](https://www.youtube.com/watch?v=-lLILaIZr44) and [slides](http://www.palantir.net/presentations/dcbogota2015-drupal-and-us/#/2/1) when he explained that not only is Drupal 8 a new generation PHP Platform, but that far from what we have been led to expect, namely that it will only be useful for experienced developers and for large companies with huge resources, in actual fact it can do much more than any other CMS framework, for everyone, right off-the-shelf even for plain old site-building right in core without any configuration. It's worthwhile going into a little detail here:

  • Benefits for site builders **for everyone, out of the box**: Build real sites with what comes in core, without any configuration

    • More fields in core (Entity Reference, Date, Link, Email, Telephone) with the Field API (rich data model just with core)

    • Views API and UI in core (saves 6 months in terms of being able to use Drupal 8 after initial RC release, compared to having had to wait for views when Drupal 7 was released, without Views in core)

      • Admin uses views, much more customizable (VBO in core!)

      • Content modeling, editing, assembly, delivery out of the box

      • Content delivery

    • Configuration management based on versionable YAML text files; the configuration is no longer mixed with content in the database

      • Much better solution for dev -> testing -> production workflow and deployment

      • Everyone, large and small, has the right to have access to configuration management tools

      • Real Configuration API

      • Config import/export built in

      • Modules can include default config

    • Translation (of interface, content AND configuration!) has been completely revamped, compacted, improved and better integrated in core

  • Benefits for content editors

    • Rich editing experience (in core: WYSIWYG editor, editing in place, more usable forms; works without configuration)

    • Back to site button (instead of overlay :) )

    • Accessibility WAI-ARIA, keyboard control, voice control with Drupal Announce API so that reportedly a sight-impaired person may edit in place. Best accessibilityt there is. All built in and automatic.

    • New text-based help system (including context-sensitive help)

  • For themers

    • Out with IE6-8

    • Module for IE8 if you need it

    • HTML5 + CSS3

    • Everything responsive out of the box (including menus and toolbars)

    • HTML5 Forms which also work on mobile!

    • Twig (https://www.drupal.org/theme-guide/8/twig) template engine.

    • 25% fewer divs

  • Benefits for coders (under the hood)

    • Modern version of PHP 5.4, re-visioning how Drupal uses a modern language.

      • Interface-driven development

      • Loose coupling

      • "Hack core without hacking core"; fewer Drupalisms

      • No more Not Invented Here; now Proudly Invented Elsewhere

        • Symfony2 components (HttpFoundation, HttpKernel, DependencyInjection, EventDispatcher, Routing, Serializer, Validator, Yaml)

        • Symfony CMF (Content Management Framework, co-authored by the Symfony, Easy CMS and Drupal communities)

        • Zend Feed (including Atom, and with greatly reduced dependencies)

        • Doctrine Annotations

        • Guzzle (best Http client in PHP)

        • EasyRDF

        • Twig

    • Plugins: same pattern used all over

    • Unified entity API, used all over

    • Unit tests with PHPUnit

    • RESTful pipeline

    • Drupal has gotten off the island, meaning that general development experience in many PHP projects transfer to Drupal 8 and multiple platforms

    • Drupal Console built on Symfony Console for scaffolding and code generation, instrospection and profiling

In addition

A very recent article by Alex Pott, “Drupal 8 and the Enterprise” http://chapterthree.com/blog/drupal-8-and-the-enterprise also does a good job of outlining how Drupal 8 really is for everyone, out of the box. (However, the point raised by Nedjo Rogers concerning difficulties with Drupal 8 support for installation profiles or something similar to features module is worthy of consideration, see my comment (and also the author's very clear reply).

Now we know when to start switching to D8

“The Other Keynote” even included excellent criteria for knowing when we can start using D8 for actual projects, stating that the single most important block for this is the current absence of an automatic upgrade path for beta to beta releases. And it’s best to wait until a release candidate is out or about to be out.

Much Needed Drupal leadership

The “Other Keynote” as I am calling it was very refreshing, almost like a breath of fresh air in its defense of the project and its positioning in terms of free software for everyone. But, such a keynote is neither more nor less than what you would expect Drupal leadership to say. It's just that we haven't had that kind of spirit here since nineteen sixty nine...

I was also impressed by the leadership shown, for example, by Cathy Theys (@YesCT) both in making sure the event was a success, as well as in gaining support for the sprint events and sharing “The Drupal Way” to many first timers, despite language differences.

Huge participiation in the Sprints and beyond

I think a record was broken in percentage of attendees participating in sprints. The level of enthusiasm was enormous and quite a bit was done. Just another indicator of this having been a very special DrupalCon.

Bookmark/Search this post with

Feb 27 2015
Feb 27

If you are playing around with Drupal 8, you may want to install version 7 of Drush on your computer. However, Drush 7 is currently only available as the master branch at github, and you may not like to throw out your existing Drush 6 in favor of the Drush development version, which is not stable. I’d like to share with you a way you can have both installed at the same time. I used a Mac, though these commands should work well also under Linux. They will obviously not work on Windows.

1. Clone Drush master branch from git

We want to get the master branch from the Drush github repository. This will be placed under “usr/local/lib” as a new folder named “drush”. Launch your Terminal and type:

> cd /usr/local/lib/

> git clone --branch master https://github.com/drush-ops/drush.git

2. Get composer

Drush 7 requires composer to install, so you need to get that if you don’t have it already. We also want to move composer to /usr/local/bin/ so that it’s easier to use.

> curl -sS https://getcomposer.org/installer | php

> mv composer.phar /usr/local/bin/composer

3. Install Drush

We can now install Drush through Composer. At the end, Composer will generate some autoload files, though you can ignore the suggestions.

> cd drush

> composer install

4. Create an alias for Drush 7.

To make Drush 7 a bit easier to access, we can create an alias that you can use in the Terminal. Type:

> vi ~/.bash_aliases (Linux)

> vi ~/.bash_profile (Mac)

This will open the “vi” text editor. To move around, use your cursor keys. Type “i” to edit the text. When you’re done, type “esc” followed by “:wq” to save and close the editor. Inside this file, we want to add:

alias drush7='/usr/local/lib/drush/drush'

5. Go ahead and unleash the power of Drush 7

Now it’s time to test that everything we did works well. Type:

> drush7 version

It should return this text:

Drush Version   :  7.0-dev

Your Drush 6 will still be there and untouched by this installation. Enjoy!

So what’s new in Drush 7?

Drush 7 adds the following commands to your default arsenal:  browse, core-cli (php), image-derive (id), cache-rebuild (cr, rebuild), config-export (cex), sql-sanitize (sqlsan). Some of them are Drupal 8 specific. I’ll write about these commands in a future blog post.

Feb 27 2015
Feb 27

Begin to design a Drupal website with a million nodes in mind. We build a Drupal website. It runs well at beginning. Until one day, the system has hundreds of thousands of node. We found the site became slow. We need wait many seconds before we can open a new page. Not only it is slow, but also sometimes we got errors like memory exhausted.

Most time the problem was existed at the beginning stage of a system. When designing a site, there are something we as a developer have to take care. We need bear in mind the site will grow and more and more nodes will come. Everytimes creating a function, we need to make sure the function will work fine when there are hundreds of thousands of nodes in the system. Otherwise, those functions may time out or finish all the memory by those ever increasing nodes in the system.

PHP have a maximum memory limit for each user. Sometimes it is 128 MB. Sometimes it is 256MB. The number is limited, and it is not infinite large for sure. There is no limit on how many nodes can exist on our website. As our system getting larger and larger with more nodes created, we will face the memory limitation sooner or later if we did not take it into consideration at the beginning.

Here is a quick sample. Drupal have a function node_load_multiple(). This function can load all nodes in the database to memory. Here are some codes from one of our contributed module.

foreach (node_load_multiple(FALSE) as $node) {
// Modify node objects to be consistent with Revisioning being
// uninstalled, before updating the {taxonomy_index} table accordingly.
unset($node->revision_moderation);
revisioning_update_taxonomy_index($node, FALSE);
}

This code is in an implementation of hook_uninstall. It will run into a problem if there are over 10,000 nodes in the system. As a result, we can not uninstall this module. Here is the error message:

Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 36 bytes) in ...

It used up all 256MB memory before it can load all the nodes. As the result, the module can never be uninstalled from the site.

It is an extreme case. As we troubleshooting an existing site, we may notice similar case here and there. I also notice that we can do something on the field_sql_storage module to make Drupal running faster and keep SQL database smaller.

Feb 27 2015
Feb 27

It's the Drupalize.Me podcast!

This week on the podcast, I chatted with Jesus Manuel Olivas about the Drupal Console project.

Listen here: Podcast Episode 58: Drupal Console

What is the Drupal Console?

The Drupal Console is, at this time, a suite of tools that you run on a command line interface (CLI) to generate boilerplate code and interact with a Drupal 8 installation.

Similar tools include:

  • Module Builder: (Generates Drupal 6, 7, or 8 module scaffolding)
  • Drupal Module Upgrader: (Converts modules from Drupal 7 to Drupal 8; generates static help file with links to relevant change records)
  • Drupal 8 Tools: (Drupal code generator written in bash)
  • Drush (Interact with Drupal installation via CLI, create aliases, create custom commands)

What makes Drupal Console unique?

From the ground up Drupal Console is using the modern PHP practices introduced into Drupal 8, including object-oriented PHP. The Drupal Console isn't a Drupal module, but was built with the Symfony Console Component and other libraries, such as Twig, to generate PHP, YAML, and other file types used in Drupal 8 module development. It is a tool designed for anyone using or planning to use Drupal 8. At the moment, it is used via a CLI, but there are plans to make it accessible through the Drupal administrative interface. Drupal Console works with Drupal 8, and because of the nature of its code base and use of modern PHP, will not be ported to work with Drupal 6 or 7, but instead plans to support Drupal versions from 8 onward.

How does Drupal Console differ from Drupal Module Upgrader?

Drupal Module Upgrader takes a Drupal 7 module and attempts to port it to Drupal 8. While it generates files like Drupal Console does, Drupal Console generates module scaffolding and code based on a series of interactive prompts, instead of analyzing an existing module and converting it to work in Drupal 8.

How does Drupal Console compare to Drush?

There are many similarities between these two tools, but the main difference is how it was built, using an object-oriented architecture and Symfony components. Read more about how the tools are similar in these two blog posts:

What kinds of things can you do with Drupal Console?

Drupal Console provides a number of commands for creating module scaffolding and boilerplate code. For any command, you will be asked a series of questions about what you want. In the case of module scaffolding, files are created and inside these files, classes—complete with namespacing and use statements—are created for you with the naming convention you specified in the command's prompts.

Here are some of the code generating commands currently available, or in active development, in Drupal Console:

  • generate:authentication:provider - Generate an Authentication Provider
  • generate:command - Generate commands for the console
  • generate:controller - Generate and Register a controller
  • generate:entity:config - Generate a new EntityConfig object
  • generate:entity:content - Generate a new EntityContent object
  • generate:form:config - Generate a new ConfigFormBase object
  • generate:module - Generate a module
  • generate:permissions - Generate a module permissions object
  • generate:plugin:block - Generate a block plugin
  • generate:plugin:imageeffect - Generate image effect plugin
  • generate:plugin:rest:resource - Generate REST resource plugin
  • generate:service - Generate a service object

Similar to Drush, you can also use Drupal Console to interact with your Drupal 8 installation, or use it for debugging during development. Here are some of the commands currently available (with more in development!):

Clear (rebuild) cache:

  • cache:rebuild - Rebuild and clear all site caches

Configuration Management:

  • config:debug - Show the current configuration
  • config:edit - Edit the selected configuration
  • config:export - Export current application configuration (Note: config:import is planned for development.)
  • config:override - Override config value in active configuration

Container

  • container:debug - Display current services for an application

Migrate (depends on Migrate module)

  • migrate:debug - Display current migration available for the application
  • migrate:execute - Execute a migration available for application

Module

  • module:debug - Display current modules available for application
  • module:download - Install module or modules in the application
  • module:install - Install module or modules in the application
  • module:uninstall - Install module or modules in the application

REST

  • rest:debug - Display current REST resource for the application
  • rest:disable - Disable a REST resource for the application
  • rest:enable - Enable a REST resource for the application

Router

  • router:debug - Display current routes for the application
  • router:rebuild - Rebuild routes for the application

Site

  • site:maintenance - Switch site into maintenance mode
  • site:mode - Switch system performance configuration (Proposed by Joe Shindelar (@eojthebrave) and other Lullabots during DrupalCon Bogotá, this is similar to the Drush devify command.)

Test

  • test:debug - List units-test classes available for the application

Similar to how a module can supply its own Drush commands, modules can also supply custom commands for use in the Drupal Console. Webprofiler is one example of a module that has supplied its own set of Drupal Console commands:

  • webprofiler:benchmark - Benchmark an url
  • webprofiler:export - Export Webprofiler profile/s to file
  • webprofiler:list - List Webprofiler profiles

To learn more about how the Webprofiler project provided integration with Drupal Console, see this blog post by Luca Lusso, Building Bridges - Webprofiler meets Drupal Console.

There are more commands and functionality in the works, and module developers are invited to provide their own custom Drupal Console commands.

Who is the intended audience for the Drupal Console?

Because Drupal Console generates boilerplate code—working example code—for the many different types of entities and objects in Drupal 8 core, this tool can be particularly useful for anyone looking to learn or teach Drupal 8 development. The goal of the project is to make a tool for people learning Drupal 8 that is relatively easy to use.

As such, the following groups in particular could find this tool advantageous to add to their learning Drupal 8 toolkit:

  • Drupal trainers and consultants (providing Drupal 8 developer training)
  • Contributed Drupal 8 module maintainers and developers
  • Drupal development companies (reducing development time for Drupal 8 projects by using the code generation tools)

As mentioned, there are plans to include a non-CLI interface, to make the tool even more accessible to all site administrators of Drupal 8.

Is it ready now? Who can I ask about it?

Yes, and the maintainers invite you to try it out and send them any questions or comments through Twitter at the following accounts: @drupalconsole, @dmouse, @jmolivas, @enzolutions or @omers.

You can download and learn how to set up the project at drupalconsole.com.

What kind of help does the project need?

What features are planned for development?

  • Verbose code output for learning and leveraging docblocks
  • Complete config:import, site:status, and few a few other commands.
  • Import/export content between Drupal installations
  • Site aliases
  • Generate dummy content, probably using PHP Faker library or Default Content project.
  • Add a GUI for Drupal Console as an alternative to the CLI. This could be especially useful for site builders wanting to generate dummy content or issue site commands without needing to use the command line. It could also be used for code generation in the form of a downloadable compressed file.

Additional Resources Mentioned in this Podcast

Project links

Libraries or projects

Blog posts

Bonus!

Check out this Drupal Podcast in Spanish, hosted by Jesus Manuel Olivas and David Flores, two of the maintainers of Drupal Console.

As you can tell, this project is in full swing and looks to be a key resource for Drupal 8 users of all kinds. Listen to the full Drupal Console podcast and give the Drupal Console a spin!

Thanks to Jesus Manuel Olivas for providing a wealth of information and resources about the Drupal Console on the podcast and for this blog post.

Pages