Author

Aug 25 2016
Aug 25

Matt and Mike are joined by Andrew Berry, Juampy NR, Mateu Bosch, and Dave Reid to deep dive into Drupal 8 development. We talk best practices, IDE Plugins, tips, tricks and lots more.

Lullabot developers sitting around the table recording the podcastClockwise from top left: Juampy, Dave, Andrew, Matt, Andrew (again), Dave (again), Juampy (again), and Mateu

Andrew Berry’s PHPStorm Plugins (as promised in the podcast)

Note: Some of these are distributed by JetBrains directly, and don’t have links in their PHPStorm info. In general, install plugins from within the preferences instead of downloading them from the web.

Aug 25 2016
Aug 25
Lots of people think that template engines like Twig cannot be interactively debugged. I heard this several times as an argument against template engine, and for using legacy php processing like phptemplate (standard in Drupal 7).Well, it’s not entirely true. And even more, debugging Twig is not only easy, but you will also get much more information about what your template is doing!
Aug 25 2016
Aug 25

About Me

With 15 years of experience in the Information Technology field, and 10 of those years focused on leadership, I’ve learned first hand the value of investing in people and setting them up for success. Before joining Mediacurrent, I started a QA department from scratch and grew it to its current size. Prior to that, I built an IT team. If you're an incoming leader, here's how to start building your own QA/IT department. 

Too Busy to Hire?

So you have established your department, written some procedures and notice things are improving. You are now ready for your first hire. Well at least you think you are, but how do you know?

First we want to begin to examine your workload. With an additional hire, will you have enough of a break both financially and timewise to properly lead a department? Not only is it important to set yourself up for success, but you also need to properly invest in whoever you hire to set them up to succeed. An absent leader is a source of frustration for departmental team members and can lead to a high turnover rate, or simply poor decision making due to lack of a shared vision.

Communicate to Build Trust

That being said, though it is good for a leader to be active in their employees work life, there is a strong difference between leading and micro managing. If you constantly ask, “what are you working on? Why are you doing it like that? When will you be done?” You come off as pestering which will only lead to your employee becoming more and more frustrated.

Why is that bad? You need the information and they report to you, right? Well, let’s first break down the language and meaning behind it. You hired them because you feel they are competent in their role and you trust their abilities. When you barrade them with questions or directions on a day to day basis, then you portray a lack of “said” trust which degrades the employee on a professional level and can build resentment.

A better way to communicate is to schedule checkins with the employee at a time that best suits your business, whether it be daily, weekly or monthly intervals. Allow the employee the chance to bring issues, road blocks and general project updates to you before you go fishing for the status updates. By doing this you allow the person to act within a professional manner and over time learn what information you want and how you want it, all without making them feel like they are under your thumb, so to speak.

If you haven’t noticed yet, the running theme to running a successful department is building that foundation of trust with your employees. When they know you trust them and their work ethics, they will work harder and more efficiently. Also, with your already busy schedule you don’t want to form a dependency to where an employee feels they need to check with you before doing anything.

Balance Management and Leadership

Earlier, I said not to be a leader who is never around, and then I talked about not being there too much. So what is the balance? Well again you want to setup checkins with your employees in either 1 on 1 or group setting to gather the input/update, but that isn’t enough. Make sure you have an open door policy so that employees know they have someone to go to should an issue arise needing attention. If you are unable to maintain a constant open door, that is understandable, but you need to at least attempt to keep a designated time open on your calendar for employees to reach out and be heard. Finding that balance is something you will have to approach carefully as different employee personalities require different levels of availability and leadership.

Now you have established yourself as a leader who is there for their employees but is not a micromanager. This is good for the most part, but what happens when you need to implement discipline or correct behavior? You need to take a position of authority but you don’t want to destroy all of the trust you have built up. This is where a coaching style of leadership comes into play.

Play The Role of The “Coaching Manager”

When you correct a behavior, it is best to not immediately (unless absolutely necessary) correct the employee. If you do this, it will almost always come off as a knee jerk reaction and it doesn’t give you enough time to take all factors of what caused the incident into consideration. At the same time, you can not wait too long or you risk the employee losing sight of all the contributors to their behavior. The best example comes from a book The Coaching Manager. If something were to happen in a hospital’s operating room, the doctor can’t snap at the nurse right away nor can they wait until the next day to come down on them. The best time to discuss the issue is after everything is calmed down, in the hallway on the same day.

It is different with every employee but the one constant to remember as a “coaching manager” is to allow the employee to come up with the way it “should” have happened. No, I don’t mean let the employee dictate your decision, but instead lead them to the choice you believe they should have made instead by asking them the right questions, “What do you think went well? What do you think went wrong? How could you have handled that differently?” etc. In situations like this that are hopefully few and far between it is okay to ask this style of question and still not come across as a micromanager. This method helps the employee realize for themselves how they should have acted, maintain professionalism and in turn will commit it to memory far better than if you were to bark orders at them.

In closing, it is about being a servant leader, a person who is there when their employees need them, who treats them as the trusted professionals they are and by doing so will earn the trust of your department that you have their best interest in mind and are setting them up for success. Accomplish this, and you will find that employees will work harder, smarter and show true passion for what they are doing because they know the impact they can make.

Additional Resources
Build Your QA Department - Part 1: Laying a Foundation | Blog Post
Friday 5: 5 Free QA Webtools | Video
Using VMs for Quick and Reliable QA | Blog Post

Aug 25 2016
Aug 25

One of the "late to the party" features of Drupal 8 is the ability to assign the same block to multiple locations in the theme. Drupal 7 still lacks this feature in the core, but it's easy to achieve it by using a contributed module such as MultiBlock.

While it works out of the box with all modules that provide blocks, you will need to modify your code in order to allow administrators to have separate configuration for each block instance. The official documentation for MultiBlock module is lacking and there was no straightforward example on what exactly you need to do in code. In this article I'll show how to integrate your custom module with MultiBlock and have different configuration for each instance of your block.

To continue, you can clone the Blank Module boilerplate. It will make it easier to create a new empty module and start coding immediately.

MultiBlock adds an extra page in the block admin section where you can create instances of existing blocks. Out of the box it works with all blocks but it does not allow you to have different configuration between instances. To achieve this, we must let MultiBlock know that our module can be integrated with it and add some extra code for fetching information related to the current instance.

Here's what we need to do in code:

  1. Implement hook_block_info(). To integrate with MultiBlock, we have to pass one extra key in the block array (mb_enabled) and set its value to TRUE.
    This will make MultiBlock instance ID available to us in hook_block_view() and hook_block_configure(), so we can use it for fetching configuration specific to the current instance.
  2. Implement hook_block_view(). MultiBlock will pass us instance ID only for blocks that integrate with MultiBlock.
  3. Implement hook_block_configure(). Just like above, we will get one extra argument with instance ID. Since the instance ID will not be provided by MultiBlock in the hook_block_save(), we will have to store it in the form as a hidden value.
  4. Implement hook_block_save(). Here we will just check if the instance ID is passed in the form, and store the settings under appropriate ID.

Below is full code. Do note that the $edit value provided by MultiBlock module will contain the value in the hidden field format (for whatever reason).

/**
 * Implements hook_block_info().
 */
function YOUR_MODULE_block_info() {
  $blocks = array();

  // This is the block name.
  $blocks['sample']['info'] = t('Sample Block');
  // We have to enable administrative interface for configuring our block.
  $blocks['sample']['properties']['administrative'] = TRUE;
  // Enable MultiBlock integration.
  $blocks['sample']['mb_enabled'] = TRUE;

  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function YOUR_MODULE_block_view($delta = '', $edit = NULL) {
  $block = array();
  switch ($delta) {
    case 'sample':
      $block['subject'] = NULL;
      // Check if multiblock module is in use.
      $prefix = '';
      if ($edit && isset($edit['multiblock_delta']['#value'])) {
        $prefix = '_' . $edit['multiblock_delta']['#value'];
      }
      $block['content'] = variable_get('YOUR_MODULE_block_config' . $prefix . '_text');

      return $block;
  }
}

/**
 * Implements hook_block_configure().
 */
function YOUR_MODULE_block_configure($delta = '', $edit = NULL) {
  $form = array();

  switch ($delta) {
    case 'sample':
      // If MultiBlock is installed, pass the delta as a hidden value so we can
      // retrieve the correct variable from the database in hook_block_save()
      // implementation.
      $prefix = '';
      if ($edit && isset($edit['multiblock_delta'])) {
        $form['multiblock_delta'] = array(
          '#type' => 'value',
          '#value' => $edit['multiblock_delta']['#value'],
        );
        $prefix = '_' . $edit['multiblock_delta']['#value'];
      }
      $form['sample'] = array(
        '#type' => 'fieldset',
        '#title' => t('Block configuration'),
      );
      $form['sample']['text'] = array(
        '#type' => 'textfield',
        '#title' => t('Enter some text'),
        '#required' => TRUE,
        '#default_value' => variable_get('YOUR_MODULE_block_config' . $prefix . '_text'),
      );

      return $form;
  }
}

/**
 * Implements hook_block_save().
 */
function YOUR_MODULE_block_save($delta = '', $edit = array()) {
  switch ($delta) {
    case 'sample':
      $prefix = ($edit['module'] == 'multiblock') ? '_' . $edit['delta'] : '';
      variable_set('YOUR_MODULE_block_config' . $prefix . '_text', check_plain($edit['text']));
      break;
  }
}

After enabling your custom module, you can go to Structure -> Blocks -> Instances and create as many instances of your block as you need. Each one of them can have different text.

Bonus points: do remember to delete your variables when your module is uninstalled from the system. To do that, the following code would go to your .install file:

/**
 * Implements hook_uninstall().
 */
function YOUR_MODULE_uninstall() {
  // This is easiest approach because it will remove all variables at once.
  db_query("DELETE FROM {variable} WHERE name LIKE :variables", array(':variables' => 'YOUR_MODULE_%'));
}

See also:

Aug 25 2016
Aug 25

Drupal 8.2.0 will see a bunch of new experimental modules. Once of these is Content Moderation. This is a port of the Drupal 8 release of Workbench Moderation, with a number of updates to make it suitable for core.

Work is currently underway to get Content Moderation working for Workspaces. Workspaces, defined by the Workspace module and it’s dependency Multiversion, are a way of creating different versions of your site’s content and getting the elusive “full site preview” functionality. With Content Moderation you are able to moderate a whole Workspace. Then once published all content will be deployed to the live workspace.

The screencast below shows adding some content on the Stage Workspace and confirming the content doesn’t exist on the Live Workspace. Then publishing the Stage Workspace results in the content being on both Workspaces.

[embedded content]

Please enable JavaScript to view the comments powered by Disqus.

blog comments powered by
Aug 25 2016
Aug 25

on August 24th, 2016

How Zoomdata employees share insights into company life

Xeno Media is pleased to announce our latest Drupal 7 contrib module, Slack to Drupal.  This module imports pictures uploaded to Slack to Drupal 7 systems--thereby allowing a community of users to add content to a site while managing their daily business collaboration through the Slack app.

Zoomdata--who makes visual analytics software for big data--tasked us with coming up with a solution that allows their employees to submit images for the public website to share the company’s unique, engaging culture to aid in marketing and recruiting.  

Various source platforms, including Instagram, Flickr, and Twitter, were originally considered. As we surveyed Zoomdata employees, though, we realized that Slack was the ideal source. Slack is fundamental to Zoomdata’s work culture; Its 200 employees and contractors throughout North America and Europe actively collaborating on Slack on an ongoing basis. Leveraging Slack as the source platform would allow employees to submit images in real-time without breaking their typical work/collaboration workflows and methods.

With that settled, we started researching how to integrate.  Our developers researched Slack’s API and proposed two approaches: 1) Create a Slack “bot”--a virtual user that our human users could interface with. Or: 2) Integrate with a specific Slack channel.  We elected the later as we could more efficiently access the files in a specific channel and Zoomdata appreciated having a single destination channel for users to come to rather than clogging other channels with off-topic bot chatter.

With the Slack-side figured out, we worked on the Drupal development.  We are supporters of the Drupal Media initiative, and decided to integrate the the Drupal Media 7.x-2.0 File Entity as we do on many of our client sites.  The File Entity module creates an entity like a node for each file in the system.  This allows us to add fields, like Caption, Approval, Date, and Uploader.  It also allows us to use, and reuse the entities in the site on other pieces of content and create views of the entities.  We called this new entity Slack Image.

We also created an administration screen where an administrator can approve or disapprove images.  If images are disapproved, they are removed from the system and not imported again.  If approved, they are available where all the other File Entities are available.

For the Zoomdata public site, we created a view of the new Slack images that appears on their Careers page in a beautiful, modern, and responsive layout using Masonry Views, Colorbox, and GD infinite scroll plugin modules.

Our employees are always posting photos in Slack. I really wanted to share those photos with our customers, partners, prospective employees and vendors so they could get a view inside Zoomdata and know what a great team of people they’re partnering with. Jim, and the team at Xeno Media, made it possible by creating a fantastic Drupal website for us, and by developing Slack to Drupal.

Robyn Forman, Zoomdata’s VP of Digital Marketing.

Results so far have been very positive--with more than half of the company joining the channel and submissions coming from every office and department.  Through Slack to Drupal, employees from throughout the organization have shown what an engaged, fun, and cutting edge culture Zoomdata really is.

Aug 24 2016
Roy
Aug 24

We’re probably misusing the term MVP when we try to frame what we would like to see make it into core. But the actual mode of working we use there is quite an achievement. We used to grind it out endlessly, where proposed changes could be discussed endlessly, with a high risk of not committing anything at all in the end. What we’re doing now is: agree up front that it’s a good idea to improve feature X or rework interface Y. And then focus on keeping the scope as small as possible.

Yes, I, J and K are also good ideas, but we’re trying to do X here and while these are all related ideas and together would like make for a nicer whole, we should really focus on shipping X, and X alone, before turning our attention to I, J and K. If at all, because while shiny, interface Y actually presents people with more problems, so maybe we should focus on that. Though it’s never that strongly a case of either/or, and we should definately not stop iterating after the initial commit.

This is a very new and different way of working. Deliberately lowering our standards for the goal of introducing change. This is uncomfortable at times, but even that is good, because it means we’re stretching ourselves, which means we’re doing and learning new things. I’m excited and proud to see this happen. More like this.

Doing it like this means that Drupal 8.2:

  • Has content moderation tools (draft! review! publish! etc.)
  • Provides a new way to add new elements (blocks) to the page you’re on, without having to go to some far away corner in the admin section
  • Those elements (blocks! menus! logo & site name! etc.) can then also be configured in the context of the user facing page. A side tray will show up and expose the relevant settings.

Looking forward to learn how these additions will be received and how we can improve them. In the mean time, lets add more useful and usable things to 8.3 (sample content! media handling! better dates! etc).

Aug 24 2016
Aug 24

Thinking of coming to DrupalCon Dublin this year? Why not extend your trip by a few days and stay a bit longer to take in some of the fabulous things you can go do and see in Dublin?

Here's our recommended list of things to do and see while here:

1. Guinness Storehouse

Guinness barrels

Recently awarded the best tourism attraction in Europe accolade, the Guinness Storehouse tops our list of places to visit in Dublin.

At the Guinness Storehouse you can explore each of the seven floors in this pint-glass shaped building to see how Guinness is made, before finishing the tour at the Gravity Bar where you can enjoy a complimentary pint of the black stuff while overlooking panoramic views of the city.

2. Kilmainham Gaol

Kilmainham Gaol

Interested in history? Then be sure to stop by Kilmainham Gaol during your stay here. Leaders of various nationalist rebellions since 1798 were imprisoned here, and in some cases, executed, such as the seven signatories of the 1916 Proclamation of the Irish Republic.

This year we're commemorating the 100 year anniversary since the 1916 Easter Rising and Kilmainham Gaol is holding a special “1916 Portraits and Lives” exhibition.

3. Trinity College Dublin & the Book of Kells

Trinity College Dublin and the Book of Kells

Trinity College Dublin, one of Ireland's most well known third-level education institutions, is located in the heart of Dublin city. Founded by Queen Elizabeth in 1592, it contains a lot of history and many beautiful buildings. This includes the fabulous Long Room, a library containing many old and rare books, and inspired the Jedi Archives in the “Star Wars Episode II” movie.

Trinity offers many campus tours, which cover the Campanile and the Long Room but also includes admission to see the Book of Kells. The Book of Kells is a beautifully hand-illustrated manuscript of the four Gospels dating from around 800 AD.

4. Art Galleries

National Gallery of Ireland

There are a number of worthwhile art galleries in Dublin, most notable among which are the National Gallery of Ireland and the Irish Museum of Modern Art.

The National Gallery of Ireland houses more than 12,000 pieces of art, from paintings to prints and sculptures. It features work from Jack B. Yeats, Van Gogh, Monet and Caravaggio.

Meanwhile, the Irish Museum of Modern Art is Ireland's leading institution collecting modern and contemporary art. It is located in the former 17th century Royal Hospital building in Kilmainham, with its beautiful grounds containing a formal garden and medieval burial grounds.

Like many of the national museums, admission to both of these art galleries is free.

5. National Museum of Ireland

National Museum of Ireland

The National Museum of Ireland is split across four main campuses in Dublin and Mayo. Of these we would highly recommend the Decorative Arts and History museum in Collins Barracks. As the name might suggest, Collins Barracks was an army base for nearly 300 years before being renovated to become part of the National Museum. It is itself a historical place of interest and played a key base for the British troops in the 1916 Easter Rising. These days it showcases Ireland's economic, social, political and military progress through the ages.

Also worthwhile is the Archaeology museum campus on Kildare Street. It contains many excellent examples of Celtic and medieval art, including the Tara Brooch and Ardagh Chalice.

Again, entry to the National Museum of Ireland is free of charge.

6. Dublinia

Dublinia

Dublinia is fast becoming one of Dublin's most popular attractions. Located at Christchurch, it has four exhibitions on offer, which include learning more about Vikings and the Battle of Clontarf, life in Medieval Dublin, how archaeology works and a 96 step climb to the top of the medieval St. Michael's Tower for spectacular views over the city. This is worth a visit, and will keep kids entertained too.

7. National Leprechaun Museum

National Leprechaun Museum

So yes, this really does exist, and no, it's not as bad as you might think! The National Leprechaun Museum dedicates itself to Irish mythology and explores the world of Irish folklore and old stories. It offers an interactive and engaging experience for kids and adults alike, and offers visitors a deeper understanding of Irish culture and imagination.

8. Little Museum of Dublin

One of the newer museums in Dublin, the Little Museum of Dublin is worth a visit. Located in a Georgian townhouse on St. Stephen's Green and focusing on the 20th century, it should take you less than an hour to wander around. It contains 400 pieces of art, photography, letters and other artefacts from the era, offering unique insight into the life and changes in Dublin throughout the 20th century.

9. Cathedrals of Christ Church and St. Patrick's

Cathedral

Two of the most iconic cathedrals in Dublin are located a stone's throw away from each other, namely St. Patrick's Cathedral and Christ Church Cathedral.

St. Patrick's Cathedral, named after Ireland's patron saint, is one of the last remaining medieval buildings in Dublin, built between 1220 and 1260 AD and is the largest cathedral in Ireland. A number of well known people are buried on the site, including Jonathan Swift, author of Gulliver's Travels, who was also Dean here for a while. Try and visit during one of the choir's daily performances if you can.

Christ Church Cathedral on the other hand is Dublin's oldest building, with the oldest parts dating from around 1030 AD. It contains beautiful floor tiles and a distinctive archway (over what is quite a busy road these days). However, one of its most renowned features is its 12th century crypt, one of the oldest and largest in Ireland and the UK.

10. Dublin Castle

Dublin Castle

If you're after the classic castle, with moats, drawbridge, turrets or crenellations, then this is not the castle for you. While Dublin Castle dates back to the early 13th century (and is probably built over a much earlier defensive fort), much of what remains today is from the 18th century. The Record Tower is the only remaining building from the original medieval structure which has somehow miraculously survived.

If visiting the castle, be sure to take in the State Apartments, the Chester Beatty Library and the Dubhlinn Gardens, which cover the area where there was once a black pool or “dubh linn”, where is Dublin gets its name.

These days the castle is mainly used to host grand ceremonial or state functions, but is open to the public if no event is on.

Photo credits: ccharmon, Joe Loong, Rob Hurson, William Murphy, Ana Rey, Jolin 2013

Aug 24 2016
Aug 24

The TWG coding standards committee is announcing two coding standards changes for final discussion. These appear to have reached a point close enough to consensus for final completion. The new process for proposing and ratifying changes is documented on the coding standards project page.

Official coding standards updates now ratified:

Issues awaiting core approval:

Issues that just need a little TLC (you can help!):

These proposals will be re-evaluated during the next coding standards meeting currently scheduled for August 30th. At that point the discussion may be extended, or if clear consensus has been reached one or more policies may be dismissed or ratified and moved to the next step in the process.

Aug 24 2016
Aug 24

The TWG coding standards committee is announcing two coding standards changes for final discussion. These appear to have reached a point close enough to consensus for final completion. The new process for proposing and ratifying changes is documented on the coding standards project page.

Official coding standards updates now ratified:

Issues awaiting core approval:

Issues that just need a little TLC (you can help!):

These proposals will be re-evaluated during the next coding standards meeting currently scheduled for August 30th. At that point the discussion may be extended, or if clear consensus has been reached one or more policies may be dismissed or ratified and moved to the next step in the process.

Aug 24 2016
Aug 24

For anyone who's ever looked up a definition of a Drupal term and been left wondering what it all means, here are some practical real world explanations you can use to navigate the Drupalverse. Watch this space and use comments to send us your feedback and requests.

The Discipline of Dev Ops

Dev Ops, or Development Operations, is the intersection between IT managed hosting support and development. While it is a specialization in many organizations, senior developers, tech leads, and architects should be conversant in the various systems and tools to be used by your IT team or provider.

One of the primary goals of Dev Ops is to create standardized operating system iterations that are consistently reliable and easily replicable. Your unique infrastructure or hosting service plays a big role in these systems, which is why they tend to be customized to each project.

Standardized Dev Ops systems are used to create local and remote development environments, as well as staging and production environments, which all function in the same way. Having good Dev Ops systems in place means that your organization can support continuous development practices like version control and automated testing.

For any site that’s even moderately complex, having Dev Ops standards is huge. You don’t have to try to become a Dev Ops genius yourself: instead, you can find an organization like FFW to provide the level of Dev Ops help and support that is appropriate for the size and scope of your project.

Defining a Display

Displays, unlike Dev Ops, are a little simpler. A Display in Drupal typically refers to how queried data is organized and shown to visitors. It is usually used in connection with a native database query referred to as a View.

One View (or database query) can have several Displays sorted in different ways. For instance, a set of queried data can be output in the following ways:

  • a sortable table
  • a grid
  • as consecutive field sets
  • in a rotating banner
  • as a calendar or list of coming events
  • as points on a map

… and these are only just a few examples of the many different kinds of Displays.

The Details Around Distributions

A Distribution is a pre-developed assembly of database data, code, and files. Distributions commonly include saved content, configuration settings, Drupal core, contributed and custom modules, libraries, and a custom theme. It’s basically a pre-built Drupal site.

Most people first become acquainted with Distributions as different iterations of Drupal that are built for specific use cases or verticals, such as e-commerce or publishing. Many distributions are robust, production-ready applications that will save you tremendous work. They let you take advantage of the distribution sponsor’s subject matter expertise.

There are other kinds of distributions, such as ones developed mainly for marketing purposes to showcase what Drupal can do and how Drupal can be used. Both of these types of distributions have value, but it is important to differentiate between the two.

Distributions can be vetted in much the same way that a Drupal module or theme can be vetted. When evaluating a Distribution, I always like to ask the following questions:

  • Who are the contributors?
  • What is their experience?
  • Is the project actively maintained and are new features or versions planned?

The other primary consideration when vetting a Distribution is how much complexity and effort is required to ‘unravel’ a distribution. Many organizations have found that the more fully realized distributions are difficult to customize around their specific workflows and therefore are more expensive to change than starting fresh with a more basic version of Drupal.

If you want to know more about Distributions, I recommend looking at Drupal’s distribution project pages and this documentation page.

Aug 24 2016
Aug 24

In recent weeks we've been making several small changes to Drupal.org: precursors to bigger things to come. First, we moved the user activity links to a user menu in the header. Next, we're moving the search function from the header to the top navigation. These changes aren't just to recover precious pixels so you can better enjoy those extra long issue summaries—these are the first step towards a new front page on Drupal.org.

As the Drupal 8 life-cycle has moved from development, to release, to adoption, we have adapted Drupal.org to support the needs of the project in the moment. And today, the need of the moment is to support the adoption journey.

As we make these changes you'll see echoes of the visual style we used when promoting the release of Drupal 8.

  • The Drupal wordmark region will help to define Drupal, and promote trying a demo.

  • A ribbon will promote contextual CTAs like learning more about Drupal 8.

  • The news feed will be tweaked.

  • DrupalCon will have a permanent home on the front page.

  • Community stats and featured case studies will be carried over(but may evolve).

  • The home page sponsorship format may change.

  • We'll be phasing in a new font throughout the site: Ubuntu - which you've already seen featured in the new Documentation section.

Here's a teaser

… a sneak preview of some new page elements and styles you'll see in the new home page.  

Our first deployment will introduce the new layout and styles. Additional changes will follow as we introduce content to support our turn towards the adoption journey. Drupal evaluators beginning their adoption journey want to know who uses Drupal, and what business needs Drupal can solve. We will begin promoting specific success stories: solutions built in Drupal to meet a concrete need.

What's next?

We're continuing to refine our content model and editorial workflow for the new front page. You'll see updates in the Drupal.org change notifications as we get closer to deployment.

Wondering why we're making these changes now? This turn towards the adoption journey is part of our changing priorities for the next 12 months.

Aug 24 2016
Aug 24

Drutopia is an initiative within the Drupal project that prioritizes putting the best online tools into the hands of grassroots groups. By embracing the liberatory possibilities of free software and supporting people-centred economic models, Drutopia aims to revolutionize the way we work and cooperate.

Drutopia is at once an ethos of Drupal development and a fresh take on Drupal distributions for users to build upon, all based in a governance model that gives users a large role in the direction of the project.

Core values of the Drutopia initiative include:

  • Be inclusive regarding gender, gender identity, sexual orientation, ethnicity, ability, age, religion, geography and class.
  • Commit to protection of personal information and privacy and freedom from surveillance.
  • Put collaboration and cooperation above competition.
  • Prioritize human needs over private profit.
  • Foster non-hierarchical structures and collective decision-making.

Drutopia focuses on shared solutions. Drupal excels at providing the tools to develop and distribute specialized website platforms that can be freely shared, reused, and adapted. Of the three most-used free software content management systems (CMSs) – WordPress, Joomla!, and Drupal – only Drupal has the built-in ability to package and share highly developed distributions.

Distributions are essential in attracting and meeting the needs of groups that want to support the free software movement but don’t have the technical know-how or resources to create a site from scratch. For developers, too, distributions hold a lot of potential because they do the heavy lifting of initial setup, allowing developers and site builders to bypass many hours of unnecessary effort. Drupal distributions so far have been held back by a series of factors that Drutopia aims to address.

Drutopia is about returning to Drupal’s roots in free software and progressive social change. Since its founding years, the Drupal free software project has both reflected and contributed to the democratic potential of the internet: to empower citizens to freely collaborate and organize outside the control of governments and corporate media. Long before it powered Fortune 500 sites and whitehouse.gov, Drupal was a tool of choice for small, grassroots, change-oriented groups.

This initiative aims to reclaim Drupal for the communities and groups that have always been its core users and adopters and have contributed to much of its best innovation.

Join us at drutopia.org.

Aug 24 2016
Aug 24

The Winnipeg City’s NOW (Neighbourhoods Of Winnipeg) Portal is an initiative to create a complete neighbourhood web portal for its citizens. At the core of the project we have a set of about 47 fully linked, integrated and structured datasets of things of interests to Winnipegers. The focal point of the portal is Winnipeg’s 236 neighbourhoods, which define the main structure of the portal. The portal has six main sections: topics of interests, maps, history, census, images and economic development. The portal is meant to be used by citizens to find things of interest in their neibourhood, to learn their history, to see the images of the things of interest, to find tools to help economic development, etc.

The NOW portal is not new; Structured Dynamics was also its main technical contractor for its first release in 2013. However we just finished to help Winnipeg City’s NOW team to migrate their older NOW portal from OSF 1.x to OSF 3.x and from Drupal 6 to Drupal 7; we also trained them on the new system. Major improvements accompany this upgrade, but the user interface design is essentially the same.

The first thing I will do is to introduce each major section of the portal and I will explain the main features of each. Then I will discuss the new improvements of the portal.

Datasets

A NOW portal user won’t notice any of this, but the main feature of the portal is the data it uses. The portal manages 47 datasets (and growing) of fully structured, integrated and linked datasets of things of interests to Winnipegers. What the portal does is to manage entities. Each kind of entity (swimming pools, parks, places, images, addresses, streets, etc.) are defined with multiple properties and values. Several of the entities reference other entities in other datasets (for example, an assessment parcel from the Assessment Parcels dataset references neighbourhoods entities and property addresses entities from their respective datasets).

The fact that these datasets are fully structured and integrated means that we can leverage these characteristics to create a powerful search experience by enabling filtering of the information on any of the properties, to bias the searches depending where a keyword search match occurs, etc.

Here is the list of all the 47 datasets that currently exists in the portal:

  1. Aboriginal Service Providers
  2. Arenas
  3. Neighbourhoods of Winnipeg City
  4. Streets
  5. Economic Development Images
  6. Recreation & Leisure Images
  7. Neighbourhoods Images
  8. Volunteer Images
  9. Library Images
  10. Parks Images
  11. Census 2006
  12. Census 2001
  13. Winnipeg Internal Websites
  14. Winnipeg External Websites
  15. Heritage Buildings and Resources
  16. NOW Local Content Dataset
  17. Outdoor Swimming Pools
  18. Zoning Parcels
  19. School Divisions
  20. Property Addresses
  21. Wading Pools
  22. Electoral wards of Winnipeg City
  23. Assessment Parcels
  24. Libraries
  25. Community Centres
  26. Police Service Centers
  27. Community Gardens
  28. Leisure Centres
  29. Parks and Open Spaces
  30. Community Committee
  31. Commercial real estates
  32. Sports and Recreation Facilities
  33. Community Characterization Areas
  34. Indoor Swimming Pools
  35. Neighbourhood Clusters
  36. Fire and Paramedic Stations
  37. Bus Stops
  38. Fire and Paramedic Service Images
  39. Animal Services Images
  40. Skateboard Parks
  41. Daycare Nurseries
  42. Indoor Soccer Fields
  43. Schools
  44. Truck Routes
  45. Fire Stations
  46. Paramedic Stations
  47. Spray Parks Pads

Structured Search

The most useful feature of the portal to me is its full-text search engine. It is simple, clean and quite effective. The search engine is configured to try to give the most relevant results a NOW portal user may be searching. For example, it will positively bias some results that comes from some specific datasets, or matches that occurs in specific property values. The goal of this biasing is to improve the quality of the returned results. This is somewhat easy to do since the context of the portal is well known and we can easily boost scoring of search results since everything is fully structured.

Another major gain is that all the search results are fully templated. The search results do not simply return a title and some description for your search results. It does template all the information the system has about the matched results, but also displays the most relevant information to the users in the search results.

For example, if I search for a indoor swimming pool, in most of the cases it may be to call the front desk to get some information about the pool. This is why different key information will be displayed directly in the search results. That way, most of the users won’t even have to click on the result to get the information they were looking for directly in the search results page.

Here is an example of a search for the keywords main street. As you can notice, you are getting different kind of results. Each result is templated to get the core information about these entities. You have the possibility to focus on particular kind of entities, or to filter by their location in specific neighbourhoods.

now--search-1

Templated Search Results

Now let’s see some of the kind of entities that can be searched on the portal and how they are presented to the users.

Here is an example of an assessment parcel that is located in the St. John’s neighbourhood. The address, the value, the type and the location of the parcel on a map is displayed directly into the search results.

now--template-search-assessment-pacels

Another kind of entity that can be searched are the property addresses. These are located on a map, the value of the parcels and the building and the zoning of the address is displayed. The property is also linked to its assessment parcel entity which can be clicked to get additional information about the parcel.

now--template-search-property-address

Another interesting type of entity that can be searched are the streets. What is interesting in this case is that you get the complete outline of the street directly on a map. That way you know where it starts and where it ends and where it is located in the city.

now--template-search-street

There are more than a thousand geo-localized images of all different things in the city that can be searched. A thumbnail of the image and the location of the thing that appears on the image appears in the search results.

now--template-search-heritage-building-image

If you were searching for a nursery for your new born child, then you can quickly see the name, location on a map and the phone number of the nursery directly in the search result.

now--template-search-nurseries

There are just a few examples of the fifty different kind of entities that can appear like this in the search results.

Mapping

The mapping tool is another powerful feature of the portal. You can search like if you were using the full-text search engine (the top search box on the portal) however you will only get the results that can be geo-localized on a map. You can also simply browse entities from a dataset or you can filter entities by their properties/values. You can persist entities you find on the map and save the map for future reference.

In the example below, it shows that someone searched for a street (main street) and then he persisted it on the map. Then he search for other things like nurseries and selected the ones that are near the street he persisted, etc. That way he can visualize the different known entities in the portal on a map to better understand where things are located in the city, what exists near a certain location, within a neighbourhood, etc.

now--map

Census Analysis

Census information is vital to the good development of a city. They are necessary to understand the trends of a sector, who populates it, etc., such that the city and other organizations may properly plan their projects to have has much impact as possible.

These are some of the reason why one of the main section of the site is dedicated to census data. Key census indicators have been configured in the portal. Then users can select different kind of regions (neighbourhood clusters, community areas and electoral wards) to get the numbers for each of these indicators. Then they can select multiple of these regions to compare each other. A chart view and a table view is available for presenting the census data.

now--census

History, Images & Points of Interest

The City took the time to write the history of each of its neighbourhoods. In additional to that, they hired professional photographs to photograph the points of interests of the city, to geo-localize them and to write a description for each of these photos. Because of this dedication, users of the portal can learn a much about the city in general and the neighbourhood they live in. This is what the History and Image sections of the website are about.

now--history

Historic buildings are displayed on a map and they can be browsed from there.

now--history-heritage-buildings

Images of points of interests in the neighbourhood are also located on a map.

now--history-heritage-resources

Find Your Neighbourhood

Ever wondered in which neighbourhood you live in? No problem, go on the home page, put your address in the Find your Neighbourhood section and you will know it right away. From there you can learn more about your neighbourhood like its history, the points of interest, etc.

now--find-your-neighbourhood

Your address will be located on a map, and your neighbourhood will be outlined around it. Not only you will know in which neighbourhood you live, but you will also know where you live within it. From there you can click on the name of the neigbourhood to get to the neighbourhood’s page and start learning more about it like its history, to see photos of points of interest that exists in your neighbourhood, etc.

now--find-your-neighbourhood-result

Browsing Content by Topic

Because all the content of the portal is fully structured, it is easy to browse its content using a well defined topic structure. The city developed its own ontology that is used to help the users browse the content of the portal by browsing topics of interest. In the example below, I clicked the Economic Development node and then the Land use topic. Finally I clicked the Map button to display things that are related to land use: in this case, zoning and assessment parcels are displayed to the user.

This is another way to find meaningful and interesting content from the portal.

now--topics

Depending on the topic you choose, and the kind of information related to that topic, you may end up with different options like a map, a list of links to documents related to that topic, etc.

Export Content

Now that I made an overview of each of the main features of the portal, let’s go back to the geeky things. The first thing I said about this portal is that at its core, all information it manages is fully structured, integrated and linked data. If you get to the page of an entity, you have the possibility to see the underlying data that exists about it in the system. You simply have to click the Export tab at the top of the entity’s page. Then you will have access to the description of that entity in multiple different formats.

now--export-entity

In the future, the City should (or at least I hope will) make the whole set of datasets fully downloadable. Right now you only have access to that information via that export feature per entity. I hope because this NOW portal is fully disconnected from another initiative by the city: data.winnipeg.ca, which uses Socrata. The problem is that barely any of the datasets from NOW are available on data.winnipeg.ca, and the ones that are appearing are the raw ones (semi-structured, un-documented, un-integrated and non-linked) all the normalization work, the integration work, the linkage work done by the NOW team hasn’t been leveraged to really improve the data.winnipeg.ca datasets catalog.

New with the upgrades

Those who are familiar with the NOW portal will notice a few changes. The user interface did not change that much, but multiple little things got improved in the process. I will cover the most notable of these changes.

The major changes that happened are in the backend of the portal. The data management in OSF for Drupal 7 is incompatible with what was available in Drupal 6. The management of the entities became easier, the configuration of OSF networks became a breeze. A revisioning system has been added, the user interface is more intuitive, etc. There is no comparison possible. However, portal users’ won’t notice any of this, since these are all site administrator functions.

The first thing that users will notice is the completely new full-text search engine. The underlying search engine is almost the same, but the presentation is far better. All entity types have gotten their own special template, which are displayed in a special way in the search results. Most of the time results should be much more relevant, filtering is easier and cleaner. The search experience is much better in my view.

The overall site performance is much better since different caching strategies have been put in place in OSF 3.x and OSF for Drupal. This means that most of the features of the portal should react more swiftly.

Now every type of entity managed by the portal is templated: their webpage is templated in specific ways to optimize the information they want to convey to users along with their search result “mini page” when they get returned as the result of a search query.

Multi-linguality is now fully supported by the portal, however not everything is currently templated. However expect a fully translated NOW portal in French in the future.

Creating a Network of Portals

One of the most interesting features that goes with this upgrade is that the NOW portal is now in a position to participate into a network of OSF instances. What does that mean? Well, it means that the NOW portal could create partnerships with other local (regional, national or international) organizations to share datasets (and their maintenance costs).

Are there other organizations that uses this kind of system? Well, there is at least another one right in Winnipeg City: MyPeg.ca, also developed by Structured Dynamics. MyPeg uses RDF to model its information and uses OSF to manage its information. MyPeg is a non-profit organization that uses census (and other indicator) data to do studies on the well being of Winnipegers. The team behind MyPeg.ca are research experts in indicator data. Their indicator datasets (which includes census data) is top notch.

Let’s hypothetize that there would be interest between the two groups to start collaborating. Let’s say that the NOW portal would like to use MyPeg’s census datasets instead of its own since they are more complete, accurate and include a larger number of important indicators. What they basically want is to outsource the creation and maintenance of the census/indicators data to a local, dedicated and highly professional organization. The only things they would need to do is to:

  1. Formalize their relationship by signing a usage agreement
  2. The NOW portal would need to configure the MyPeg.ca OSF network into their OSF for Drupal instance
  3. The NOW portal would need to register the datasets it want to use from MyPeg.ca.

Once these 3 steps are done, taking no more than a couple of minutes, then the system administrators of the NOW portal could start using the MyPeg.ca indicator datasets like they were existing on their own network. (The reverse could also be true for MyPeg.) Everything would be transparent to them. From then on, all the fixes and updates performed by MyPeg.ca to their indicator datasets would immediately appear on the NOW portal and accessible to its users.

This is one possibility to collaborate. Another possibility would be to simply on a routine basis (every month, every 6 months, every year) share the serialized datasets such that the NOW portal re-import the dataset from the files shared by MyPeg.ca. This is also possible since both organizations use the same Ontology to describe the indicator data. This means that no modification is required by the City to take that new information into account, they only have to import and update their local datasets. This is the beauty of ontologies.

Conclusion

The new NOW portal is a great service for citizens of Winnipeg City. It is also a really good example of a web portal that leverages fully structured, integrated and linked data. To me, the NOW portal is a really good example of the features that should go along with a municipal data portal.

Aug 24 2016
Aug 24

On August 13th, I had the pleasure of enjoying another Drupal Camp Asheville. This has become one of my favorite Drupal camps because of the location and quality of camp organization. It has the right balance of structure, while maintaining a grassroots feel that encourages open discussion and sharing.

<img data-cke-saved-src="image.jpg" src="image.jpg" alt="image description" title="drupalcampasheville"/>
The Mediacurrent team at DrupalCamp Asheville

I didn't make it up for the training sessions or sprints on Friday, but from what I hear, they went well. I did drive up early Saturday morning to make a long day of it. The first thing I noticed was the diversity of session topics. I think the planning committee did a great job of placing the sessions so that each block had something for everyone.

While I did attend some sessions and presented on Guardr, I find that BoFs and hallway shop talk (or as my coworkers call it “shrop talk”), to be very valuable. Google defines "Shop Talk" as "conversation about one's occupation or business at an informal or social occasion." I had a great time talking shop with Drupal friends that I have known in the community for years and some who I met for the first time.

When sharing with others about daily work challenges and successes, it becomes obvious that we all have so much in common. Many of us run into the same challenges with time estimation, development workflows, keeping up with tech, technical hurdles in a project, physical and mental health, etc. When sharing openly about struggles and challenges, solutions to seemingly impossible problems can emerge.

The real win is being able to share and help others. Helping others comes with benefits. Simple acts of sharing personal experiences, podcasts, web links, and getting to know someone can help someone regain confidence for their work, solve a problem, and start a new friendship.

So what kind of shop talk did I have and enjoy?

  •  Caught up on Backdrop CMS progress, usage and some new security related modules being back-ported from Drupal 7.
  • Shared tools for auditing Drupal sites for standards and security.
  • Met up with some coworkers and Drupal camp attendees at the Mediacurrent event booth.
  • Learned about some command/standard security questions used in RFPs.
  • Shared some questions I had with improving Composer usage with Guardr for Drupal 8 and received some great suggestions.

Drupal Camp Asheville was a lot of fun. I want to thank the Asheville Drupal User Group and the sponsors for making this camp a reality and allowing me to have some dedicated time to enjoy a part of the Drupal community in the North Carolina Mountains.

Additional Resources
Security Talks at DrupalCon New Orleans 2016 | Blog Post
DrupalCon NOLA: The People Behind the Usernames | Blog Post
Planning a Drupal Camp: Lessons from Drupalcon New Orleans | Blog Post

Aug 24 2016
Aug 24

Using the Drupal module Hook Update Deploy Tools to move node content  can be an important part to a deployment strategy. 

What is the unique ID that connects an export to an import?

To create the export file, the node id is used to create the file.  After that, the filename and 'unique id' references the alias of that node.  So when you import the node, the node id on the production site will be determined by looking up the alias of the node.  If a matching alias is found, that is the node that gets updated.  If no matching alias is found, a new node gets created.  The alias becomes the unique id.

What are the risks of this import export model?

At present the known risks are:

  1. If the exported node uses entity references that do not exist on prod, the entity reference will either not be made, or reference an entity that is using that entity id on prod.  This can be mitigated by exporting your source node while using a recent copy of the production DB.
  2. If the exported node uses taxonomy terms that do not exist on prod, the tag may import incorrectly. This can be mitigated by exporting your source node while using a recent copy of the production DB.
  3. if you are using pathato and the existing pattern on the production site is different than the pattern on your sandbox.  The imported node will end up with a different alias, resulting in an invalid import.  The imported node will be deleted since it failed validation and the hook_update_N will fail. This can be mitigated by exporting your source node while using a recent copy of the production DB.
  4. File attachments.  There is currently not a way to bring attached files along with them unless the files already exist with a matching fid on production.

What if I am using an entity reference or a taxonomy that does not exist on production?

See answers 1 and 2 in What are the risks of this import export model?

Does the import show up as a revision?

Yes it does, and the revison note contains the imported note, but also indicates it was imported with Hook Update Deploy Tools.  The revision will take on the status of the exported node.  If the exported node was unpublished, the impoirted revision will be unpublished.

What happens if the import does not validate?

If the import was to an existing node, the update revision wil be deleted and return the node to its last published revision.  If the import was for a node that did not exist on the site, the node and its first revision will be deleted.  In either case, if the import was run through a hook_update_N, that update will fail and allow it to be re-run once the issue is resolved.

What if the alias or path is already in use by another node?

If the alias is in use by a node, that node will be updated by the import.  The alias is the unique id that links them not the nid.

What if the alias or path is already in use by a View or used by a menu router?

If the alias is in use on the site by something other than a node, the import will be prevented.  If the import is being run by a hook_update_N() then the update will fail and can be run when the issue is resolved.

Is there a limit to the number of nodes that can be imported this way?

Technically, there is no real limit.  Realistically, it is not a great workflow to move all of your content this way.  It is not a good workflow.  This export import method is best reserved for mission critical pages like forms or thankyou pages that go along with a Feature deployment.  It is also good for pages that often get destroyed during early site development like style guides and example pages.

Aug 24 2016
Aug 24

How to install it?

drush -y en twig_tweak

How to use it?

Print views in templates:

{{ drupal_view('latest_posts', 'default') }}

You can use arguments:

{{ drupal_view('latest_posts', 'default', '81,60') }}

latest_posts

View machine name.

default

Display ID (default, block_1 etc).

81,60

(optional) Arguments. Example: add an ID contextual filter to the view and you can limit the view results for only selected nodes (81 and 60 in this case).

Note: this function uses Views Embed View function that doesn't display the title of the view. You can print it manually above the view like this: <h2>Latest Posts</h2> or use the drupal_block function below (if you don't use arguments).

Print blocks in templates:

{{ drupal_block('mytheme_search') }}

mytheme_search

The machine name of the block.

Print tokens in templates:

{{ drupal_token('site:name') }}

Example tokens:

site:name

Site name.

site:slogan

Site slogan.

current-date:long

Current date in long format

Note: you can install Token module to see all available tokens in here: admin/help/token.

Token module

Use token_replace filter to print out multiple tokens at once:

{{ '<h1>[site:name]</h1><h2>[current-date:long]</h2>' | token_replace | raw }}

[site:name] [current-date:long]

The tokens.

token_replace

The filter.

raw

I had to use this filter for the HTML tags to show up right.

You can also access configuration data with drupal_config:

{{ drupal_config('system.site', 'name') }}

PHP filter:

{{ 'return date("Y d m");' | php }}

Note: allowing PHP like this in templates can create security holes and perfomance issues. Read more about the PHP Filter module:

Search and replace with regular expressions:

{{ 'some text' | preg_replace('some', '<strong>some</strong>') | raw }}

This replaces the word some with <strong>some</strong>.

some text

The text to apply search and replace.

some

The text to look for.

<strong>some</strong>

The replacement.

raw

I had to use raw filter to make it work.

Render entities:

Note: at this moment (2016.08.24) with the stable version: 8.x-1.2 this function seemed to get stuck in a loading screen. Please write in the comments if you know the cure and I will update this.

This will render the whole node:

{{ drupal_entity('node', 1) }}

This will render the teaser:

{{ drupal_entity('node', 1, 'teaser') }}

This will render the current node:

{{ drupal_entity('node', NULL, 'teaser') }}

node

The entity type.

1

Entity ID.

teaser

The view mode.

Check the video to see it in action!

In the video I also use Bootstrap to divide node content into two columns and show Recent Posts view next to the body field.

Sources & links:
Module page: https://www.drupal.org/project/twig_tweak
Issue queue: https://www.drupal.org/project/issues/twig_tweak?status=All&categories=All
Documentation: http://cgit.drupalcode.org/twig_tweak/tree/src/TwigExtension.php

Aug 24 2016
Aug 24

Marc Drummond (mdrummond), Front-end developer at Lullabot, Drupal core contributor, and self-processed Star Wars expert joins Kelley and Mike to discuss all the things the Drupal front-end community has been talking about lately. We also discuss the next major version of Drupal, whether or not a major Drupal contrib module will be deprecated, as well as our picks of the week.

Interview

DrupalEasy News

Three Stories

  1. Proposal: Deprecate Field Collections for Drupal 8, focus on Entity Reference Revisions & Paragraphs.
  2. The Average Web Page (Data from Analyzing 8 Million Websites).
  3. There will never be a Drupal 9 vs. There will be a Drupal 9, and here is why.

Sponsors

Picks of the Week

Upcoming Events

Follow us on Twitter

Five Questions (answers only)

  1. Disney
  2. Docker for Mac
  3. Writing a fantasy novel
  4. Llama
  5. DrupalCamp Twin Cities

Intro Music

  • Chunk-y Town - performed by Marc Drummond at Twin Cities DrupalCamp 2016.

Subscribe

Subscribe to our podcast on iTunes, Google Play or Miro. Listen to our podcast on Stitcher.

If you'd like to leave us a voicemail, call 321-396-2340. Please keep in mind that we might play your voicemail during one of our future podcasts. Feel free to call in with suggestions, rants, questions, or corrections. If you'd rather just send us an email, please use our contact page.

Aug 24 2016
Aug 24

In my previous post I explained why there will be a Drupal 9 even though we have previously unseen possibilities to add new things within Drupal 8.x.y. Now I'd like to dispel another myth, that initiatives are only there to add those new things.

Drupal 8 introduced initiatives to the core development process with the intention that even core development became too big to follow, understand or really get involved with in general. However because there are key areas that people want to work in, it makes sense to set up focused groups to organize work in those areas and support each other in those smaller groups. So initiatives like Configuration Management, Views in Core, Web Services, Multilingual, etc. were set up and mostly worked well, not in small part because it is easier to devote yourself to improving web services capabilities or multilingual support as opposed to "make Drupal better". Too abstract goals are harder to sign up for, a team with a thousand people is harder to feel a member of.

Given the success of this approach, even after the release of Drupal 8.0.0, we continued using this model and there are now several groups of people working on making things happen in Drupal 8.x. Ongoing initiatives include API-first, Media, Migrate, Content Workflows and so on. Several of these are primarily working on fixing bugs and plugging holes. A significant part of Migrate and API-first work to date was about fixing bugs and implementing originally intended functionality for example.

The wonder of these initiatives is they are all groups of dedicated people who are really passionate about that topic. They not only have plan or meta issues linked in the roadmap but also have issue tags and have regular meeting times. The Drupal 8 core calendar is full of meetings happening almost every single workday (that said, somehow people prefer Wednesdays and avoid Fridays).

If you have an issue involving usability, a bug with a Drupal web service API, a missing migration feature and so on, your best choice is to bring it to the teams already focused on the topics. The number and diverse areas of teams already in place gives you a very good chance that whatever you are intending to work on is somehow related to one or more of them. And since no issue will get done by one person (you need a reviewer and a committer at minimum), your only way to get something resolved is to seek interested parties as soon as possible. Does it sound like you are demanding time from these folks unfairly? I don't think so. As long as you are genuinely interested to solve the problem at hand, you are in fact contributing to the team which is for the benefit of everyone. And who knows, maybe you quickly become an integral team member as well.

Thanks for contributing and happy team-match finding!

Ps. If your issue is no match for an existing team, the friendly folks at #drupal-contribute in IRC are also there to help.

Aug 24 2016
Aug 24

This article covers, how to send email programmatically in your Drupal 8 site. There are two main steps to send an email using Drupal 8. First we need to implement hook_mail() to define email templates and the second step is to use the mail manager to send emails using these templates. Let's see an example for sending an email from the custom module, also the following name spaces.

use Drupal\Core\Mail\MailManagerInterface;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Html;
/**
 * Implements hook_mail().
 */
function module-name_mail($key, &$message, $params) {
  $options = array(
    'langcode' => $message['langcode'],
  );
  switch ($key) {
    case 'node_insert':
      $message['from'] = \Drupal::config('system.site')->get('mail');
      $message['subject'] = t('Your mail subject Here: @title', array([email protected]' => $params['title']), $options);
      $message['body'][] = Html::escape($params['message']);
      break;
  }
}

Here, the variables $key, $message and params can be described as :

  • $key: An identifier of the mail template.
  • $message: An array to be filled in. Elements in this array include: id, to, subject, body, from, headers
  • $params: An array of parameters supplied by the caller of drupal_mail().

Now lets create a custom function to send the mail using mail manager.

function custom_function_name() {
  $mailManager = \Drupal::service('plugin.manager.mail');
  $module = 'module-name';
  $key = 'node_insert'; // Replace with Your key
  $to = \Drupal::currentUser()->getEmail();
  $params['message'] = $message;
  $params['title'] = $label;
  $langcode = \Drupal::currentUser()->getPreferredLangcode();
  $send = true;

  $result = $mailManager->mail($module, $key, $to, $langcode, $params, NULL, $send);
  if ($result['result'] !== true) {
    $message = t('There was a problem sending your email notification to @email.', array([email protected]' => $to));
    drupal_set_message($message, 'error');
    \Drupal::logger('mail-log')->error($message);
    return;
  }

  $message = t('An email notification has been sent to @email ', array([email protected]' => $to));
  drupal_set_message($message);
  \Drupal::logger('mail-log')->notice($message);
}

Hope this helps, also checkout how to configure SMTP in Drupal 8 using swiftmailer Module

You may also like

Get Drupal updates straight to your inbox

Aug 24 2016
Aug 24

As mentioned in our earlier blog on Video Annotations: A powerful and innovative tool for education, the most intriguing feature of the pilot version of NVLI is Video Annotation. UniMity Solutions assisted in building Annotation feature for Audio and Video assets. This involved identifying and integrating an open plugin that supported video and audio annotations and a generic annotation store module that was plugin agnostic.

The first step of the project was to identify a suitable plugin, open source tool that support the Annotation needs of the NVLI project.

The tools reviewed included popcorn.js and Open Annotation Plugin. Popcornjs provided by Mozilla Foundation is an HTML5 media framework written in java script for film makers, web developers and anyone who want to create time-based interactive media on the web.  Annotations need to be pre created and made available through scripts. This plugin does not provide a user interface to create annotation.  The Open Annotation Plugin met most of the requirements and was on top Video.js plugin, which has a lot of adoption in the Education space.

The identification and finalization of the tool was done through a systematic process of evaluating them against specific criteria.  As Open Annotation Plugin requires Video.js, wherever required details of Video.js also provided.

Find below the criteria used to evaluate Open Annotation Plugin:

S.No

Criteria for Evaluation

Details

1

Name of Tool used

Open Video Annotation Project used with Video.js

2

Licensing

2.1

Licensing for Open Video Annotation Project

Open Video Annotation by Philip Desenne and Daniel Cebrián Robles is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

2.2

Licensing for Video.js

Licensed under the Apache License, Version 2.0

3

Standards compliance

3.1

Annotations

Compliant with Open Annotation data formats

3.2

Compliance

Open Annotation Data Model

3.3

HTML5 support

Video.js works with HTML5 only (Default failure msg built in)
Key HTML5 features include, Video, audio tag, buffering and fall back.

3.4

Accessibility

Video.js Is accessible, need to review accessibility of Open Video Annotation Project

3.5

Browser

Google Chrome, Firefox, Safari, Internet Explorer 9

3.6

Device Compatibility

iPhone, iPad, Android

3.7

Video Formats supported

MP4, ogv, webm

4

Customization

4.1

UI using CSS

Possible to override Plugin CSS - By adding weight to the style classes.

4.2

Modular Code

API Methods to take control of the plugin are listed at GitHub

5

Functional Requirements

5.1

Out of box functionality - Standard Play/ Pause/ Stop; Volume Control

Yes

5.2

Annotations

Supports Annotations - Yes

5.3

Timeline based

Yes

5.4

Spatial

No

5.5

Unicode Text Support for Multilingual

Multilingual for annotations -
This can be managed by Drupal as all annotations are saved as entity. More advanced understanding of the plugin's multilingual capability and the overall multilingual architecture  will be taken up separately

5.6

Support for Text/ Rich Text/ Images/ Embed Videos/ Audio

Yes

5.7

Annotation Scope
(Public and Private)

This has to be handled in Drupal. The annotation store will be stored as entity. The entity author will help track the author.

6

Community Support

6.1

Founder

Twitter ID of Daniel

6.2

Working Group

https://www.w3.org/community/openannotation/

6.3

IRC Channel

#videojs , no separate channel for open video annotation found

6.4

Newsletter

Not Available

6.5

Product Roadmap

One request for 3D Annotation is been raised - No clear date or plan for implementation

6.6

Usage Stats and Case studies

Top users of video.js - newspaper sites, "the ONION" and "theguardian"

7

Technology

Based on open-source java script libraries
Extending Annotator Open Knowledge Foundation Project
Build on top of the Video.js the open source HTML5 video player
Compliant with Open Annotation data formats
Customizable and mashable with open API's
HTML5 components

8

Architecture

Annotateit - For storing annotation data
Rangeslide JS - Simple, small and fast JavaScript/jQuery polyfill for the HTML5
ova JS -  handles the java script for managing display and annotation creation UI on the HTML5 video.

9

Libraries Used/ Dependencies  

Open Video Annotation Library/Videojs

10

Ease of Integration

Open Video Annotation Library - for Annotation
Annotation Module helps to store the annotation data.

11

Security Compliance

Has to be handled by Drupal
– Filtering text to prevent SQL Injection
– For internal store Drupal will handle the security.

 

IIT Bombay wanted to leverage Open source technologies and share the work back to relevant communities and hence we choose this open tool. Integrating this with Drupal meant having it work with content types, Drupal entities and more.

Watch out our next blog for solution architecture in Drupal….
 

Aug 24 2016
Aug 24

With the 7.x-1.18 release of Hook Update Deploy Tools for Drupal 7 it is now possible to export a node on a development sandbox, commit the export file to the repository, then import it using either a hook_update_N() or using drush site-deploy-import node

Pros:

  • No need to re-create a node on prod after a client approves it.
  • Early content that keeps getting wiped out by database snapshots (think style guides) can get re-created instantly with a single drush command.
  • Content imported into an existing node shows up as a revision.
  • Atomated deployment is testable and repeatable on all dev environments.
  • No uuid required.

Workflow Example:

You have a styleguide you created on your sandbox and want to deploy it to the production site.

  1.  Create the node on your sandbox (node id = 1234).
  2. Export the node to an export file.

    drush site-deploy-export 1234

  3. The command created an export file named  for the alias of the node being exported
    ex: site-deploy/node_source/helpzZzstyle-guide.txt  ('zZz' represents '/')
  4. Create a hook_update_N() to import the file on deployment
     

    <?php
    /**
     * Import a the style guide
     */
    function site_deploy_update_7129() {
     
    $nodes = array('help/style-guide');
     
    $message = HookUpdateDeployTools\Nodes::import($nodes);
      return
    $message;
    }
    ?>

  5. Commit the file and update hook to your repo.
  6. Push the code, run 'drush updb'
drush updb -y
Site_deploy  7129  Import a the style guide

Site_deploy: Updated: node/1234: help/style-guide - successful.
Summary: Imported Nodes 1/1.  Completed the following:
   [help/style-guide] => Updated: node/1234
  
Performed update: site_deploy_update_7129

or the import can be performed by

drush site-deploy-import  help/style-guide

Aug 23 2016
Aug 23

Now we've got the experience of a number of production D8 sites under our belt we took the time to consolidate our CMI workflow into some useful drush commands.

And naturally we've open sourced them.

Read on to find out more about our drush CMI tools.

Use case

Say you're working on a local development environment for a project where the client is adding and editing configuration. For example, the project might be using contact-forms or Yaml forms for user interaction. Each of these and their associated fields, form and view displays are a config object. As the client is editing these, you don't want that configuration tracked in your source control.

So you start working on a new feature, the first thing you do is sync down a QA or production database and then you run your config import so that your local environment is in a clean state.

You work on some features and the time has come to export those changes to your config export folder, in order to check in the new work into git ready for deployment.

Enter drush cexy

drush cexy

Its like drush cex but with some powersauce.

So the normal drush cex command comes with a --skip-modules option that prevents configuration from say devel module from being exported. But let's go back to our original use case.

We want to export all configuration, but we want to exclude certain patterns.

This is where the --ignore-list option of drush cexy comes in.

In our project we have a ./drush folder, so we stick a file in their called config-ignore.yml with contents as follows.

ignore:
  - field.field.contact_message.*
  - field.storage.contact_message.*
  - contact.form.*
  - core.entity_form_display.contact_message*
  - core.entity_form_display.contact_form*
  - core.entity_view_display.contact_message*
  - core.entity_view_display.contact_form*
  - system.site
  - workbench_email.workbench_email_template.*

You'll note there are some wildcards there. We're ignoring all contact message fields and forms as well as any form or view display configuration. Additionally we're ignoring Workbench Email templates and the system site settings.

So now we run drush cexy like so

drush cexy --destination=/path/to/config-export --ignore-list=/path/to/drush/config-ignore.yml

So what this does is export the active configuration, and then apply the ignore list to remove unwanted configuration.

So now when you run git status you should only see changes you want to commit.

Single install configuration

So lets assume you're working on a feature branch that requires installation of the Google Analytics module.

You download and enable the module

drush dl google_analytics
drush en -y google_analytics

And then you export your configuration with drush cexy using your build tool of choice (make in this case - cause remembering all the flags is bound to go wrong)

make export

After running that you find you have a new file in your exported configuration folder:

google_analytics.settings

Now you know that you want this configuration to be editable by the client, as they'll have different GA urchin codes on different environments.

So you don't want to check this into git. But, you do need it to be deployed at least once. And that's where drush cexy's sibling comes in drush cimy.

drush cimy

drush cimy is the import equivalent of drush cexy. We've found it significantly increases our CMI workflow productivity.

So returning to our single install of the google analytics settings. You'd just exported your config using drush cexy and found yourself with a new google_analytics.settings.yml file that you needed to deploy, but only once.

drush cimy combines the following features

  • The power of drush cim --partial
  • The ability to perform config deletes
  • The ability to perform one-time installs

The format is as follows

drush cimy --source=/path/to/config-export --install=/path/to/config-install --delete-list=/path/to/config-delete.yml

So we move the google_analytics.settings.yml out of our config-export folder and into our config-install folder. And then we add it to our drush/config-ignore.yml file, so it doesn't get exported in the future.

Partial imports

So as alluded above, drush cimy is similar to drush cim --partial in that it does partial imports.

The way drush cim --partial works is equivalent to the following

  • firstly it creates a temporary folder
  • then it exports all active configuration
  • then it copies your nominated config-export folder (the one under source control) over the top (in the temporary folder)
  • then it imports from the temporary folder

So what you get imported is all active config plus and new config from the config export, with changes in the exported config taking precedence over the active config.

The main pain point with using --partial is you don't get config deletes.

e.g. if you delete a config file from git (it is no longer in your config-export folder) because it is still present in the active configuration, it still remains after import.

So why is this a problem. So let's consider a scenario where someone enabled dblog module on QA, and saved the settings so that dblog.settings.yml is in the active configuration.

Your core.extensions.yml that is tracked in git does not contain dblog module. But dblog.settings.yml depends on dblog module.

So you work away on your feature and go to deploy to QA. But the import step of your deployment automation fails, because --partial places a copy of dblog.settings.yml in the temporary folder and tries to import it, but because dblog module is going to be disabled by the import, you have an unmet config dependency.

This is where the --delete-list flag kicks in. Let's look at a sample delete list file

delete:
  - dblog.settings

So this is where drush cimy varies from drush cim, its (equivalent) logic is as follows

  • As with drush cim --partial, first it creates a temporary folder
  • Move one-time install configuration into the folder first - so that active configuration takes precendence over initial state
  • export all active configuration
  • delete any configuration found in active configuration that is listed in the delete list
  • copy the nominated config-export (tracked in source control) over the top, taking final precendence
  • import the result

So this means you get the good bits of partial imports, without the dependency dramas that can result. It also allows you to perform valid deletes, something that isn't possible with drush cim --partial - for example you might want to delete a field from active configuration. Previously you'd have to write an update hook to do that before you performed your config import. Now you just list it in the config-delete.yml file

Installation

cd ~/.drush
wget https://raw.githubusercontent.com/previousnext/drush_cmi_tools/8.x-1.x/drush_cmi_tools.drush.inc
drush cc drush
drush CMI Drupal 8
Aug 23 2016
Aug 23

If you are using the Special Menu Items module to add things like HRs and unlinked titles to your menus, you might run into the Breadcrumb issue.

If you have a non-linked menu item it may show up on your breadcrumbs as a plain text title which you may not want to see. There are a number of issues for this in the modules queue, but as far as I can tell it has not been fixed.

My quick fix is a function in template.php

function ems_college_process_page(&$variables) {
    // Add support for the breadcrumb : nolinks would be still available leading to 404
    $item = menu_get_item();
    $trail = menu_get_active_trail();
    foreach ($trail as $key => $value) {
        if($trail[$key]['href'] == '<nolink>') {
            unset($trail[$key]);
            menu_set_active_trail($trail);
            drupal_alter('menu_breadcrumb', $trail, $item);
            $variables['breadcrumb'] = theme('breadcrumb', array('breadcrumb' => menu_get_active_breadcrumb()));
               }
        }
}

Aug 23 2016
Aug 23

Students' final evaluations is over, and only mentors' evaluations is left. During these months, I have been working on projects to harmonize social networking functionality in Drupal and documenting them. Notwithstanding, the Social API project started as an idea for a framework —in fact, the main components provide extensible functionality. Therefore, I documented the process of creating new implementers.

I'm interested, tell me more..

The documentation is based on code of current implementers, but it provides more comprehensible DocBlock comments, so developers can understand the process easily. This documentation can be found at: https://github.com/drupalsocialinitiative/social_api_examples.

If you believe something need to be explained better or need help for developing your implementer, feel free to create a new issue in the repository.

Thanks GSoC

This week marks the end of Google Summer of Code 2016. It has been a great summer (winter for me :D) working alongside my mentors, Mateu and Daniel, to turn what was previously just an idea into a functioning project. Therefore, I am happy to share a list of commits made during this program. I would also like to say that even though GSoC 2016 has ended, the Social API project continues. Hence, I will keep working on the projects.

This is a tweet from one of my mentors:

Next week

There is not a next week goal this time, but I would like to make clear that as always, feel free to contact me if you have any question. Remember that you can also collaborate with the Social Initiative projects: social_apisocial_authsocial_post, and social_widgets

See you in the Drupal community!

Aug 23 2016
Roy
Aug 23

Two meetings every week since end of march this year. Safe to say we’ve found a consistent rhythm.

And it’s working. It’s become a useful way to check in on current priorities, review patches while screensharing (visuals, transitions, flows!), decide on next steps and generally discuss hard problems without having to type so much.

The agenda for today was

  1. Roadmap – The core roadmap was updated to current state of things. Use this page to get a bird’s eye view on where Drupal core is moving towards.
  2. Ideation process – The first part of going from idea to plan got positive feedback and helpful questions and suggestions. Maybe a few words from actual maintainers and then we can make it so.
  3. Status page – We have a beautiful new design that now needs review and more code to create a complete patch. If you know your core markup and CSS, go have a look!
  4. Block place design update – An issue that iterates the design of an initial commit. We quickly discussed what the feedback should be and I added a comment to that effect right then and there. It’s an example of managing scope, pushing to focus on the actual fix first, and defer new, potentially good ideas to a followup discussion.
  5. Sample content – Kevin shared his initial thoughts and ideas for adding sample content, structure and configuration to core. More questions then answers but that’s just where we’re at for now. You are welcome to add your questions and ideas, please do.

As always, most welcome to join if you’re interested. Find us in the ux channel of the Drupal Slack room, or follow @drupalux on the twitters.

Aug 23 2016
Aug 23

Over the weekend, Drupal 8.2 beta was released. One of the reasons why I'm so excited about this release is that it ships with "more outside-in". In an "outside-in experience", you can click anything on the page, edit its configuration in place without having to navigate to the administration back end, and watch it take effect immediately. This kind of on-the-fly editorial experience could be a game changer for Drupal's usability.

When I last discussed turning Drupal outside-in, we were still in the conceptual stages, with mockups illustrating the concepts. Since then, those designs have gone through multiple rounds of feedback from Drupal's usability team and a round of user testing led by Cheppers. This study identified some issues and provided some insights which were incorporated into subsequent designs.

Two policy changes we introduced in Drupal 8—semantic versioning and experimental modules—have fundamentally changed Drupal's innovation model starting with Drupal 8. I should write a longer blog post about this, but the net result of those two changes is ongoing improvements with an easy upgrade path. In this case, it enabled us to add outside-in experiences to Drupal 8.2 instead of having to wait for Drupal 9. The authoring experience improvements we made in Drupal 8 are well-received, but that doesn't mean we are done. It's exciting that we can move much faster on making Drupal easier to use.

In-place block configuration

As you can see from the image below, Drupal 8.2 adds the ability to trigger "Edit" mode, which currently highlights all blocks on the page. Clicking on one — in this case, the block with the site's name — pops out a new tray or sidebar. A content creator can change the site name directly from the tray, without having to navigate through Drupal's administrative interface to theme settings as they would have to in Drupal 7 and Drupal 8.1.

Editing the site name using outside-in

Making adjustments to menus

In the second image, the pattern is applied to a menu block. You can make adjustments to the menu right from the new tray instead of having to navigate to the back end. Here the content creator changes the order of the menu links (moving "About us" after "Contact") and toggles the "Team" menu item from hidden to visible.

Editing the menu using outside-in

In-context block placement

In Drupal 8.1 and prior, placing a new block on the page required navigating away from your front end into the administrative back end and noting the available regions. Once you discover where to go to add a block, which can in itself be a challenge, you'll have to learn about the different regions, and some trial and error might be required to place a block exactly where you want it to go.

Starting in Drupal 8.2, content creators can now just click "Place block" without navigating to a different page and knowing about available regions ahead of time. Clicking "Place block" will highlight the different possible locations for a block to be placed in.

Placing a block using outside-in

Next steps

These improvements are currently tagged "experimental". This means that anyone who downloads Drupal 8.2 can test these changes and provide feedback. It also means that we aren't quite satisfied with these changes yet and that you should expect to see this functionality improve between now and 8.2.0's release, and even after the Drupal 8.2.0 release.

As you probably noticed, things still look pretty raw in places; as an example, the forms in the tray are exposing too many visual details. There is more work to do to bring this functionality to the level of the designs. We're focused on improving that, as well as the underlying architecture and accessibility. Once we feel good about how it all works and looks, we'll remove the experimental label.

We deliberately postponed most of the design work to focus on introducing the fundamental concepts and patterns. That was an important first step. We wanted to enable Drupal developers to start experimenting with the outside-in pattern in Drupal 8.2. As part of that, we'll have to determine how this new pattern will apply broadly to Drupal core and the many contributed modules that would leverage it. Our hope is that once the outside-in work is stable and no longer experimental, it will trickle down to every Drupal module. At that point we can all work together, in parallel, on making Drupal much easier to use.

Users have proven time and again in usability studies to be extremely "preview-driven", so the ability to make quick configuration changes right from their front end, without becoming an expert in Drupal's information architecture, could be revolutionary for Drupal.

If you'd like to help get these features to stable release faster, please join us in the outside-in roadmap issue.

Thank you

I'd also like to thank everyone who contributed to these features and reviewed them, including Bojhanyoroypwolaninandrewmacphersongtamaspetycompzsofimajor,SKAUGHTnod_effulgentsiaWim Leerscatchalexpott, and xjm.

And finally, a special thank you to Acquia's outside-in team for driving most of the design and implementation: tkolearywebchicktedbowGábor Hojtsytim.plunkett, and drpal.

Acquia's outside in team celebrating

Acquia's outside-in team celebrating that the outside-in patch was committed to Drupal 8.2 beta. Go team!

Aug 23 2016
Aug 23

by Elliot Christenson on August 23, 2016 - 7:51am

A few weeks ago, we had A Survey! Is Drupal Hard?

First of all, thank you for taking the time to answer (even though we had a short-lived technical snafu!). At myDropWizard, we believe in transparency and openness, so I'm going to share the unfiltered data with you - as well as what my thoughts are in interpreting this non-scientific study.

The Data

The Complex Things [CHART]

The Simple Things [CHART]

Some Issues

  1. Many of those answering would be biased towards Drupal
  2. The choices were somewhat arbitrary, and no doubt some were left out
  3. There was an initial bug in the survey keeping some good data out
  4. The choice "It's about what I would expect" is probably better labeled as something more along the lines of "an average web developer should be able to accomplish their needs in a reasonable amount of time"

Analysis

So, there were plenty of flaws in the data, but that won't keep me from drawing a few conclusions - and I'm anxious to hear what others feel as well.

Drupal 7 Still a Favorite

"0" respondents claimed it "impossible" to do complex things while coupled with the lowest number of "Never Used It / No Opinion" at 5.

Backdrop Ease of Use on Complex Things

WordPress and Backdrop [CHART]

Still a Need for Professionals

While (thankfully) the tools we all use to build the web keep improving, the complexities that we are tasked with keep increasing as well. Based on the very diverse set of skill levels and the varying opinions on complexity across platforms, it seems pretty clear that there will be a need for professional web developers as well as support and maintenance specialists (like myDropWizard) for a long time to come. If you fall into the camp of needing support for a Drupal website, please contact us!

What Do You Think?

Please feel free to hit the comments below, or reply to myDropWizard on Twitter - or to me personally on Twitter

Aug 23 2016
Aug 23

Answering the most commonly asked question about Configuration Management in Drupal 8; and a preview of our DrupalCon training.

This post is an excerpt from the topics covered by our DrupalCon Dublin training: Drupal 8 Development - Workflows and Tools.

For the last two years we have been giving trainings and presentations at various Drupal events about configuration management and its new workflows in Drupal 8. One of the recurring questions has been:

How do I keep some configuration from being deployed? For example the devel module and its configuration?

Until now we have answered to use drush with the --skip-modules flag and then to gitignore the configuration for devel. But then you can't share the development configuration and the process is error prone when there are more modules and other configuration items that depend on the configuration you gitignore.

For some simpler cases where configuration needs to be different between environments (for example the error verbosity) the configuration override system allows to override the configuration in settings.php. This is a solution for some cases, however, you can not override which modules are enabled or override configuration that doesn't exist.

Enter: Configuration split!

Our new module Configuration split splits the configuration when exporting it with a special Drupal Console command. It can be configured to split out enabled modules and given blacklisted configuration and it will then separate all the configuration that is dependent on the listed modules or configuration. The module's settings also allow to set a folder to which the separated configuration will be exported to.

That way the configuration set which you use to deploy configuration between different environments is a subset of your development configuration and the trusty configuration system of Drupal 8 can be used unharmed. Of course when importing with the special command the split configuration is merged back, allowing you to keep your development configuration in place.

"To split" is a synonym for "to break" and as such "Configuration split" has a dangerous ring to it. This is on purpose because the exported subset is on purpose not what you have on your development site and not what you have locally tested. So you need to compensate that with a workflow that imports and verifies the configuration you are going to deploy. This is better than to import and export individual configuration because Drupal needs the whole set of configuration to do its checks.

How do I use it?

Download and enable the Configuration split module like any other module. Then configure it under admin/config/development/configuration/config_split. Set the split folder to a different folder than your normal config sync folder. If you want a prettier interface, consider using Chosen. Then use the Drupal Console command config_split:export and config_split:import to export and import respectively.

Let's look at the devel example from above. We typically version the configuration outside of the webroot in ../config/sync as seen by Drupal. (In the project root when starting a project with drupal-composer/drupal-project.) So the folder we specify for config_split would be ../config/dev. The module to filter would be Devel and the rest can be left empty. The devel.settings will be detected automatically. Note though that the system.menu.devel does not depend on the devel module and can not be detected automatically, but it is easy to add it to the blacklisted config and it could theoretically be deployed without breaking anything.

The config_split.settings.yml could look something like this:

folder: ../config/dev
module:
  devel: 0
theme: {  }
blacklist:
  - system.menu.devel

Finally the following command will export the configuration to the default sync directory without the devel module enabled and export the devel configuration into the dev directory.
web$ ../vendor/bin/drupal config_split:export

Now if you would import the configuration through the UI or with drush cim the devel module would be un-installed, and you can do that to see the site without its development configuration. However, If you want the development configuration to stay or become active and the devel module installed use the following command:
web$ ../vendor/bin/drupal config_split:import

How does it work internally?

We implemented a StorageWrapper that allows filters to interact with the configuration after it has been read and before it is written to the wrapped FileStorage during the import and export operation. The SplitFilter has a secondary storage and decides where to read from or write to. This is a very similar concept to what drush does with its --skip-modules flag since we will want to easily integrate this with drush in the future.

What comes next?

The module is still in an early development stage and some more additions in the scope of splitting configuration could be added. The subset without the split configuration could be verified after exporting it and we could warn the user if it couldn't be imported. Or for example we currently use only config_split.settings but if the need arises we could support multiple split configurations. Or we could add a "gray list" to ignore some configuration that exists rather than removing it when splitting, essentially making it a configuration override outside of the scope of Drupal's runtime. This could be useful when maintaining several sites that are almost the same but all have their little "special snowflake" configuration which in turn could be synchronized with the normal workflow.

It is important to understand that the configuration system of Drupal has limitations that are there for a good reason. Most of them are to ensure data integrity and robustness and reliability of the synchronisation and so on. In other words measures to protect you from accidentally breaking your site. Using tools like config_split or drush --skip-modules you circumvent some of these security and integrity checks so use them with caution.

Since the module is not required for the regular functioning of a Drupal 8 site (it can even be used to blacklist itself) it can already be used in the development process of your current projects already. Your feedback is welcome, see you in the issue queue.

Aug 23 2016
Aug 23

GSoC is almost over and I’m now submitting the project which I started with my awesome mentors Dick Olsson, Andrei Jechiu and Tim Millwood nearly 4 months ago. I knew it’d be a really great journey but I had no idea it’d be this awesome. Everything related to GSoC was perfect. The organisation, my mentors, the project itself was enough challenging as well as interesting at the same time. Weekly blogs, daily updates and communication with mentors over Slack made sure we’re on track. First part was easy but I struggled a bit in second half but my mentors were always right here to help me with all the issues I had. I used to feel a bit embarrassed as I was not getting things done as easily as any other student could have but they never felt the same way. They always had a smile at their face and a solution for me to work on. I’m really glad I got such supportive mentors.  Thanks a lot Drupal.

Drupal makes me happy

Project Description: The task was to solve the conflicts which may occur when two users try to push the same content with modifications in same piece of content/entity on their respective end. Initially it looked like a very difficult task and I was really afraid when I chose the project but when Dick Olsson told me that this is a very interesting project and something like this has not been done in Drupal like this from a long time, it may also get a lot of attention as well as support from other people in community as well, I was more than just happy in going with this project. It took me some time to actually understand how we would solve the problem and to be very honest, I had no clear idea for the community bonding period about if I still understand it clearly or not. I decided to go on step by step and knew what I had to do at one time. Once we started coding, I could see the future and the parts where the code I was writing at that moment would be used. Soon, I could see a very clear picture of our project and the path we had to follow to make it a success. All thanks to my mentors again for their constant guidance.

How we solved it: I started by understand what actually happens at the backend of Drupal When a node is updated. I learnt that a revision is created every time a node is updated. Multiple revisions forms a graph with actual entity as root node. In the image below, you can see a graph with multiple nodes. All these nodes are revision and root is actual entity. In simpler words, when we create a new entity, we are starting a graph and when we update that entity, we are adding a node in that graph. It should be noted that even when we remove an entity, we’re adding a node in the graph and not removing.

The complete solution was depending on two steps:

  1. Find Lowest common ancestor of 2 revisions.

  2. Implement recursive 3-way merge algorithm on them.

I will start by explaining the 2nd step and It’d pretty much cover the 1st one itself. Recursive 3-way merge Algorithm takes 3 parameters as input which are 3 entities (local, remote and base) and compares two of them (local and remote) with base entity.

It then makes sure that none of the content which is changed in Local/Remote is changed in Remote/Local as well. For example:  If some changes are made in Local on line number 19, there should not be any changes on line number 19 of remote and It should be identical to line number 19 of base entity. There can be changes on any other line of remote entity but not those which are changed/modified in local. Vice versa is true as well. If it is made sure that no changes in local and remote overlaps, there’d not be any merge conflicts otherwise there would be conflicts.

Let’s take another example: In the image below, we see that line 51 is changed by both the developers and content is different from the base entity. In this scenario, the system can not decide on it’s own if we want the loops to run 10 times as per Remote Entity or 20 times as per local entity or just 5 times as Base entity says. So we’ll let users manually decide what they want. In our case, developer wanted it to run for 25 times.

Figure 1 : Explaining how merge conflicts occursFigure 1 : Explaining how merge conflicts occurs
                                                                                                                                                                     IMAGE BY : DR. DROBBS (FOR INFORMATIONAL USE ONLY)

For further information on how it all works, you can also have a look at the 3rd week blog post at my blog.

Now coming back to the first step: “Finding LCA”, the base entity we use in recursive 3-way merge is the LCA of two revisions. It is considered as base as it contains all the latest changes which are reckoned to be in the two revisions we will be comparing. So, we find a common parent of both the revisions which is closest to both of them and compare these revisions with that parent only. That parent or LCA acts as base entity.

Example: Below is a graph of revisions with revision ID and status. As we can see there are multiple revisions. Now let’s suppose someone (Developer A) starts editing revision with revision_id 4-8B10006… and at the very same time, another person (Developer B) starts editing 4-82460F0…. When both the developers try to save their edits, we don’t know which changes should be kept in the final revision (new revision which would be created after the merge). So for that purpose, we need to develop a system which could compare the revisions content and make sure that there is no conflict.

As discussed above, first we would find Lowest common ancestor of both the revisions developers have modified. As we can see Revision 3-6F7F875…  is closest to both of them, it is the Lowest Common Ancestor. Relaxedws/lca library does this task of finding LCA of two revisions. Now we have three important parts we can use from the graph:

  • Revision 1 (4-8B10006…) which was modified by developer A.

  • Revision 2 (4-82460F0…)  which was modified by developer B.

  • Lowest Common Ancestor of both the revisions (3-6F7F875…). 

Figure 2: Revision Graph created by workspace module.Figure 2: Revision Graph created by workspace module.

 The next step is to find if there are any merge conflicts or not. For that purpose, we will compare contents of revision 4-8B10006… with revision 3-6F7F875… and inspect all the changes made in revisions 4-8B10006…. We’ll do the same for revision 4-82460F0….. Once we have compared both revisions with their LCA (revision 3-6F7F875…), we will compare the changes made in both revisions. If the changes contains some common content in both revisions, we know there is a merge conflict as the system can not decide which changes are more important. So at that time, we’ll have to show a 3 pane window to the developer and let him/her decide whether he wants. He would be shown content of all three parts i.e, revision 1, revision 2 and LCA. The manually chosen content will then create a new revision. The tree pane window would look like this.

Figure 3 : 3-Pane window to resolve merge conflicts manually (containing content from Local, Base and Remote entities).Figure 3 : 3-Pane window to resolve merge conflicts manually (containing content from Local, Base and Remote entities).
                                                                                                                                                       IMAGE BY : CODEMIRROR DEMO (FOR INFORMATIONAL USE ONLY)

And once the conflicts and either resolved or there wasn't any conflict, the graph would look something like the following image:          

Expected Graph after conficts are resolved.Expected Graph after conflicts are resolved.

Initially the biggest concern was to get my system set up and running properly. I had to install Drupal 8 locally and get an IDE with a good debugger to start working. As per my mentor’s suggestion, I used PhpStorm IDE from JetBrains and Xdebug for debugging purposes. Also, my mentors kept telling me to learn how to test the code I will write as they wanted to “Write tests first, code later” approach. It was one of the most challenging tasks as I had no exposure to testing and was totally new to it. So, with a little knowledge of everything, I started my journey and I’m really happy we got it going till the end.

Once the problem was clear, we started coding our way into it. We divided the whole process in sub tasks and completed one at a time which in the end was integrated together for a complete success of project.

Let’s take a look at the all the subtasks and how we implemented them.

Task 1: First task was to create a PHP Library which could return Lowest Common Ancestor from a Directed Acyclic Graph.

Implementation: We used clue/graph library and ran a Breadth First Search on the graph for both the revisions and then found the common nodes and returned the one closest to both the nodes.

Code: The code is pushed over github and packagist as well.

List of all my commits : Commits made by Rakesh Verma in Relaxedws/lca Library.

 A Pull commit may contain multiple commits.

Task 2: Once we’re done with the relaxedws/lca library, we needed another library which could use the LCA returned by relaxedws/lca for implementing recursive 3-way merge algorithm as described above. For this purpose, we created relaxedws/merge library which takes 3 arrays as input and merge them according to 3-way merge algorithm.

Implementation: We implemented all the algorithm by ourselves for this library. We converted the contents of file into array and then compared each line of these array with array from other revision. If there was any change in values of the arrays at same index, we made sure it doesn’t exist in 3rd array as well otherwise we returned a custom exception alerting user about merge conflict.

List of all commits: Commits made by Rakesh Verma in Relaxedws/merge Library.

Task 3: After the successful completion of both these libraries, we’re ready to implement these libraries in Multiversion module but then we realized we need one module which won’t use these libraries but use simple terminology to find LCA and perform merge algorithm in Drupal as not all Drupal sites would use Multiversion and hence these libraries won’t be used by all.

Implementation: As we discussed earlier how revisions are created in a linear graph by default in drupal, we created a module named “Conflict” which would take 2 node id as input and would return the parent of the node_id which was created first.

For ex: LCA(4,5) would be 3 and LCA(12,16) would be 11 and LCA(1,8) would be 1 as it’s the root node and it doesn’t have any parent.

Similarly it takes 3 node ids to perform merge and return the last created node id out of those 3 as the last created node is the latest one and it contains all the latest changes in linear graph. So, Merge(3,4,5) would return contents of node with id = 5 and Merge(4,6,9) would return the contents of node with id = 9.

We created a pluggable pattern with services in the container which could be used by other drupal modules as well. The services we created in the conflict module were used in Multiversion module as well to detect and solve merge issues in the complex graphs where a node can have multiple branches (nonlinear graph).

Code: The code is available at Drupaldeploy/drupal-conflict.

List of commits made by me can is available here: Commits made by Rakesh Verma.

Task 4: After implementing the simple LCA resolver and simple Merge resolver in Conflict module, we’re ready to start integrating the relaxedws/lca library into the Multiversion module. All the websites which uses Multiversion module can use these libraries to find Lowest common ancestor from the graph of revisions and use that as an input to merge library.

The feature is already completed and merged in Multiversion module.

List of all the commits made by me is present : Commits made by Rakesh Verma to integrate relaxedws/lca with multiversion module.

Task 5: Now we’re left with the integration of relaxedws/merge library with the multiversion module. We’ve implemented the functionality and writing tests for it. Some tests are failing because revision ID is different for each revision and hence, merge library is returning an exception because the revision ID is changed in all three revisions and library can not decide on it’s own which results are to be kept in final revision. We’re trying to solve this issue.

Implementation: We created a method to convert the tree returned by multiversion module into a graph and later, we used that graph and it’s contents in PHP libraries we created in first phase. We integrated those libraries with Multiversion module and accessed them via services defined in Conflict module.

Code: All the commits made by me can be seen here: Link to pull request for integrating relaxedws/merge into multiversion module.

Task 6: The last task of the project is to integrate Codemirror with the multiversion module so that if in any case, there is a merge conflict, A user would be shown all 3 nodes (Local, remote and Base) and would be allowed to decide what changes are to be kept in final revision. This is where Codemirror comes in. This is the last part of the project and we ran out of time.

Weekly Breakdown: The work we did weekly is mentioned below:

  • Community Bonding period:  Familiarize myself with the organizations, mentors and the codebase.

  • Coding Phase Week 1: Finished the PHP library to find LCA. (Blog Post)

  • Week 2: Wrote tests for the PHP library. (Blog Post)

  • Week 3: Finished the code for PHP library to perform recursive 3-way merge (Blog Post)

  • Week 4: Wrote tests for the PHP library to ensure it performs the algorithms correctly (Blog post)

  • Week 5: Started code to create module to find LCA in linear graph (Blog post).

  • Week 6: Wrote tests for module and Finished the LCA part of the Conflict module (Blog Post).

  • Week 7: Implemented Simple Merge Resolver in Conflict Module (Blog Post).

  • Week 8: Extensive tests written for Simple Merge Resolver (Blog Post).

  • Week 9: Finished the Conflict module (Blog Post).

  • Week 10: Started Integration of PHP library which finds LCA from a graph into Multiversion module. (Blog Post)

  • Week 11: Wrote tests to ensure integration has been done correctly in multiversion module (Blog post).

  • Week 12: Finished Integration of PHP library to perform recursive 3-way merge with multiversion module (Blog Post).

  • Week 13: Wrote Tests for the integration part of the PHP library with multiversion Module.

  • Week 14: Fixing Bugs, added documentation and fixed other issues.

Future Work:  I’d keep contributing to the organisation as much as possible and I’d finish the tasks which I couldn’t complete in given time. I’ll also try to mentor students in Google Code In. This was such a great experience and learning curve grew exponentially for me. I would be really fortunate if I could experience something like this ever again or if I could get another chance to work full time with my mentors.

Conclusion: Participating in Google Summer of Code has brought me closer to the Drupal community members which comprises of an amazing group of developers. The experience in working with them taught me essential soft skills like effective communication, extensive testing and much more, than just writing code. Not only I learnt about full scale development but also about writing Industrial level code as well which I believe I couldn’t have learnt on my own. Every single time I tried to write code with as few mistakes as possible but there were always some. In order to not make new mistakes, I sometimes made same mistakes multiple times but my mentors (specially Andrei) always informed me about these mistakes and why I shouldn’t repeat them. Writing tests was one of the major learning. I never thought they were this important. After writing code, when I thought now the work is done, it was always the start. Solving errors took twice the time than writing code. Initially when my mentor Dick told me that ideally writing code takes 1/3rd of the total time, I really didn’t take him very seriously until I experienced it myself. Other than this, I learnt the importance of having a good and working debugger. A few hours tasks could take more than a week if you don’t have a debugger working fine at your end as you just simply can not identify the problems sometimes with your code. No matter how fine code you’ve written or how obvious it seems that it should work, there will always be an issue at your end if tests are failing and only a debugger can help you detecting the issue. There were many other little things which I got to learn like working under given time and not sticking to a wrong method if that’s not working rather than spending time with it to make it work. These all things will help me a lot shaping my future as a software developer. I will be forever indebted to them for providing such a nurturing environment.

I would sincerely thank my mentors Dick Olsson, Andrei Jechiu and Tim Millwood, My C0-mentor Matthew Lechleider and whole Drupal community for the support over IRC. A big thank to Drupalize.me for giving us a chance to learn about drupal through their website for free. Thanks a lot Google for providing us the opportunity and thanks Drupal for choosing me . I am really grateful.

Aug 23 2016
Aug 23

Over the weekend, Drupal 8.2 beta was released. One of the reasons why I'm so excited about this release is that it ships with "more outside-in". In an "outside-in experience", you can click anything on the page, edit its configuration in place without having to navigate to the administration back end, and watch it take effect immediately. This kind of on-the-fly editorial experience could be a game changer for Drupal's usability.

When I last discussed turning Drupal outside-in, we were still in the conceptual stages, with mockups illustrating the concepts. Since then, those designs have gone through multiple rounds of feedback from Drupal's usability team and a round of user testing led by Cheppers. This study identified some issues and provided some insights which were incorporated into subsequent designs.

Two policy changes we introduced in Drupal 8 — semantic versioning and experimental modules — have fundamentally changed Drupal's innovation model starting with Drupal 8. I should write a longer blog post about this, but the net result of those two changes is ongoing improvements with an easy upgrade path. In this case, it enabled us to add outside-in experiences to Drupal 8.2 instead of having to wait for Drupal 9. The authoring experience improvements we made in Drupal 8 are well-received, but that doesn't mean we are done. It's exciting that we can move much faster on making Drupal easier to use.

In-place block configuration

As you can see from the image below, Drupal 8.2 adds the ability to trigger "Edit" mode, which currently highlights all blocks on the page. Clicking on one — in this case, the block with the site's name — pops out a new tray or sidebar. A content creator can change the site name directly from the tray, without having to navigate through Drupal's administrative interface to theme settings as they would have to in Drupal 7 and Drupal 8.1.

Editing the site name using outside-in

Making adjustments to menus

In the second image, the pattern is applied to a menu block. You can make adjustments to the menu right from the new tray instead of having to navigate to the back end. Here the content creator changes the order of the menu links (moving "About us" after "Contact") and toggles the "Team" menu item from hidden to visible.

Editing the menu using outside-in

In-context block placement

In Drupal 8.1 and prior, placing a new block on the page required navigating away from your front end into the administrative back end and noting the available regions. Once you discover where to go to add a block, which can in itself be a challenge, you'll have to learn about the different regions, and some trial and error might be required to place a block exactly where you want it to go.

Starting in Drupal 8.2, content creators can now just click "Place block" without navigating to a different page and knowing about available regions ahead of time. Clicking "Place block" will highlight the different possible locations for a block to be placed in.

Placing a block using outside-in

Next steps

These improvements are currently tagged "experimental". This means that anyone who downloads Drupal 8.2 can test these changes and provide feedback. It also means that we aren't quite satisfied with these changes yet and that you should expect to see this functionality improve between now and 8.2.0's release, and even after the Drupal 8.2.0 release.

As you probably noticed, things still look pretty raw in places; as an example, the forms in the tray are exposing too many visual details. There is more work to do to bring this functionality to the level of the designs. We're focused on improving that, as well as the underlying architecture and accessibility. Once we feel good about how it all works and looks, we'll remove the experimental label.

We deliberately postponed most of the design work to focus on introducing the fundamental concepts and patterns. That was an important first step. We wanted to enable Drupal developers to start experimenting with the outside-in pattern in Drupal 8.2. As part of that, we'll have to determine how this new pattern will apply broadly to Drupal core and the many contributed modules that would leverage it. Our hope is that once the outside-in work is stable and no longer experimental, it will trickle down to every Drupal module. At that point we can all work together, in parallel, on making Drupal much easier to use.

Users have proven time and again in usability studies to be extremely "preview-driven", so the ability to make quick configuration changes right from their front end, without becoming an expert in Drupal's information architecture, could be revolutionary for Drupal.

If you'd like to help get these features to stable release faster, please join us in the outside-in roadmap issue.

Thank you

I'd also like to thank everyone who contributed to these features and reviewed them, including Bojhan, yoroy, pwolanin, andrewmacpherson, gtamas, petycomp, zsofimajor, SKAUGHT, nod_, effulgentsia, Wim Leers, catch, alexpott, and xjm.

And finally, a special thank you to Acquia's outside-in team for driving most of the design and implementation: tkoleary, webchick, tedbow, Gábor Hojtsy, tim.plunkett, and drpal.

Acquia's outside in team Acquia's outside-in team celebrating that the outside-in patch was committed to Drupal 8.2 beta. Go team!
Aug 22 2016
Aug 22

The Drupal accessibility initiative started with some advancements in Drupal 7 to ensure that Drupal core followed the World Wide Web Consortium (W3C) guidelines: WCAG 2.0 (Web Content Accessibility Guidelines) and ATAG 2.0 (Authoring Tool Accessibility Guidelines).
Many elements introduced in Drupal 7 were improved and bugs discovered through intensive testing were addressed and integrated to Drupal 8 core as well. Let’s take a tour of the accessibility in Drupal 8 !

Contrasts improved

Drupal’s accessibility maintainers improved contrasts in core themes so people that suffer from colorblindness are able to visit websites clearly. It is also good when visiting the website under bright sunlight, on mobile for instance.

A screenshot that compares Bartik headers in Drupal 7.43 and Drupal 8

Color contrasts in Bartik theme in Drupal 7.43 and Drupal 8.

See the related WCAG 2.0 section about contrasts.

Alternative texts for images

The alternative text for images is really useful for blind people who use screen readers. They can understand the meaning of an image through short descriptive phrases. This alternative text is now by default a required field in Drupal 8.

A screenshot showing that the alternative text is required when uploading an image in Drupal 8.

The alternative text for an image is required by default in Drupal 8 content edition.

See the related WCAG 2.0 section about alternative texts.

More semantics

Many accessibility improvements are hard to see as it involves semantics. Drupal 8 uses HTML5 elements in its templates which add more meaning into the code. For instance, assistive technology such as screen readers can now interpret elements like <header>, <footer> or <form>.

Moreover, WAI-ARIA (Web Accessibility Initiative – Accessible Rich Internet Applications) additional markup really improved semantics using:

  • landmarks to identify regions in a page, for instance: role="banner" ;
  • live regions to indicate that an element will be updated, for instance: aria-live="polite";
  • roles to describe the type of widgets presented, for instance: role="alert";
  • properties: attributes that represent a data value associated with the element.

See the related WCAG 2.0 sections about semantics.

Tabbing order

Drupal 8 introduces the TabbingManager javascript feature. It enables to constrain tabbing order on the page and facilitates navigation with keyboards. It is really helpful to guide a non-visual user to the most important elements on the page and minimize confusion with screen readers.

See the related WCAG 2.0 section about keyboard operations.

Forms

Drupal 8 accessibility involves many improvements regarding forms in Drupal 8.

In Drupal 7, all errors were displayed by default on top of the form and fields were highlighted in red. It was not right for colorblind people to understand where the errors were.
In Drupal 8, there is an experimental option to enable form inline errors and an error icon is displayed next to the field. Nevertheless, note that this feature is not enabled by default as there are still some pending issues.

Screenshot of a password field highlighted in red with an error message below "The specified passwords do not match"

The error message is displayed below the field when the Form Inline Error module is enabled.

See the related WCAG 2.0 sections about error identification.

Regarding the form API, radios and checkboxes are now embedded in fieldsets to meet WCAG compliance. Indeed, grouping related elements will help screen readers to navigate in complex forms. Plus, all fields have a label associated with the right element using the “for” attribute.

Here is an example of HTML code for radio buttons:

<fieldset id="edit-active--wrapper" class="fieldgroup form-composite js-form-item form-item js-form-wrapper form-wrapper" data-drupal-selector="edit-active"> <legend><span class="fieldset-legend">Poll status</span></legend> <div class="fieldset-wrapper"> <div id="edit-active" class="form-radios"> <div class="js-form-item form-item js-form-type-radio form-type-radio js-form-item-active form-item-active"> <input id="edit-active-0" class="form-radio" name="active" type="radio" value="0" data-drupal-selector="edit-active-0" /> <label class="option" for="edit-active-0">Closed</label> </div> <div class="js-form-item form-item js-form-type-radio form-type-radio js-form-item-active form-item-active"> <input id="edit-active-1" class="form-radio" name="active" type="radio" value="1" data-drupal-selector="edit-active-1" /> <label class="option" for="edit-active-1">Active</label> </div> </div> </div> </fieldset>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<fieldset id="edit-active--wrapper" class="fieldgroup form-composite js-form-item form-item js-form-wrapper form-wrapper" data-drupal-selector="edit-active">

  <legend><span class="fieldset-legend">Poll status</span></legend>

  <div class="fieldset-wrapper">

    <div id="edit-active" class="form-radios">

      <div class="js-form-item form-item js-form-type-radio form-type-radio js-form-item-active form-item-active">

        <input id="edit-active-0" class="form-radio" name="active" type="radio" value="0" data-drupal-selector="edit-active-0" />

        <label class="option" for="edit-active-0">Closed</label>

      </div>

      <div class="js-form-item form-item js-form-type-radio form-type-radio js-form-item-active form-item-active">

        <input id="edit-active-1" class="form-radio" name="active" type="radio" value="1" data-drupal-selector="edit-active-1" />

        <label class="option" for="edit-active-1">Active</label>

      </div>

    </div>

  </div>

</fieldset>

See the related WCAG technical section about fieldsets

Tables and views

As Views UI module is in core now, it became accessible.
The views tables markup is more semantic. Data cells are associated with header cells through “id” and “headers” attributes. It is also possible to add a <caption> element to explain the purpose of the table and a <summary> element to give an overview on how the data is organized and how to navigate the table.
Plus, the “scope” attribute enables to explicitly mark row and column headings.

Here is an example of a table HTML code generated by a view:

<table class="views-table views-view-table cols-2"> <caption> Caption for the table <details> <summary>Details for the table</summary> Description for details </details> </caption> <thead> <tr> <th id="view-title-table-column" class="views-field views-field-title" scope="col">Title</th> <th id="view-type-table-column" class="views-field views-field-type" scope="col">Content type</th> </tr> </thead> <tbody> <tr> <td headers="view-title-table-column" class="views-field views-field-title"> <a href="https://blog.liip.ch/node/1" hreflang="und">Premo Quae Vero</a> </td> <td headers="view-type-table-column" class="views-field views-field-type"> <a href="https://blog.liip.ch/admin/structure/types/manage/article">Article</a> </td> </tr> <tr> <td headers="view-title-table-column" class="views-field views-field-title"> <a href="https://blog.liip.ch/node/6" hreflang="und">Capto Dolor</a> </td> <td headers="view-type-table-column" class="views-field views-field-type"> <a href="https://blog.liip.ch/admin/structure/types/manage/article">Article</a> </td> </tr> </tbody> </table>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

<table class="views-table views-view-table cols-2">

  <caption>

    Caption for the table

    <details>

        <summary>Details for the table</summary>

        Description for details

    </details>

  </caption>

  <thead>

    <tr>

      <th id="view-title-table-column" class="views-field views-field-title" scope="col">Title</th>

      <th id="view-type-table-column" class="views-field views-field-type" scope="col">Content type</th>

    </tr>

  </thead>

  <tbody>

    <tr>

      <td headers="view-title-table-column" class="views-field views-field-title">

        <a href="/node/1" hreflang="und">Premo Quae Vero</a>

      </td>

      <td headers="view-type-table-column" class="views-field views-field-type">

        <a href="/admin/structure/types/manage/article">Article</a>

      </td>

    </tr>

    <tr>

      <td headers="view-title-table-column" class="views-field views-field-title">

        <a href="/node/6" hreflang="und">Capto Dolor</a>

      </td>

      <td headers="view-type-table-column" class="views-field views-field-type">

        <a href="/admin/structure/types/manage/article">Article</a>

      </td>

    </tr>

  </tbody>

</table>

See the related WCAG section about tabular information.

Hidden elements

Using "display:none;" CSS styling can be problematic as it will hide elements for both visual and non-visual users and consequently, screen readers will not be able to read them.
Drupal 8 accessibility maintainers decided to standardize in the naming convention of HTML5 Boilerplate using different classes to hide elements:

  • hidden“: hide an element visually and from screen readers;
  • visually-hidden“: hide an element only visually but available for screen readers;
  • invisible“: hide an element visually and from screen readers without affecting the layout.

Aural alerts

Users with visual impairment will not be able to see all visual updates of the page such as color changes, animations or texts appended to the content. In order to make these changes apparent in a non-visual way, Drupal provides the Drupal.announce() JavaScript method which creates an “aria-live” element on the page. This way, text appended to the node can then be read by a screen reading user agent.

Here is an example of a code using the aural alert:

Drupal.announce('Please fill in your user name', 'assertive');

1

Drupal.announce('Please fill in your user name', 'assertive');

The first parameter is a string for the statement, the second is the priority:

  • polite“: this is the default, polite statements will not interrupt the user agent;
  • assertive“: assertive statements will interrupt any current speech.

See the related WCAG technical section about how to use live regions to identify errors.

CKEditor WYSIWYG accessibility

Drupal community helped improving CKEditor accessibility.
First of all, the WYSIWYG editor now comes with keyboard shortcuts which are beneficial for both power users and keyboard-only users.
Drupal 8 implements more semantic elements. For instance, the user can create HTML tables with headers, caption and summary elements. <figure> and <figcaption> HTML5 tags are also available to add captions to images.
Moreover, every image added through CKEditor are required by default, as it is on image fields.

CKEditor module also introduces a language toolbar button so that users can select a part of text and specify the language used. Screen readers will be able then to choose the appropriate language for each content.

See the related WCAG technical section about language attributes.

Finally, there is an accessibility checker plugin for CKEditor. It is not in core yet as a CKEditor issue blocks its integration, you can find more information on the related Drupal issue queue. However, you will find a module that implements it currently: ckeditor_a11checker.

All these options will definitely help users to generate accessible contents.

Conclusion

Drupal core maintainers accomplished great enhancements regarding accessibility in Drupal 8. These accessibility features will definitively be beneficial to keyboard-only users, low-vision users and colorblind people but will also be good for the usability and the SEO of your website.
Nevertheless, there is still work to be done to make Drupal 8 core fully accessible and Drupal needs contributors to tackle the remaining issues.

If you want to learn more about Drupal 8 accessibility, you can watch the presentation about “How Drupal 8 makes your website more easily accessible” given by Mike Gifford, one of the main accessibility core maintainer for Drupal.

Aug 22 2016
Aug 22

Nederlandse versie van dit blog

Here’s what struck me last month about Drupal modules. This month I have chosen to focus on Drupal 8 as this is slowly becoming the go-to version - partly because many required modules have been migrated and grown up.

1. Require Login

Make sure all your visitors on your Drupal website are obligated to log in. Handy for a Drupal intranet or social communities. It is possible to exclude certain paths so that they are publicly available.

Download

2. 403 to 404

Mini module that ensures you will get to see a page not found on an access denied page. This way others will not found out that this page is an administration page.

Global redirect contains a similar feature.

Download

3. Block tabs

Add tabs in blocks in order to cluster information. Similar to the Quick Tabs module. But Quick Tabs has no version for Drupal 8. Furthermore Block Tabs is offering integration with the Drupal 8 API, plugin system, block, entity and config API. Add CSS yourself to adjust the tabs according to your house style.

Download

4. ShareThis

Do you like to have social buttons so people can easily share pages on Facebook, Twitter and LinkedIn? Integrate the ShareThis social bookmarking service in your Drupal 8 website using this module to get you socialized in no time.

Download

5. Page Load Progress

Some heavy activities in a Drupal website can take a few seconds. In these cases it is preferable to lock the screen to avoid impatient users clicking other features. You can show a throbber and thus lock the screen using this module.

Download

6. Adminimal Admin Toolbar (Drupal 8)

The Drupal 8 admin toolbar is fine, but could be better. This version is inspired on the popular module Adminimal Administration Menu

Download

7. Node Order

Manually organizing nodes within a given Drupal taxonomy term. By default Drupal is sorting on sticky and date created. Using this module you can determine the order yourself.

Download

8. Mail system

This popular module is migrated to Drupal 8. This allows the administration of all kinds of actions related to sending an email from Drupal 8. For example:

  • Formatting of emails in HTML
  • Managing email per Drupal module
  • Templates for e-mails

Download

9. Optimizely

Everybody should constantly be A/B testing for conversion optimization. Optimizely.com is such an A/B testing tool that integrates in your Drupal 8 website using this module.

Download

10. Menu block

Drupal 8 has standard features to place menus via blocks in your website. But it misses some features that are complemented by this module:

  • Determine how many menu levels you want to show
  • Set initial menu level
  • Expand all Drupal menu items

Download

11. Update External Links

Open external links in text automatically in a new window to avoid people navigating accidentally away from your Drupal 8 website. Similar to the modules External links and External New Tab

Download

12. Pinterest Hover button

Simple module that let’s you show automatically a pin it button as soon as website visitors hover over an image. Now also available for Drupal 8.

Download

13. Easy Social

Similar to the above mentioned ’ShareThis’: make it easy to share your Drupal 8 content on social media platforms such as Twitter, Facebook and LinkedIn. This module is not using an external service unlike ‘ShareThis’.

Download

14. Chosen

Makes selecting items (f.e. Drupal taxonomy terms) easier for content managers in your Drupal system. Now available for Drupal 8.

Download

Wrap up

OK, that’s it for now, stay tuned for more interesting Drupal stuff and next month again a cool Drupal modules update!

Credits header foto
Credits mail foto
Credits social foto

Aug 22 2016
Aug 22
Progressive decoupling, a concept outlined last year in Dries Buytaert’s first post about decoupled Drupal, is a compelling approach to building Drupal's front end where content editors, site assemblers, and front-end developers maintain contiguous experiences. For content editors and site assemblers, progressive decoupling allows for contextualized interfaces, content workflow, site preview, and other features to remain usable and integrated with Drupal as a whole.
Aug 22 2016
Aug 22

As you may already know, the BlackMesh team is committed to ensuring developers can focus on their website goals without worrying about scalability, infrastructure, and – in particular – security. That’s why we’re thrilled to have partnered with leading Drupal security agency Tag1 Consulting to provide our Drupal clients a comprehensive tool for managing site updates.

What?

The new Tag1 Quo is a hosted security dashboard that provides up-to-the-minute snapshots of a client’s security status and potential vulnerabilities. Basically, this innovative tool provides Drupal users consolidated and critical security updates for their websites. Tag1 Quo features include essentials for a website’s success, such as self-service monitoring, security notifications for out-of-date modules, and patch and release delivery.

How?

Tag1 Quo automatically monitors upstream releases and security advisories in collaboration with module maintainers and other Drupal 6 long term support (LTS) providers. The Tag1 team of Drupal security experts review and decide which issues affect the client, carefully backporting those that are applicable to their site. Quo then delivers timely notifications to the client’s inbox. Quo users can choose to either leverage pre-patched releases or quickly apply the patches themselves to bring their website up-to-date and secure against all known vulnerabilities. For extra peace of mind, the Quo dashboard provides at-a-glance visualization of all client websites, highlighting all outstanding updates across them.

Tag1 Quo Dashboard

Why?

Though D6 was phased out earlier this year, Tag1 Consulting continues to provide long-term D6 support to those who need it. As a way to adequately manage the significant maintenance and monitoring of these systems, the Tag1 team developed Tag1 Quo.

If you are currently managing a D6 site, signing up for Tag1 Quo is a no-brainer. It provides affordable long-term support for all of your core and contributed modules and themes, tested and delivered by an approved LTS provider, backed by a team of renowned Drupal experts.

Your Security. Your Options …

Even if you don’t maintain a D6 site, you’ll still want to check it out.

Depending on your needs and budget, Tag1 Quo offers three different plan options. Tag1’s roadmap includes upcoming support for D7 and D8, WordPress 4.6 and 4.7, application programming interface (API) access, upgrade planning, and more.

Signing up for Tag1 Quo means less time spent on maintenance and security – and that means more time focusing on your goals and overall mission. Whenever BlackMesh teams up with companies like Tag1, we’re advancing our commitment to your security. Contact us to learn more about how we can make the Tag1 Quo dashboard solution fit your needs.

Aug 22 2016
Aug 22

Drupal.org encourages developers to host all of their Drupal-related Open Source code directly on Drupal.org. This is great, because all your OS code will be associated with your account and you will get a lot of extra features such as issue tracking, release publishing, ability to reference other issues and so on. However, current interface of DrupalCore.org website is not the most user friendly, especially when you want to have a quick look at the code of a contrib module.

This is why I think developers should host mirror repositories on another service where the source code can easily be checked through the browser. Why would anyone want to do this? Well, there are dozens of modules that revolve around using one simple hook to achieve certain functionality for example. If you are developing your module, you might want just to check how was that hook used in the contrib module, so you can adjust the code for your project.

To set this up, you will need 2 remote destinations: one on GitHub (or Gitlab, BitBucket, etc.) and the second one on Drupal.org. To keep things simple and self-explanatory, I suggest naming them just like that - github and drupal.

Here's how to set proper destinations:

# Add GitHub source.
git remote add github https:[email protected]/YOUR_USERNAME/YOUR_REPO.git
# Add Drupal.org source for a full project.
git remote add drupal [email protected]:project/YOUR_PROJECT.git
# OR Add Drupal.org source for a sandbox project.
git remote add drupal [email protected]:sandbox/YOUR_GIT_USERNAME/PROJECT_NODE_ID.git

Do note that your git username on Drupal.org can be different than the one you use for logging in to Drupal.org. You can check your username by logging to Drupal.org, going to your profile page and then going to "Edit" -> "Git access".

Now when you want to push the code, here's what you need to do;

# Push the code on GitHub.
git push github
# Push the code on Drupal.org.
git push drupal

If for whatever reason you want to push one branch into another (e.g. local master to 8.x-1.x on Drupal.org), here's how to do that:

git push drupal master:8.x-1.x

That's it!

Last thing: do bear in mind that contributions by other members are easier to track through issues on Drupal.org. If your project is used by others as well, use Drupal.org issue tracking system to be fair to contributors.

Aug 22 2016
Aug 22

One of the many changes in Drupal 8 is adding a block to a region. The block interface has been pretty consistent over the years, so changes to how it works can be confusing at first. You do something over and over again and then “Wait a minute! Things have moved, what do I do?!”. But never fear, the new way of adding blocks to regions is pretty straight forward once you get your head around it.

Create a new block

For this demonstration, we are going to create a new block in the blocks interface (you could also create a block in a custom module, or it could come from another module like Views).

In the admin menu, go to Structure and then Block layout.

The block layout button

You will then land on the main blocks interface page and see a list of all existing blocks and the regions that they belong to.

At the top of the page, you will see two tabs: Block layout and Custom block library. You are currently on the Block layout tab. Click on the Custom block library tab.

You are going to add your own module, so click on the + Add custom block button at the top of the modal. You will then get the add block form. Add the following for the description and body:

  • Description: Hello block
  • Body: Hello, World!

Save the form. You should then get a message to say that the block has been created.

The block you created should now appear on the list of custom blocks.

Next to Sidebar first you will see a Place block button.

Place block

You can add the new block to any region. For the purposes of this exercise, let’s add the block to the Sidebar first region.

Add the block to a region, head back over to the Block layout tab. To add the block to the sidebar first region, click on the Place block.

Place a block button for sidebar first region

A modal will appear with a list of available blocks. These blocks have already been defined in various modules or are custom modules (like the one you just created). You should see the Hello block block that you created above. If it is hard to spot in the list, you can search for it in the Filter by block name field at the top of the modal. To add the block to this region, click on the Place block. Then on the next form (Configure block), click Save

You should then see the block listed under Sidebar first.

New custom block in sidebar first region list

View the block

Go to the homepage of the site. You should now see the block you created in the sidebar left of your site.

The new custom block on the page

Assigning the block to another region

In another change in Drupal 8, you can now assign a block to more than one region. To demonstrate this, try adding the block you created to the Sidebar second region.

  • Go back to the main blocks interface
  • Next to sidebar second click on Place a block
  • In the filter by block name field, search for hello. The hello block you created above should be visible
  • In the operations column, click on place block.

Get more

There are many changes in Drupal 8. I’m going to sharing tutorials and guides to many of them over the coming weeks and months. Be the first to get them

Aug 22 2016
Aug 22

As you'd be aware by now - Drupal 8 features lots of refactoring of from procedural code to object-oriented.

One such refactoring was the way forms are build, validated and executed.

One cool side-effect of this is that you can now build and test a form with a single class.

Yep that's right, the form and the test are one and the same - read on to find out more.

Background

Firstly kudos here to Tim Plunkett who pointed this out to me, and to all of those who championed much of the refactoring that made this even possible.

Testing forms and elements in Drupal 7

In Drupal 7 to test a form, or an element you need the following:

  • A test module with:
    • A hook_menu entry
    • A form callback
    • (optional) A validate callback
    • (optional) A submit callback
  • A web-test (a test that extends from DrupalWebTestCase)

Drupal 8 forms

As you're probably aware from all the example code and posts out there, forms in Drupal 8 are objects that implement Drupal\Core\Form\FormInterface.

Luckily, you can write a test that both extends from KernelTestBase (Drupal\KernelTests\KernelTestBase) that also implements FormInterface. This means you don't need all of the additional routing plumbing you needed in Drupal 7.

Let's look at an example in Drupal - PathElementFormTest (\Drupal\KernelTests\Core\Element\PathElementFormTest). This test is to test core's PathElement (\Drupal\Core\Render\Element\PathElement) - a plugin that provides a form element where users can enter a path that can be optionally validated and stored as either a \Drupal\Core\Url value object or a array containing a route name and route parameters pair. So in terms of testing, the bulk of the logic in the element plugin is contained in the #element_validate callback - PathElement::validateMatchedPath.

There are several different combinations of configuration for the path element as follows:

  • Required and validated with no conversion
  • Required and non validated with no conversion
  • Optional and validated with no conversion
  • Optional, validated and converted into a route name/parameter pair
  • Required, validated and converted into a route name/parameter pair
  • Required, validated and converted into a Url object

So we need to set up several instance of the element on a test form.

So because our test extends from KernelTestBase, but also implements FormInterface, we just build a normal form array with all of these configurations in our implementation of FormInterface's ::buildForm method - see \Drupal\KernelTests\Core\Element\PathElementFormTest::buildForm to see how this is done. We're not interested in doing any additional validation or submission, so our implementation of FormInterface's ::submitForm and ::validateForm can be blank.

Testing the element behaviour

So to test the element validate works as expected for each of the fields, we need to trigger submission of the form. Now in a web-test, we'd use the internal test browser to visit the form on a route and then use a method like BrowserTestBase::submitForm to actually submit the form. But as we're using a kernel test here, there is no internal browser - so instead we can submit directly through the form_builder service (\Drupal\Core\Form\FormBuilderInterface). The code in PathElementFormTest looks something like this:

$form_state = (new FormState())
  ->setValues([
    'required_validate' => 'user/' . $this->testUser->id(),
    'required_non_validate' => 'magic-ponies',
    'required_validate_route' => 'user/' . $this->testUser->id(),
    'required_validate_url' => 'user/' . $this->testUser->id(),
  ]);
$form_builder = $this->container->get('form_builder');
$form_builder->submitForm($this, $form_state);

So firstly we're building a new FormState object and setting the submitted values on it - this is just a key-value pair of form values. Then we're getting the form builder service from the container and submitting the form.

From here, if there were any errors, they'll be present on the form state object. So we can do things likes check for expected errors, or check for expected values.

For example, to check that there were no errors.

$this->assertEquals(count($form_state->getErrors()), 0);

Or to check that the conversion occurred (i.e. the input path was upcast to a route name/parameter pair or Url object).

$this->assertEquals($form_state->getValue('required_validate_route'), array(
  'route_name' => 'entity.user.canonical',
  'route_parameters' => array(
    'user' => $this->testUser->id(),
  ),
));

Or to check for a particular error.

$this->assertEquals($errors, array('required_validate' => t([email protected] field is required.', array([email protected]' => 'required_validate'))));

Summing up

So why would you want to use this approach?

Well for one, the test is damn fast. Kernel tests don't do a full site install, and because there is no HTTP to fetch and submit the form, you get fast feedback. And when you get fast feedback, you're more likely to practice good test driven development.

So if you're building an element plugin for a contrib or client project, I encourage you to start with a test, or rather a form, or rather both. Specify the various configurations of your element and test the expected behaviour.

I'm sure you agree, this is another clear case of Drupal 8 for the win.

Drupal 8 Drupal Development Testing
Aug 21 2016
Roy
Aug 21

Mapping out the moving parts of the content workflow initiative we arrived at this high level grouping of related activities:

  • Create content
  • Review & approve content
  • Publish content
  • Manage the creation, review and publishing process
  • Configure the tools that enable all of the above

For either single items of content or a set of multiple items, bundled in a workspace.

Create content

Everything related to creating new, editing existing content in the first place.

Roles

  • Author
  • Copy writer
  • Photo/image editor

Tasks & activities

  • Review assignments
  • Create content
  • Format content
  • Preview content
  • Request review
  • Edit content based on feedback
  • Review other people’s content
  • Review existing, live content

Review & approve content

All the things that need to happen to get new content ready for publication. Here’s a more elaborate example of a moderation workflow using a workspace.

Roles

  • Editor
  • Marketing associate
  • Archivist

Tasks & activities

  • Review content, give feedback
  • Edit content
  • Preview content
  • Get notified of content conflicts
  • Adapt content for different channels
  • Analyse impact of content changes
  • Review existing content
  • Recover content

Publish content

Actual publication of content and managing its life cycle from then on.

Roles

  • Section editor
  • Legal
  • Compliance

Tasks & activities

  • Define/specify content packages
  • Review content (packages)
  • Audit (legal, compliance)
  • Preview content
  • Approve revivisions
  • (un)publish content items
  • (un)publish content packages
  • Schedule (un)publishing of content
  • Archive/delete content

Manage content workflow

Set the strategic agenda, coordinate with other business units, oversee all of the above.

Roles

  • Managing editor
  • Marketing executive
  • Support & maintenance

Tasks & activities

  • Define content strategy
  • Content planning
  • Coordinate with the business
  • Coordinate with IT
  • Coordinate content delivery
  • Define content assignments
  • Schedule content production
  • Monitor progress
  • Review audit trail

Configure content workflow tools

Providing the tools and processes to enable all of the above.

Roles

  • Administrator
  • Developer

Tasks & activities

  • Configure workflows for content moderation
  • Configure content workspaces
  • CMS configuration: content types, roles & permissions, notification settings…
  • Technical development

Have a look at the visual definition of a workspace and a more fleshed out example of a moderation workflow as well.

Hope this helps clarify the main concepts, activities and relationships in the workflow initiative.

Aug 21 2016
Aug 21
TL;DR The Google Summer of Code period ends, and am glad that I am able to meet all the goals and develop something productive for the Drupal community. In this blog post, I will be sharing the details of the project, the functionality of the module and its current status.

I am glad that I was one of the lucky students who were selected to be a part of the Google Summer of Code 2016 program for the project “Integrate Google Cloud Vision API to Drupal 8”. The project was under the mentorship of Naveen Valecha, Christian López Espínola and Eugene Ilyin. Under their mentoring and guidance, I am able meet all the goals and develop something productive for the Drupal community.

Let me first share why the Google Vision API module may be required.

Google Cloud Vision API bring to picture the automated content analysis of the images. The API can not only detect objects ranging from animals to famous monuments, but also detects faces on emotions. In addition, the API can also help censor images, extract text from images, detect logos and landmarks, and even the attributes of the image itself, for instance the dominant color in the image. Thus, it can serve as a powerful content analysis tool for images.

Now let us see how can we put the module to use, i.e. what are its use cases. To start with, the Google Vision API module allows Taxonomy tagging of image files using Label Detection. Label Detection classifies the images into a number of general purpose categories. For example, classifying a war scenario to war, troop, soldiers, transport, etc. based on the surroundings in the images. This feature of the module is especially important to filter the images based on some tags.

Second feature listing our use case is the Safe Search Detection. It quickly identifies and detects the presence of any explicit or violent contents in an image which are not fit for display. When this feature is enabled in the module, the Safe Search technique validates any image for explicit/violent contents. If found, these images are asked for moderation, and are not allowed to be uploaded on the site, thus keeping the site clean.

Please click here for video demonstration of the two above-mentioned use cases.

Continuing with the other use cases, the third one is Filling the Alternate Text field of an image file. Label, Logo, Landmark and Optical Character Detection feature of the Google Cloud Vision API have been used to implement this use case. Based on the choice entered by the end user, he/she can have the Alternate Text for any image auto filled by one of the four above-mentioned options. The choice “Label Detection” would fill the field with the first value returned in the API response. “Logo Detection” identifies the logos of famous brands, and can be used to fill the field accordingly. Likewise, “Landmark Detection” identifies the monuments and structures, ranging from natural to man-made; and “Optical Character Detection” detects and identifies the texts within an image, and fills the Alternate Text field accordingly.

Next comes the User Emotion Detection feature. This feature is especially important in cases of new account creation. On enabling this feature, it would detect the emotion of the user in the profile picture and notify the new user if he/she seems to be unhappy in the image, prompting them to upload a happy one.

Lastly, the module also allows Displaying the similar image files. Based on the dominant color component (Red, Green or Blue), the module quickly groups all the images which share the same color component, and display them under the “Similar Content” tab in the form of a list. Each item links itself to the image file itself, and is named as per the filename saved by the user. Users should note here that by “similar contents”, we do not mean that the images would resemble each other always. Instead we mean here the same dominant color components.

All the details of my work, the interesting facts and features have been shared on the Drupal Planet.

Please watch this video to know more on how to use the above-mentioned use cases in proper way.

[embedded content]


This is the complete picture of the Google Vision API module developed during the Google Summer of Code phase (May 23, 2016- August 23, 2016).

With this, the three wonderful months of Google Summer of Code phase comes to an end, enriching me with lots of experiences, meeting great persons and working with them. In addition of giving me an asset, it also boosted and enhanced my skills. I learnt a lot of new techniques, which probably, I would not have learnt otherwise. The use of services and dependency injection, constraints and validators, controllers, automated tests and the introduction to concepts of entities and entity types to name a few.
I would put to use these concepts in best possible way, and try to contribute to the Drupal community with my best efforts.

Pages

About Drupal Sun

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

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

See the blog post at Evolving Web

Evolving Web