14 Sep 2014

feedDrupal.org aggregator

Károly Négyesi: Drupal 8 progress from my / MongoDB perspective: update #29

Perhaps the most important development is the final naming of what was field/field instance in Drupal 7: in Drupal 8 these are configuration entities. The machine names are field_storage_config and field_config. There has been several renames but we have settled on these finally (although the field_config rename is not yet in). It does reflect the most important difference between them: field storage contains everything pertaining to the storage of the field. The things that do not change the storage of it go into the instance. However, some confusion might come from already existing Drupal 8 documentation and other materials where field_config was the name for what ended up as field_storage_config.

In other rename news, entity storage/list/form/render "controllers" are now handlers. This probably decreases confusion as controllers are used by the router system to deliver the page content.

Migrate now tracks the whether a migration has been run or not. Previously we were guessing from the id mappings -- but if a source returned zero rows we couldn't really say whether the migration ran or not. Now we could clarify for real what are hard dependencies and what are optional. In the Drupal 6 migration, there are few optional ones which is just as it should be.

There's a Views migration in the works. As expected it's really complicated with lots of moving parts but it's coming along nicely.

Only book storage needs entity field query conversion after the epic comment query conversion issue finally got resolved.

One of the child issues of the last beta blocker removes the special casing for SQL storage -- hurray! Instead of requesting the schema of entity tables during module install (and other places) and then creating the tables there are now events on entity type create, update and delete. This makes it possible to create mongodb indexes cleanly.

14 Sep 2014 10:47pm GMT

d7One: Step by step guide to installing Commerce from scratch

The following guide was used in a presentation at DrupalCamp Montreal 2014. The presentation focused on how to install Drupal Commerce from scratch.

FIRST FLOOR

  1. https://www.drupal.org/project/commerce
  2. Install required modules
    • drush dl ctools views entity rules addressfield commerce
    • drush en ctools views entity rules addressfield commerce -y
Share page with AddThis

Tags:

14 Sep 2014 6:50pm GMT

Steve Purkiss: Case Study - NickJr. Colour CMS & API - Feedback sought!

Steve Purkiss's picture
Sunday, 14th September 2014

Case Study - NickJr. Colour CMS & API - Feedback sought!

It's been an embarrassing amount of time since I last blogged or did anything to my site so I've started to create some content, but before I submit it as a case study on Drupal's site I'd love to have some feedback, it's been years since I wrote case studies so a little rusty. Is it of interest? Does it help? Does it answer the right questions? Are there any questions you'd like me to answer?

NickJr. Colour CMS Home Screen

Brief overview

Viacom's Nick Jr. is a digital television channel aimed younger children, home to popular shows including Dora the Explorer, Angelina Ballerina, and PAW Patrol. 'Colour' is a section of the Nick Jr. website where, daily, tens of thousands of users interact with predefined line-art drawings using paint brushes and stickers. They can then, if they wish to, send pictures they create to their friends via email. The mostly Flash-based front-end currently connects to a legacy back-end system which is being replaced with Drupal.

Completed Drupal site or project URL

http://www.nickjr.co.uk/create/#!/colour

Why Drupal was chosen

Drupal's core and contributed modules along with customisable web administration interface provided all the functionality required out-of-the-box and is already used widely throughout the organisation.

Describe the project (goals, requirements and outcome)

Project Goals

The goal of this project was to provide a bespoke back-end CMS based on Drupal to replace the legacy system, along with introducing new functionality enabling Send to Gallery and Pic of the Week features. The CMS needed to as simple as possible for content managers to use, and the whole system had to be able to cope with the tens of thousands of users using the API on a daily basis.

Deliverables

The site was to be delivered as a Drupal install profile so it can be adapted and re-used - an initial step towards creating internal Nickelodeon-specific distributions of Drupal, further lowering costs and time-to-market for future projects with similar requirements. Purkiss built a similar system a few months prior for Universal Artists uView Augmented Reality App and have extensive experience integrating Drupal with 3rd party services so were ideally placed to deliver this type of Drupal project.

Theme

First we set up the install profile with Shiny, the administration theme which comes with Drupal Commerce Kickstart, to be the main theme to the site. Shiny is a great theme for this kind of system where there's really only one main display the content managers interact with - it's easy on the eye with good typography and spacing.

Legacy Migration

We then re-created what functionality was required from the legacy system using Drupal Services - the calls for saving images, retrieving images for a show, etc. There was a major difference here as the legacy system stored all the data in flat XML files with no user data linked. Drupal is a relational database system so we have user accounts, content types and taxonomies - this proved to be an exercise in both education of the client as to the benefits of hooking into the Drupal API, along with re-architecting of the current content model and workflow.

Features

We used a Features-based approach to development with each of these features, along with the install profile, having their own private Git code repository in the cloud in order for issue tracking and maintenance to be easier.

The features we delivered were as follows:

  • Content Types
    • NickJr Colour Image - stores the user's image along with a Canvas ID which refers to the line art used, a taxonomy field to link to the associated show, and two flags - one to show if the user has sent the image in to Nickelodeon for consideration to be included in the showcase, and one to denote whether it is in the associated show's showcase.
  • Fields
    • User Profile Fields - extra profile fields to store the user's name and age.
  • Rules
    • Redirect after login - redirects to the front page view after logging in.
    • Pic of the Week - Views Bulk Operations Component - one rule to set and one to unset an image as Pic of Week
    • Showcase - one to set and one to unset an image as to be in a Show's ShowcaseNickJr. Colour CMS Views Bulk Operations
  • Services
    • NickJr. Colour API - the Services settings for the custom API endpoints.
  • Taxonomy
    • Shows Taxonomy - with Pic of the Week field
  • Variables
    • Always harmonize views filters - Allows views to use both contextual and exposed filters for views
  • Views
    • Front Page - Displays all images, defaults to only show images Sent to Nick
    • Showcase - Displays images in showcase, all if no show_id sent through
    • User Profile - Displays users images on their profile page

Schedule

Project timescale and budget was for an incredibly tight 10 days which we delivered in, however were subsequently hired for a further 7 days to re-factor the API and provide a few final additions to the administration interface.

Out-of-the-box, Drupal Services module provide a standard set of API calls so you can do things like create a user, a node, etc. so all the functionality required was there however required a number of calls to the API to achieve the desired workflow. It was decided to spend extra time creating custom API endpoints which would hide this functionality, reduce the number of API calls required, and make it easier for future users of the API.

The downside to this approach is the technical debt introduced when diverting away from the *.drupal.org infrastructure of support, i.e. core and contributed modules. In this instance the code was simply wrapping existing API calls and the client has access to technical resources so the decision was to take on the technical debt in order to produce a more tailored outcome.

Outcome

We used the extra time to create a RESTful API which abstracted away from Drupal Services out-of-the-box API endpoints along with coding an auto account creation system to link up user data from the front-end without users having to enter their email address, a requirement of Drupal's user account creation. We documented the API using Drupal's inbuilt help module and passed the system over to the client, helping them through building the system from the Drush make file.

Summary

The resulting system is a clean, simple-to-use CMS with RESTful API handling thousands of users on a daily basis. Content managers have a separate role with very restricted access so can only do what they need to do on the system.

We really enjoyed delivering this project, however alert anyone thinking of building similar to allow extra time, especially if it is their first Drupal experience - no matter how good specifications are, issues usually arise in one form or another. Also often once people do start using Drupal and see the possibilities available, requirements change and it is good to allow for those to be taken into account.

About Purkiss

Purkiss helps organisations onboard Drupal through consultancy, development, training and support. For more information about Purkiss services please visit http://purkiss.com

Modules/Themes/Distributions

boolean_formatter
cors
eva
features
filter_harmonizer
mimemail
rules
services
shiny
smtp
strongarm
views_bulk_operations
views

Why these modules/theme/distribution were chosen

  • boolean_formatter - makes the user interface a little nicer by providing icons for boolean fields such as ticks and crosses
  • CORS - required for connecting to the front-end
  • EVA - we used an Entity Views Attachment to display users pictures on their profiles
  • features - features allows you to export configuration settings to code
  • filter_harmonizer - Views Filter Harmonizer fixes an issue when using multiple filters on views
  • mimemail - used to send images via email
  • rules - as described above, used for redirecting user on login and for custom views bulk operations
  • services - used for the RESTful API
  • shiny - an administration theme we are using for the entire site
  • smtp - for sending email
  • strongarm - for storing variables in features
  • views_bulk_operations - to enable easy workflow, such as adding an image to a showcase
  • views - so we can display the data we want easily

Community contributions

As the API is specific to the client and used mostly existing functionality we had no code to contribute. The only custom code was for automatic account creation and there are existing modules which provide similar functionality which we used the code from but is too specific to this install to re-use externally.

This is however the second time we've been asked for this sort of system, and with the growth of mobile apps we are currently working out whether it would be possible to create a distribution which will help get most of the way there - at least have relevant modules and perhaps an example scenario based on the simple image requirements for this project.

tags:
case studies
Drupal Planet
Planet Drupal

14 Sep 2014 6:00pm GMT

12 Sep 2014

feedDrupal.org aggregator

Deeson Online: PHP 5.5 Generators and Drupal

PHP 5.5 introduces generator functions. Generator functions return an object that can be iterated over - often to be used with a foreach loop, for example:

function gen_one_to_three() {
  for ($i = 1; $i <= 3; $i++) {
  // Note that $i is preserved between yields.
    yield $i;
  }
}
 
$generator = gen_one_to_three();
foreach ($generator as $value) {
  echo "$value\n";
}

Which will output:

1
2
3

(Example taken from php.net).

PHP calls the generator function when it needs values - when the generator yields a value the state of the generator is saved, so it can then be resumed when the next value is required. This can lead to significant performance boosts over creating an array which only exists to be looped over as less memory is needed.

There is more detail on http://codingexplained.com/coding/php/introduction-to-php-generators.

So how can this apply to Drupal …

A render array might look like...

$wrapper = array(
  '#type' => 'container',
  '#attributes' => array(
    'class' => array('class'),
  ),
  'item-one' = array ();
  'item-two' = array ();
  'item-three' = array ();
);

The element_children function returns an array which contains the array keys of the children array elements. This breaks from the standard PHP foreach pattern where you perform operations directly on the value created by the foreach loops - I don't think this is ideal - I had to look twice to see what was happening the first time I saw it.

Using generators, you can use a more typical php pattern - the following is equivalent to the above.

foreach(element_children_generator($variables) as $key => &$element) {
  ...
  $element['#example'] = 'example'; 
  dpm($element);
  ...
}

As well as being a more typical PHP pattern, referencing the element within the loop is cleaner.

There are downsides to this approach too. A developer familiar with Drupal may have to look twice to see what is going on with the yield keyword. Obviously this can't go into Drupal 7 Core (which supports php 5.2.5+), and I wouldn't recommend it for Contrib either for the same reason.

However since PHP 5.3 and below is EOL I think this pattern is well worth adopting in your own projects with low risk.

Read more

PHP 5.5 Generators and Drupal

By Chris | 12th September 2014

12 Sep 2014 2:00pm GMT

DrupalCon Amsterdam: Training spotlight: Introduction to Headless Drupal

We know Drupal is an amazing platform for making websites. But did you know it's also a world-class content API that can easily be integrated with a other technologies?

In Introduction to Headless Drupal you'll write your first Node.js application(s) and learn how to integrate Node.js's real-time wizardry into Drupal's content management magic.

Meet the Trainers from Four Kitchens

Matt Grill (drpal) Engineer at Four Kitchens
Matt taught himself HTML in 1996 while making a fansite for The Simpsons, even though he's never actually watched the show. Matt's interests in technology range from Arduino to automation and deployment. Matt currently maintains Is It Shaking?, a Node.js powered app for tracking and analysing earthquakes worldwide, Is It Shaking?. He has been working with JavaScript for nearly 10 years.

Michal Minecki (mirzu) Director of Technology at Four Kitchens
Mike Minecki has been building websites since 1999, and has been working with Node.js and Drupal for about a year. He has worked on www.drupalpoetry.com, a responsive web game that mimics the experience of playing with magnetic poetry on the web. He has taught Node.js in Austin and San Francisco, and has been speaking at events around the country about how to integrate Node.js and Drupal.

Attend this Drupal Training

This training will be held on Monday, 29 September from 09:00-17:00 at the Amsterdam RAI during DrupalCon Amsterdam. The cost of attending this training is €400 and includes training materials, meals and coffee breaks.

Many of our training courses, including Introduction to Headless Drupal, are nearing capacity and we will not have waitlists, so if you are planning to attend, we strongly recommend you register this week.

Register today

12 Sep 2014 12:47pm GMT

Code Karate: Drupal 7 Entity Registration Module

Episode Number:
167
Drupal 7 Node Class Module - Daily Dose of Drupal Episode 166

The Drupal 7 Entity Registration Module makes it easy to host sign-ups or registration forms directly on your Drupal 7 website. This solution works great for event, conference, webinar, or training signup forms.

In this lesson you will learn:

Tags:
Drupal
Drupal 7
Drupal Planet

12 Sep 2014 11:57am GMT

11 Sep 2014

feedDrupal.org aggregator

Drupal Watchdog: Cooking Up Sites With Open Outreach

Article

SpicesDrupal distributions can be a huge leg up in building a website, especially for those with little technical knowledge. The "ingredients" (modules) you need are already assembled, leaving you with just the task of stirring it up, and perhaps adding your own personalizing flavors. The Open Outreach distribution is specifically designed for nonprofit and grassroots groups. It comes with a wide range of apps - bundles of modules and configurations that are geared to the needs of groups, such as contact management or mapping. It also includes a number of helper features, such as a text editor, commenting, and social media handling.

For more detailed instructions on how to work with Open Outreach, see the complete user documentation.

Below you'll find some recipes for whipping up a specific kind of Open Outreach site, giving you the apps you need: to enable; required configuration; suggested themes for the look and feel of your site; and tips on customizations to take your site further. Happy site building!

Environmental group focused on mining impacts

You're a board member of this small but enthusiastic group. You've been tasked with creating a website that will serve as the public face, but more importantly also track membership contacts as well as your contacts with other groups, government bodies, and industry.

11 Sep 2014 5:25pm GMT

Lullabot: Finding related content faster with Apache Solr

We recently fixed a performance issue at the MSNBC project: the More Like This list of content related to the current page was stressing our database servers with slow, complicated MySQL queries. Here is a screenshot of the block in question:

Original More Like This Block

11 Sep 2014 5:00pm GMT

Drupal Association News: Drupalaton 2014 in Hungary, at the largest lake in Central Europe

This post originally ran on Imagine Creativity, and has been reprinted with permission.

Wow my Hungarian friends - you have done it again! Two weeks ago, I spent a long weekend at Drupalaton, a Drupal camp in Hungary with the difference that it also served as a short relaxing break. It was the perfect combination of a holiday and work with the beautiful surroundings of Central Europe's largest lake Balaton.

I was very excited to return to the country after the amazing Drupal Developer Days in Szeged event that I went to in March. It was also filled with meeting amazing people from all around the world, learning and sharing knowledge and connecting with so many inspiring people.

At both events the thing that really stood out for me was the great hospitality shown by the Hungarians I met there. I have really been humbled by how friendly and hospitable they have been, and all of the time they put into making the event so amazing for all the attendees.

This was the fifth year that large Drupal events have been taking place in the country, but the second where the language hasn't been exclusively in Hungarian. Last year's event brought people from Romania, Serbia and other neighbouring countries but this year we had a much more international event with people from Austria, Belgium, Finland, Germany, Spain, & the UK in attendance.

Patchy, the sprint whale. Unofficial @drupalaton mascot with @ChandeepKhosa @brynvertesi @rteijeiro pic.twitter.com/AxydLT3JiO

- Bryn Vertesi (@brynvertesi) August 9, 2014

The team that made it happen

Tamás 'York' Pintér, was the main organiser and lives in the area of the camp, Zsófi Major co-ordinated many aspects of the event including community outreach over social media & sponsorship management, István Csáki, helped to create the website and other support, Bálint Fekete, made some amazing design work (in particular the innovative scroll on the website where the boat moves across the page which I spent far too long playing with!).

Also on the team were Gábor Hojtsy, (Drupal 8 multilingual initiative lead) helping with event-marketing, István 'PP' Palócz who helped with finances (and helped me learning some basic Hungarian phrases) and last but not least Tamás 'TeeCee' Szügyi, the photographer who documented the great event.

Some numbers

In the recent newsletter to all attendees from the organisers the following statistics were disclosed.

"We are really proud of the following numbers, so let us share with you:
Our 79 attendees came from 13 countries from all over the world, and only a bit more than half of them were from Hungary. This lucky number is significant for us, as Drupalaton started as a local Drupalcamp, and now we can proudly say that we are on the big Drupalmap :)"

  • You spent more than 1420 minutes (almost 24 hours) on 8 workshops with learning.
  • The sprinters worked on 70+ issues during the 4 days. This a great number, you can find more thoughts about it in Gábor Hojtsy's blog post.
  • During the 4 days you consumed 134 pcs of Túró Rudis, 132 ps of Marzipan ladybugs, 260 cans of beer, 60 kilograms of different fruits and 7 kilograms of nuts."

Next year

If any of that sounds good you should attend next year, 6-9 August 2015, I'm very excited about returning. Even the founder of Drupal, Dries Buytaert, regrets not attending! Maybe he will join us too next year, that would be awesome!

Photos from Drupalaton: https://t.co/TP0ARVawzb Wish I could have been there!

- Dries Buytaert (@Dries) August 11, 2014

Check out the pictures from Flickr below, or on Twitter and the Facebook page!

11 Sep 2014 3:22pm GMT

Drupal 8 Rules: #d8rules updates, BoF & sprints at DrupalCon Amsterdam

Hello everyone!

DrupalCon Amsterdam is coming close and we are working hard to get Milestone 1 for porting the Rules module to Drupal 8 done. Here's an outline where you can join fago, klausi, nico and many others for updates on the initiative, discussions and hands-on during the sprints!

#d8rules at DrupalCon Amsterdam

Drupal 8 Contrib Module Update (shared session)

Tuesday · 14:15 - 15:15, Room: Auditorium (Wunderkraut)
https://amsterdam2014.drupal.org/session/drupal-8-contrib-module-update

A quick, 12-minutes update on the status of Rules for Drupal 8 together with Webform (quicksketch), Display Suite (by aspilicious), Media (by daveried/slashrsm), Search API (by drunken monkey), Commerce (by bojanz), Redirect, Global Redirect, Token, Pathauto (by berdir), Panels (by japerry) & Simplenews (by miro_dietiker/ifux).

#d8rules initiative meeting (BoF)

Thursday 13:00 - 14:00, Room: Emerald Lounge E
https://amsterdam2014.drupal.org/bof/d8rules-initiative-meeting

Let's get into a deeper discussion about the #d8rules initiative in this birds-of-a-feather session. We'll inform you about the current state of funding & development and prepare you well for the sprints on Friday.

#d8rules sprints

Friday 9:00 - 18:00, Coder lounge in the venue
https://groups.drupal.org/node/427578

Sprinting at DrupalCon is THE way to learn about contributing to Drupal in general. With our training experience from DrupalCamp Alpe-Adria and Drupalaton we know that working on Rules 8.x is a great way to get started with the new programming paradigmes of Drupal 8. Join fago, klausi to port actions, fix integrations for Drupal 8 core and get Milestone 1 done in general.

#d8rules sprints are focused mainly on Friday, but we will also be around for extended sprints prior and after the conference. Check out the information about all the sprints at and around DrupalCon Amsterdam by gabor. And please don't forget: thank you for helping us estimate the number of people attending and sign-up using the sprints spreadsheet.

sprints
#d8rules trainings & sprints at DrupalCamp Alpe-Adria, Slovenia, May 2014

We are looking forward meeting everyone there. As always, you can find us on irc: #drupal-rules and don't forget to use the twitter hashtag #d8rules.

dasjo on behalf of the #d8rules team

11 Sep 2014 11:05am GMT

InternetDevels: Thanks for the great time at Lviv Euro DrupalCamp 2014!

Four months of preparation. Three golden sponsors. Two days. One Lviv Euro Drupal Camp 2014.

Ladies and gentleman, we can proudly announce - we did it! Our camp became the biggest Drupal-evet taking place in Ukrane this year, which got together the most cheerful and friendly drupalers. We hope, that all those 150 people have got a huge pile of positive emotions and impressions. But let's get in details inch by inch :).

Read more

11 Sep 2014 6:55am GMT

10 Sep 2014

feedDrupal.org aggregator

Dcycle: An approach to code-driven development in Drupal 8

What is code-driven development and why is it done?

Code-driven development is the practice of placing all development in code. How can development not be in code?, you ask.

In Drupal, what makes your site unique is often configuration which resides in the database: the current theme, active modules, module-specific configuration, content types, and so on.

For the purpose of this article, our goal will be for all configuration (the current theme, the content types, module-specific config, the active module list...) to be in code, and only content to be in the database. There are several advantages to this approach:

  • Because all our configuration is in code, we can package all of it into a single module, which we'll call a site deployment module. When enabled, this module should provide a fully workable site without any content.
  • When a site deployment module is combined with generated content, it becomes possible to create new instances of a website without cloning the database. Devel's devel_generate module, and Realistic Dummy Content can be used to create realistic dummy content. This makes on-ramping new developers easy and consistent.
  • Because unversioned databases are not required to be cloned to set up new environments, your continuous integration server can set up new instances of your site based on a known good starting point, making tests more robust.

Code-driven development for Drupal 7

Before moving on to D8, let's look at a typical D7 workflow: The technique I use for developing in Drupal 7 is making sure I have one or more features with my content types, views, contexts, and so on; as well as a site deployment module which contains, in its .install file, update hooks which revert my features when needed, enable new modules, and programmatically set configuration which can't be exported via features. That way,

  • incrementally deploying sites is as simple as calling drush updb -y (to run new update hooks).
  • deploying a site for the first time (or redeploying it from scratch) requires creating the database, enabling our site deployment module (which runs all or update hooks), and optionally generating dummy content if required. For example: drush si -y && drush en mysite_deploy -y && drush en devel_generate && drush generate-content 50.

I have been using this technique for a few years on all my D7 projects and, in this article, I will explore how something similar can be done in D8.

New in Drupal 8: configuration management

If, like me, you are using features to deploy websites (not to bundle generic functionality), config management will replace features in D8. In D7, context is used to provide the ability to export block placement to features, and strongarm exports variables. In D8, variables no longer exist, and block placement is now exportable. All of these modules are thus no longer needed.

They are replaced by the concept of configuration management, a central API for importing and exporting configuration as yml files.

Configuration management and site UUIDs

In Drupal 8, sites are now assigned a UUID on install and configuration can only be synchronized between sites having the same UUID. This is fine if the site has been cloned at some point from one environment to another, but as mentioned above, we are avoiding database cloning: we want it to be possible to install a brand new instance of a site at any time.

We thus need a mechanism to assign the same UUID to all instances of our site, but still allow us to reinstall it without cloning the database.

The solution I am using is to assign a site UUID in the site deployment module. Thus, in Drupal 8, my site deployment module's .module file looks like this:

/**
 * @file
 * site deployment functions
 */
use Drupal\Core\Extension\InfoParser;

/**
 * Updates dependencies based on the site deployment's info file.
 *
 * If during the course of development, you add a dependency to your
 * site deployment module's .info file, increment the update hook
 * (see the .install module) and this function will be called, making
 * sure dependencies are enabled.
 */
function mysite_deploy_update_dependencies() {
  $parser = new InfoParser;
  $info_file = $parser->parse(drupal_get_path('module', 'mysite_deploy') . '/mysite_deploy.info.yml');
  if (isset($info_file['dependencies'])) {
    \Drupal::moduleHandler()->install($info_file['dependencies'], TRUE);
  }
}

/**
 * Set the UUID of this website.
 *
 * By default, reinstalling a site will assign it a new random UUID, making
 * it impossible to sync configuration with other instances. This function
 * is called by site deployment module's .install hook.
 *
 * @param $uuid
 *   A uuid string, for example 'e732b460-add4-47a7-8c00-e4dedbb42900'.
 */
function mysite_deploy_set_uuid($uuid) {
  \Drupal::config('system.site')
    ->set('uuid', $uuid)
    ->save();
}    

And the site deployment module's .install file looks like this:

/**
 * @file
 * site deployment install functions
 */

/**
 * Implements hook_install().
 */
function mysite_deploy_install() {
  // This module is designed to be enabled on a brand new instance of
  // Drupal. Settings its uuid here will tell this instance that it is
  // in fact the same site as any other instance. Therefore, all local
  // instances, continuous integration, testing, dev, and production
  // instances of a codebase will have the same uuid, enabling us to
  // sync these instances via the config management system.
  // See also https://www.drupal.org/node/2133325
  mysite_deploy_set_uuid('e732b460-add4-47a7-8c00-e4dedbb42900');
  for ($i = 7001; $i < 8000; $i++) {
    $candidate = 'mysite_deploy_update_' . $i;
    if (function_exists($candidate)) {
      $candidate();
    }
  }
}

/**
 * Update dependencies and revert features
 */
function mysite_deploy_update_7003() {
  // If you add a new dependency during your development:
  // (1) add your dependency to your .info file
  // (2) increment the number in this function name (example: change
  //     change 7003 to 7004)
  // (3) now, on each target environment, running drush updb -y
  //     will call the mysite_deploy_update_dependencies() function
  //     which in turn will enable all new dependencies.
  mysite_deploy_update_dependencies();
}

The only real difference between a site deployment module for D7 and D8, thus, is that the D8 version must define a UUID common to all instances of a website (local, dev, prod, testing...).

Configuration management directories: active, staging, deploy

Out of the box, there are two directories which can contain config management yml files:

  • The active directory, which is always empty and unused. It used store your active configuration, and it is still possible to do so, but I'm not sure how. We can ignore this directory for our purposes.
  • The staging directory, which can contain .yml files to be imported into a target site. (For this to work, as mentioned above, the .yml files will need to have been generated by a site having the same UUID as the target site, or else you will get an error message -- on the GUI the error message makes sense, but on the command line you will get the cryptic "There were errors validating the config synchronization.").

I will propose a workflow which ignores the staging directory as well, for the following reasons:

  • First, the staging directory is placed in sites/default/files/, a directory which contains user data and is explicitly ignored in Drupal's example.gitignore file (which makes sense). In our case, we want this information to reside in our git directory.
  • Second, my team has come to rely heavily on reinstalling Drupal and our site deployment module when things get corrupted locally. When you reinstall Drupal using drush si, the staging directory is deleted, so even if we did have the staging directory in git, we would be prevented from running drush si -y && drush en mysite_deploy -y, which we don't want.
  • Finally, you might want your config directory to be outside of your Drupal root, for security reasons.

For all of these reasons, we will add a new "deploy" configuration directory and put it in our git repo, but outside of our Drupal root.

Our directory hierarchy will now look like this:

mysite
  .git
  deploy
    README.txt
    ...
  drupal_root
    CHANGELOG.txt
    core
    ...

You can also have your deploy directory inside your Drupal root, but keep in mind that certain configuration information are sensitive, containing email addresses and the like. We'll see later on how to tell Drupal how it can find your "deploy" directory.

Getting started: creating your Drupal instance

Let's get started. Make sure you have version 7.x of Drush (compatible with Drupal 8), and create your git repo:

mkdir mysite
cd mysite
mkdir deploy
echo "Contains config meant to be deployed, see http://dcycleproject.org/blog/68" >> deploy/README.txt 
drush dl drupal-8.0.x
mv drupal* drupal_root
cp drupal_root/example.gitignore drupal_root/.gitignore
git init
git add .
git commit -am 'initial commit'

Now let's install our first instance of the site:

cd drupal_root
echo 'create database mysite'|mysql -uroot -proot
drush si --db-url=mysql://root:root@localhost/mysite -y

Now create a site deployment module: here is the code that works for me. We'll set the correct site UUID in mysite_deploy.install later. Add this to git:

git add drupal_root/modules/custom
git commit -am 'added site deployment module'

Now let's tell Drupal where our "deploy" config directory is:

  • Open sites/default/settings.php
  • Find the lines beginning with $config_directories
  • Add $config_directories['deploy'] = '../deploy';

We can now perform our first export of our site configuration:

cd drupal_root
drush config-export deploy -y

You will now notice that your "deploy" directory is filled with your site's configuration files, and you can add them to git.

git add .
git commit -am 'added config files'

Now we need to sync the site UUID from the database to the code, to make sure all subsequent instances of this site have the same UUID. Open deploy/system.site.yml and find UUID property, for example:

uuid: 03821007-701a-4231-8107-7abac53907b1
...

Now add this same value to your site deployment module's .install file, for example:

...
function mysite_deploy_install() {
  mysite_deploy_set_uuid('03821007-701a-4231-8107-7abac53907b1');
...

Let's create a view! A content type! Position a block!

To see how to export configuration, create some views and content types, position some blocks, and change the default theme.

Now let's export our changes

cd drupal_root
drush config-export deploy -y

Your git repo will be changed accordingly

cd ..
git status
git add .
git commit -am 'changed theme, blocks, content types, views'

Deploying your Drupal 8 site

At this point you can push your code to a git server, and clone it to a dev server. For testing purposes, we will simply clone it directly

cd ../
git clone mysite mysite_destination
cd mysite_destination/drupal_root
echo 'create database mysite_destination'|mysql -uroot -proot
drush si --db-url=mysql://root:root@localhost/mysite_destination -y

If you visit mysite_destination/drupal_root with a browser, you will see a plain new Drupal 8 site.

Before continuing, we need to open sites/default/settings.php on mysite_destination and add $config_directories['deploy'] = '../deploy';, as we did on the source site.

Now let the magic happen. Let's enable our site deployment module (to make sure our instance UUID is synched with our source site), and import our configuration from our "deploy" directory:

drush en mysite_deploy -y
drush config-import deploy -y

Now, on your destination site, you will see all your views, content types, block placements, and the default theme.

This deployment technique, which can be combined with generated dummy content, allows one to create new instances very quickly for new developers, testing, demos, continuous integration, and for production.

Incrementally deploying your Drupal 8 site

What about changes you make to the codebase once everything is already deployed. Let's change a view and run:

cd drupal_root
drush config-export deploy -y
cd ..
git commit -am 'more fields in view'

Let's deploy this now:

cd ../mysite_destination
git pull origin master
cd drupal_root
drush config-import deploy -y

As you can see, incremental deployments are as easy and standardized as initial deployments, reducing the risk of errors, and allowing incremental deployments to be run automatically by a continuous integration server.

Next steps and conclusion

Some aspects of your site's configuration (what makes your site unique) still can't be exported via the config management system, for example enabling new modules; for that we'll use update hooks as in Drupal 7. I'm still having some errors doing this in D8, but I'm working on it!

Also, although a great GUI exists for importing and exporting configuration, I chose to do it on the command line so that I could easily create a Jenkins continuous integration job to deploy code to dev and run tests on each push.

For Drupal projects developed with a dev-stage-prod continuous integration workflow, the new config management system is a great productivity boost.

Tags:
blog
planet

10 Sep 2014 8:28pm GMT

Acquia: Mike Meyers explains – Help Drupal and it will help you: contribute!

Michael E. Meyers, VP Large Scale Drupal at Acquia, knows better than most how contributing to the open source project you are relying on to build or improve your business will pay off. He and his team did just that when they successfully built and sold NowPublic.com - the first venture capital funded, Drupal-based startup - while making massive contributions to the Drupal project along the way.

He and I invite you not only to use Drupal, but also to make it better and to get involved with its community. If you're only using it without giving back, you're not getting the full benefit it could be giving you. Come to DrupalCon Amsterdam or an event near you and make a difference!

10 Sep 2014 7:20pm GMT

Isovera Ideas & Insights: Drupal Commerce Tips: Implementing SimpleXML to Generate Invoice Files

Part 1 - Implementing SimpleXML to generate Invoice files

As part of the work with one of our E-Commerce clients it was a requirement to integrate with the RetailPro back-office tool. While the following post is specific to the RetailPro files and system. This same techniques could easily be re-purposed to help integrate various other systems that require invoice files to be sent to a 3rd party system.

10 Sep 2014 6:46pm GMT

ThinkShout: Nonprofit Website Benchmarks

Your website is a unique snowflake with singular requirements. While there's surely overlap, the make-up of your audience is different from every other site, because your mission - and the content you put on your website to support that mission - is different from every other nonprofit.

But you've probably wondered how your site compares to others. I know I've always wanted access to website benchmarks - some way to see if the trends I notice in our own dashboards are reflective of larger patterns.

Of course, benchmarks can be dangerous. If you obsess about them, the action becomes whatever the opposite of navel gazing is.

When you analyze the efficacy of your own website, you always need to consider it within the context of your own target audiences and organizational goals instead of worrying that your overall bounce rate is 4% higher than the "average."

After all, if your site has the profile of a news organization, with links to recent articles shared widely through third-party channels, you should expect a higher bounce rate: people come, consume, and leave. That might be okay! The goal of that content may have been to spread some news, not generate donations.

Benchmarks can inform us about larger trends, though, and it's damned annoying that they're so hard to find.

It's been almost four years since Groundwire published its 2010 Website Benchmarks Report. (Fortunately, you can still download the PDF from a third-party site.) Since then, Google has discontinued its Analytics Benchmarks Report - and even the semi-useful newsletter that followed.

You can order a $395 report from Marketing Sherpas (PDF), which may or may not be helpful; I certainly didn't buy it. KISSmetrics published an infographic about bounce rates a couple of years ago with some interesting data… that may have come from a 2006 post to a Yahoo group.

Pew Research recently released an interesting study comparing news sites, using aggregated data from ComScore. I love how they've analyzed visitor loyalty across segments, but rare is the nonprofit that's going to share the content goals of CNN or NBC News.

On our side, there are a couple of stats of interest in the latest Benchmarks Study from M+R and NTEN and the 2013 Online Marketing Benchmark Study for Nonprofits from Blackbaud, but they're mostly focused on traffic growth and donation page conversions.

At ThinkShout, because we start almost all of our engagements by exploring how our client's audiences use their current website, we felt it would be important to have some point of comparison. To facilitate discussion around questions like "How much do we need to worry about mobile?" or "How can we convert the influx of new visitors into engaged users?", we've aggregated the data we have available to us.

It seems only fair to share some of it.

This data is in no way reflective of the industry as whole, and it is very top-level. It represents fifteen organizations with diverse missions and traffic patterns, ranging from a few thousand sessions per month to more than 100,000. These are also generally organizations that have recognized the need to redesign their website.

With those caveats, we hope this data may help you understand that some of what you see in your own analytics may, in fact, be reflective of broader trends.

The following are three I see in the 37,000,000 pageviews we have access to.

Search Is the Ultimate Shortcut

Back in 2010, Groundwire found that search engines referred 55% of traffic to the nonprofit websites in their study. While we can't do a direct comparison since the sites in question aren't the same, I feel comfortable making the blanket statement that the trend is toward more traffic coming from search.

Here are the mean / median numbers since 2011:

benchmark1.png

So far in 2014, those numbers have increased to 55% (mean) / 60% (median).

That means, of course, that traffic from the other two legs of the standard triumvirate have dropped:

benchmark2.png

benchmark3.png

Essentially, the best home page ever created will not solve your problems, as your users are more and more likely to turn to search first to find what they're looking for. Your information architecture must take into account the fact that the first page your visitors encounter may be deep in your website.

User Experience starts in the first place your users experience you. You can use your data to make some assumptions about where that's mostly likely to happen and optimize the top landing pages, but, more and more, you need to worry about every piece of content on your site.

Stop Wondering if Mobile Is Important Right Now

It is. Groundwire found that in 2010, the median number of mobile visitors to the sites in their study was just 1%. That's changed over the past few years. Looking just at mobile phones (not tablets), you can see the surge:

benchmark4.png

I've seen the argument made that mobile doesn't require your attention quite yet because it still represents, according to this data, just 1 in 5 visits.

Our suggestion would be to get ahead of the curve instead of fighting to catch up. The growth in mobile traffic is having an obvious impact on the most basic measures of engagement.

Mean Median
Year Bounce Rate Time per Session Pages per Session Bounce Rate Time per Session Pages per Session
2011 62.30% 2:04 2.30 67.07% 1:57 2.09
2012 66.17% 1:58 2.06 67.20% 1:56 1.89
2013 70.48% 1:54 1.87 70.10% 1:39 1.84

[I've excluded 2014 because I haven't cleaned out the data from sites that have gone through a responsive redesign. This isn't meant to be a marketing piece, but I can tell you that redesigning for mobile can have a significant impact.]

My suspicion is that as people grow more comfortable using their smartphones to browse the Internet, visiting brands that have implemented a mobile strategy, they're less likely to put up with sites that don't work as well as they expect in their mobile browsers.

By structuring your content properly, you can create ways to put the content mobile users are most interested in front and center. If nothing else, you should take the time to understand what mobile visitors are doing on your site as a first step.

Loyalty Is Hard to Come By (or Even Define)

Perhaps, given the growth in search and mobile traffic, it's no surprise that the percentage of "New" visitors has increased over the years:

benchmark5.png

On the flip side, "Loyal" visitors (defined as those with at least three visits in the period under review) have crashed:

benchmark6.png

And those numbers aren't just relative percentage drops, caused by increases in other types of traffic, because the real numbers have dropped as well:

I'm fairly confident, given the scale of the data, that this isn't simply because people are getting better at clearing their cookies regularly - there's wide variation in estimates, much of it from surveys of user behavior, rather than actual data - or browsing the web incognito. Those technologies have been around for years, and I doubt even Mr. Snowden has had that much of an impact on people's everyday habits. (But I'm willing to be convinced otherwise.)

This loss could also be reflective of device fragmentation. Google and others are working on ways to track users across the many devices they use, but right now, if somebody visits you on August 14th on their laptop, comes back on September 9th on their tablet, and then again on October 21st on their phone, they would be classified as three different New users. As we see mobile traffic grow, it may mean that right now, we don't have an accurate way to track visitor loyalty.

Perhaps some of that loyalty is being transferred elsewhere, however, from the website to social spaces, third party donation pages, or even mobile apps. In that case, the better sites are at converting website visitors into these different kinds of traffic, the less relevant the website will become to them.

Rare is the constituent who comes once a year to donate. Engagement, even within a multi-channel strategy, has to strike a balance between assuming that visitors will find continued value from the resources we make available on the web and moving new visitors to spaces where they're more likely to continue to interact with us and each other.

In any case, if visitors are increasingly less likely to return to nonprofit websites, we need to rethink some of our engagement strategies. If they're turning elsewhere because they aren't finding what they want, when they want it, we've got some serious work to do.

Interested in Helping Out?

I've made the spreadsheet with the cleaned data for 2011-2013 publicly available. We hope you'll check it out and add insights of your own!

But beyond using it as a tool to inform your own website, we could use your help. What other data should we track and share? What do you want to know?

And more importantly, are you willing to share your own?

If you'd like to work with us on a template that can be used to collect data from other nonprofits, just let me know. We'll keep the org-by-org breakdown anonymous. Once we reach an arbitrarily large threshold - 100,000,000 pageviews? - we can do some follow-up work.

Lev Tsypin, ThinkShout's Director of Engineering, has suggested that we could go so far as to set up a Google form that feeds an anonymized spreadsheet. We could then make that data available via JSON, for further manipulation.

In the end, I believe that the more we aggregate and share, the better we'll identify the problem areas we need to focus on as a community.

10 Sep 2014 4:00pm GMT

Drupal Watchdog: Extending Drupal 7 Services into an E-commerce App

Article

Shopping Cart DesignBy now, you've surely heard that Drupal 8 is pushing boundaries for users, content editors, administrators, and developers - if not, where have you been?

Obviously, not every site has the luxury of being able to migrate and adopt new technologies. If you are in the same position as me, then many of your clients - or indeed, the company you work for - have spent lots of time and money investing in Drupal 7; at this point, urging a new platform on them is probably going to fall on deaf ears. But all is not lost! Drupal 7 can still create a powerful RESTful Web Service API or a terrific mobile application.

So the old adage again rings true: "Where there is a Drupal 8 core initiative, there is a Drupal 7 contributed module."

Having attended the Commerce 2.x sprint in Paris, I can safely say that if you do eventually upgrade to Drupal 8, it won't be a massive undertaking molding your Drupal 8 Core services output to match that of Drupal 7 contrib services. Not all your work will be lost.

When I first started down the road of mobile apps, I was certain I did not have the time to learn Objective C and Java, as well as the intricacies of each mobile platform. (Sound familiar?) All I wanted was the ability to utilize the Drupal technology I already knew, and then enable PhoneGap without having to learn any device-specific language.

For purposes of this article, I won't assume you know mobile apps technology nor much about Drupal's Services module, REST, jQuery Mobile, Xcode, or PhoneGap. I do assume that you know Drupal, can work your way around the administration interface, and know some basic PHP and Javascript. With that in mind let's take an overview of technologies you can utilize for your mobile application.

First, let's install DrupalGap and its dependencies.

Now we have a core DrupalGap service and the basic service resources we might want for our mobile application. All the generic things we use on most Drupal sites are right there: resources are content-available for query through endpoints; and DrupalGap supplies us with a default endpoint.

10 Sep 2014 3:03pm GMT