Author

Jun 30 2016
Jun 30

We’ve been getting questions about the Group Drupal module and how it relates to the general permission system that ships with Drupal. More specifically, the difference between group roles and user roles. So we figured we’d post a short explanation. 

Consider a regular Drupal site as a one-level thing.

There’s roles and permissions that allow you to do things, but it’s a flat structure. Either you have a permission across the entire site or you don’t. Group adds depth to that structure, allowing you to create smaller levels underneath the main one.

Inside those sub-levels you can have roles and permissions too, just like on the main level. The difference lies in the fact that they’re called group roles and group permissions and they only apply within their section of the site within their group.

Let’s use a practical example to demonstrate this. Suppose you’re building a news website and you allow John and Jane to post articles. But John only writes about sport and Jane only really knows about fashion. Yet they can both publish articles about anything. This is the default story in any Drupal website.

Group would allow you to divide the website into sections such as “Sport”, “Fashion”, “Domestic”, etc. and allow John to only publish articles in Sport and limit Jane to writing about Fashion.

This is just one of the many use cases Group can solve for you.

Interested? Try it out! It’s available for both Drupal 7 and 8, find out more here: https://www.deeson.co.uk/labs/9-reasons-group-drupal-8-awesome

Jun 29 2016
Jun 29
Drupal 8 Media module at Google Summer of Code 2016 slashrsm Wed, 29.06.2016 - 23:11

In this video Vijay Nandwani, our GSoC student, explains his progress on the Drupal 8 Media module.

He also wrote a blog post where he explains more technical details.

Jun 29 2016
Jun 29
1/2 Million Views of the Drupal 8 Beginner Class

Drupal 8 is now eight months old.

Has it been a success so far? Yes. Drupal 8 is running over 100,000 sites and is now more popular than Drupal 6.

In our own way, we've tried to help support Drupal 8's launch. We set ourselves a goal to help as many people as possible to use Drupal 8. We launched a Kickstarter project which provided enough financing to release over 200 free videos on YouTube. The training is the best available for Drupal 8, and it’s completely free.

The first videos were released were in The Drupal 8 Beginner Class

Today, I'm delighted to say we reached a major milestone. The Drupal 8 Beginner Class has been viewed over half a million times. That's a lot of people learning Drupal 8!

Here's the intro video from the Beginner class:

[embedded content]

Even 8 months after release, the popularity of the class shows no sign of dropping. The image below shows over 20,000 weekly views for the Drupal 8 Beginner Class, since the beginning of 2016. There's a good chance of passing one million views by the end of 2016!

d8-stats-june-2016

Next week: we launch our new Drupal 8 Site Building class

This Beginner class introduces people to all the key aspects of Drupal 8.

Next week, thanks to the support of Glowhost, we're going to launch the follow-up to the Drupal 8 Beginner class. 

This follow-up will be called “The Drupal 8 Site Building Class”.  This class is designed to help people learn how to build significantly more powerful sites with Drupal 8.

Bookmark or subscribe to our YouTube channel to be the first to know about next week's launch!


About the author

Steve is the founder of OSTraining. Originally from the UK, he now lives in Sarasota in the USA. He was a teacher for many years before starting OSTraining. Steve wrote the best-selling Drupal and Joomla books.


Jun 29 2016
Jun 29

During this last week, Google Summer of Code students must have submitted their midterm evaluation and waited for their mentors' evaluation. During these first weeks, I have been working on the main components of the Social API project. These components are:

  • Social API: contains the basic and generic methods, routing settings, and permissions every Social API sub-module will need
  • Social Auth: implements methods and templates that will be used by login-related modules
  • Social Post: provides methods to allow autoposting to social network’s accounts
  • Social Widgets: allows sub-modules to add functionality to add widgets (like buttons, embedded content) to node, blocks, etc.

There are other modules which are used to test and develop the abstraction of these projects. They can be found at the Drupal Social Initiative github repository.

Fortunately, on June 27th I received an email stating I have passed the midterm evaluation. This means I will have the chance to continue working on my project as a GSoC student!

Hi gvso,

Congratulations! You have passed the midterm evaluation

Social Auth abstraction

As a mentioned above, one of the four components of the Social API project is Social Auth (social_auth), which provides an abstract layer for modules which allow user registration/login in a Drupal Site.

To develop the Social Auth module, we created (actually adapted) a module for user login via Facebook to provide an and test the abstract layer. This implementation can be found at my github repository (simple_fb_connect). Nonetheless, to make sure that this abstraction works with other implementors, on June 10th we agreed to create another module for user login. For this purpose, we chose to work with Google API  as we believe most users would have a Google account. Therefore, during last week I have been working on a implementor called Google Login (google_login).

Social Auth integration listSocial Auth integration list

This module, Google Login, did not require any change in the Social Auth code. On the one hand, I am glad that it works with the current architecture. On the other hand, I am unhappy as I was looking for finding new requirements to challenge myself in re-adapting the Social Auth abstraction.

As of current, the Google Login settings form only allows to input the Client ID and Client Secret. It adds a Google+ icon which appears on the Social Auth Login block. Furthermore, It automatically redirects users who log in to the user page /user/{uid}.

Social Auth Login blockSocial Auth Login blockGoogle Login Settings formGoogle Login Settings form

 

After working on the module described above, I could conclude that the current abstraction proposed by the Social Auth works perfectly. However, we have tested it with two implementors (Facebook and Google) so far, so we can not assure that it would do so with any other social networking service. Nonetheless, we will keep refactoring the code if needed to adapt it to requirements.

Beta Release

We are happy to announce that we have released a beta version of Social API (social_api) and Social Auth (social_auth) modules. We invite you to test the projects and report any issue you find. And if you would like to add some new features, we will be glad to read your ideas in the issue queue.

Next week

In my last weekly summary, I described the module facebook_buttons which is based on Social Widgets to provide Facebook buttons. So far, it only allows to add Like buttons to teasers and nodes; nonetheless, it should also provide options for the Send and Share buttons. Therefore, I will be working on adding these features to the module and releasing a beta version of it in the Drupal website.

As always, feel free to contact me if you have any question. You can also collaborate with the Social Initiative projects (social_apisocial_authsocial_post, and social_widgets). We also have our weekly meetings, so follow the Social Initiative and join us on Fridays.

Stay tuned for the next weekly summary!

Jun 29 2016
jam
Jun 29
Each day, between migrations and new projects, more and more features are becoming available for Drupal 8, the Drupal community’s latest major release. In this series, the Acquia Developer Center is profiling some prominent, useful, and interesting projects--modules, themes, distros, and more--available for Drupal 8. This week: Inline Entity Form.
Jun 29 2016
Jun 29
TL;DR The safe search constraint feature is now committed to the module along with proper web tests. So, this week I started off with a new feature offered by the Google Cloud Vision API- “Image Properties Detection”. It detects various properties and attributes of an image, namely, the RGB components, pixel fraction and score. I have worked on to detect the dominant component in the image present in any content, and display all the contents sharing similar dominant color. It is pretty much like what we see on the e-commerce sites.
Previous week I had worked on writing web tests for the safe search constraint validation on the image fields. This feature is now committed in the module Google Vision API.
This week I have worked on implementing another feature provided by the Google Cloud Vision API, namely, Image Properties Detection. This feature detects the color components of red, green and blue colors in the images along with their pixel fractions and scores. I have used this feature to determine the dominant color component (i.e. red, blue or green) in the image, and to display all those contents which have the same dominant color in their images.
I have developed the code which creates a new route- /node/{nid}/relatedcontent to display the related contents in the form of a list. This concept makes use of Controllers and Routing System of Drupal 8. The Controller class is extended to render the output of our page in the format we require. The contents are displayed in the form of list with the links to their respective nodes, and are named by their titles.
In addition to the grouping of similar contents, the colors are also stored in the form of taxonomy terms under a taxonomy vocabulary programmatically generated under the name Dominant Colors.
This issue is still under progress, and requires little modification. I need to add the link to the new route in each of the nodes, so as to  get a better interface to access those contents. Henceforth, I will put this patch for review.
A very simple example of creating routes and controllers in your module can be found here.
Jun 29 2016
Jun 29
TL;DR It has been over a month since I started working on my Drupal project “Integrate Google Cloud Vision API to Drupal 8”, and gradually I have crossed the second stage towards the completion of the project, first being selection in the Google Summer of Code 2016 programme. Here, I would like to share my experiences and accomplishments during this one month journey, and also I would like to summarize my further plans with the project and the features which I would be implementing in the coming two months.
Let me first describe the significance of this post and what actually does “midterm submission” means? The GSOC coding phase has been divided into two halves, viz. Midterm submission and Final submission. In the first half, the students try to accomplish around 50% of the project, and submit their work to the mentors for evaluation. Those who passed the midterm evaluations are allowed to proceed further and complete the remaining portion of their project.
Now coming back to my experiences, after successfully passing through the Community Bonding period of the GSOC 2016 programme, now it was the time for start coding our project proposal to reality. As I had shared earlier that during the Community Bonding period, I came to know that the project has already been initiated by Eugene Ilyin,(who is now a part of my GSOC team). So, we discussed upon the project and set a roadmap of the project and the goals we need to achieve in the GSOC period. I had started coding the very first day of the coding phase, moving the new as well as existing functions to services. My mentors Naveen Valecha, Christian López Espínola and Eugene Ilyin really helped me a lot and guided me whenever and wherever I needed their guidance and support. They helped me to get through new concepts and guided me to implement them in the most effective way to make the module the best that we could.
During this period, I also came to learn about a lot of new techniques and concepts which I had not implemented earlier. Right from the very first day of the coding period, I have been coming across new things everyday, and it is really interesting and fun to learn all those techniques. In this one month period, I learnt about services and containers and how to implement them. The post on Services and dependency injection in Drupal 8 and the videos of Drupalize.me were of great help to understand the concept of services and implement dependency injection. I also learnt about the use of validators and constraints and how can they be implemented both on general basis or specifically on fields. I also learnt about how to create test modules and alter various classes and their functions in our tests so as to remove the dependency on web access or on valid informations for our testing purposes. I learnt new things every day and enjoyed implementing them to code our module plan into reality. At present, the module supports the Label Detection feature of the Vision API, along with the tests to verify whether the API key has been set by the end user or not. Currently, the feature of Safe Search Detection is available as a patch which can be found here, which would soon be committed to the module.
I have shared all the details of my work on the Drupal Planet. In addition, I have also uploaded a video demonstrating How to use Google Vision API module.
Jun 29 2016
Jun 29

Drupal events always fascinate me. They don’t just provide a wonderful environment for learning from each other, to contribute to Drupal together during code sprints, and to meet new people, but they make the community stronger as well. Drupal Developer Days is probably one of the best kinds of events to make this all happen in one place. 

Since helping organize Drupal Developer Days in 2014 in Szeged, I was really excited to see how things go at other Drupal Dev Days. Sadly, I missed DDD 2015 in Montpellier, so attending the event in Milan sounded like a good idea. Until this June, my part in Drupal events was mainly organizing and volunteering, and of course attending sprints, but this time I was also a speaker, which (for me at least) made things a bit different. From Cheppers, Miro Michalicka joined me, and he gave a talk as well, about Drupal 8 REST.

zs+m

Drupal Developer Days’s format is focused mainly on sprints, but there are also sessions and BoFs. In Milan, the event went on for six days, which gave us enough time and space to do everything we can to make the most of our own experiences. In my case, submitting a session proposal about a totally non-techy talk (fyi: How to Drupalcamp) was an interesting addition on top of the regular ‘running around, fixing stuff, making sure all goes well’ things. I also wanted to help out as volunteer, as I have organized a DDD myself before, I had experience with these things, and I was very happy that the wonderful organization team appreciated this.

So, how was Drupal Dev Days in Milan?

The event was Tuesday June 21st to that Sunday, the 26th, with sprints on all six days and sessions on three days. Having almost 400 attendees in one place requires focus, and I believe the Italian organization team did a fantastic job. Here’s a list of volunteers: Alessandra Petromilli, Alessandro Sibona, Andrea Pescetti, Antje Lorch, Chandeep Khosa, Chiara Carminati, Claudio Beatrice, Edouard Cunibil, Fabiano Sant'ana, Guillaume Bec, Julien Dubois, Kester Edmonds, Luca Lusso, Marcello Testi, Marco Moscaritolo, Paolo Libanore, Pierluigi Marciano, Riccardo Bessone, Simone Lombardi, Tamer Zoubi, Yan Loetzer, Yi Yuan, Zsófi Major.

vol

We consumed a lot during this week - 800 liters of water, 100 kgs pizza (ofc!), and 1,200 coffees went down the throats of the attendees. The food was wonderful, tasty and very diverse - we could all find our preferred snacks during lunch breaks. And yeah, GO GO healthy food on all Drupal events!

Sprints - let the numbers talk!

One of the best slots a DrupalCamp can have is sprints. This is where the actual work gets done, bringing together many, many excited contributors to make better progress by helping each other. Of approx. 373 attendees, 107 signed up to the sprints (and most likely even more were sprinting), fixing a total of 82 tickets, and 217 more are now either in Needs Review, Needs Work, Active or RTBC. You can check the contrib kanban page for more details.

So many initiatives, so many people! As Cheppers also takes part in improving Drupal UX, I was happy to see so many people working on the UX and UI initiative, and the Media initiative, the Search API, Open Social and of course Drupal Commerce 2 were pretty populated with contributors. To see the variety of sprint topics, here’s the sprint planning sheet.

sprintersPhoto by dasjo

After my session I could also take part in the work, I translated modules into Hungarian, which gave me the satisfaction of finally actually doing something. Now Chaos tool suite (ctools) 8.x-3.0-alpha26 and Pathauto 8.x-1.0-alpha are both available in Hungarian as well.

Sessions

First of all, I am extremely happy to say that 3 out of 5 keynotes were held by women, and overall it was great to see that many women attended DDD itself. This is wonderful, and truly shows that this field is diverse and inclusive. One of the sessions, Are Geeks from Mars and Geekettes from Venus? was a panel discussion directly about gender & diversity. All the talks were really great and useful, it was great to see so many people performing their sessions in a language that isn’t their native language. You can find the program here, videos will be uploaded soon.

Cheppers talks

Miro, our Drupal Developer talked about Drupal 8 REST, in a shorter track, and despite the fact that there were two other sessions at the same time about similar topics, he also had a rather large audience. Here are the slides.

miro

My talk was about the one thing I really have experience in: How to organize DrupalCamps? This was my very first real talk at a Drupal event, and despite it not being a very techy topic, I was happy to have a nice audience and positive feedback during and after the session. Organizing DrupalCamps is really a great way of contributing to Drupal, and I hope I can continue my Drupal and speaker career with this topic in the future. You can check out my slides for some details.

zsPhoto by dasjo

The video recordings of both of our sessions will be published soon.

Social events

Of course, Drupalistas like to take some break from work, and it was no different at this DDD. Social events are the best way to get to know each other a little bit more outside of what we publicly do. Thankfully, we were not missing a minute of enjoying our time together.

As speakers, we were lucky to attend a great speaker & volunteer dinner. It was IN-CRE-DI-BLE! I’ve never seen that amount of courses during one meal. Literally, after eating our first starter, a seafood platter, then the second course, fried veggies, the following two rounds of hilariously good pasta and another two rounds of pizza challenged our bellies big time. Thank you again for feeding us well, food is always the best way to the heart ;)

On Thursday we had an awesome social evening, with great food (again!), and superb beers. All in all, we consumed at least 500 beers during the night, which of course resulted in some very great discussions about Drupal, community, work, and life.

j+pPhoto by dasjo

To celebrate the session days, as a goodbye gift we were invited to a Night at the Museum, at Leonardo3 at Galleria Vittorio Emanuele II, to study Leonardo Da Vinci’s life and work, who spent 20 years in the city of Milan. 

leonardoPhoto by dasjo

All in all Drupal Developer Days 2016 in Milan was wonderful. Thanks so much for all the great work and for having us! For next year’s event you can submit your proposal here.

Here is a highlight of upcoming events in 2016. Check out Drupical to find a full list.

Hope to see you soon somewhere!

Jun 29 2016
Jun 29

Everyone has a routine. For some, it’s their morning coffee, for others it’s going to the gym after work. For me, it’s heading to Mangia Pizza every Thursday from 7pm-9pm, for the last 6 years. Why do I do this? Because the Austin Drupal Dojo meets every Thursday, and we have a great crowd!

Members of the Austin Drupal Dojo at a meeting.Buster, Chris, Fito, Irma, James, John, Marc, Mark, Nick, me (behind the camera) and others at the August 27, 2015 Austin Drupal Dojo.

The Austin Drupal Dojo is a meetup where anyone is welcome to hang out with other Drupalistas in a "hive mind" environment. There are no set topics or presentations. The pizza is delicious, beer refreshing, and conversations vary wildly. Most people bring a laptop and a project, but others just come for the community.

Our regulars range from Drupal experts, to hobbyists, to newbies. From full-time employees, to freelancers, to those looking for work. We also have a steady stream of folks who are looking for help. Maybe they’re just curious about Drupal, or need to learn it for a new job, or want to start their own business. The Drupal community is known for it’s welcoming atmosphere, and the Austin Drupal Dojo is an exemplary model of that community spirit. Our members jump at the chance to answer questions and help those in need, often sparking a group conversation about best practices and possible solutions.

Many of our members contribute to the other Austin Drupal Meetups (yes, we have more than one!) by speaking and/or organizing, and to the Drupal project in general by fixing core/contrib/documentation and organizing Sprint Weekends. When I became the de facto organizer, attendance was modest, and I never imagined it could blossom into such a great group. It’s been my privilege to work alongside these members of our community, and I’d like to thank everyone who’s joined us, past, present, and future.

If you’re ever in the Austin area, grab your laptop, appetite, and come join us!

What: Austin Drupal Users Group - Drupal Dojo
When: Every Thursday 7-9pm
Where:

Mangia Pizza
8012 Mesa Dr
Austin, Tx 78731
(512) 349-2126

Jun 29 2016
Jun 29

With our new configuration management system as part of Drupal 8 core we now have a powerful system to manage site configuration between our different environments. This system does not declare a strict workflow for how to use configuration. In this post I’d like to explore some workflows we have been exploring.

First let's define what site configuration is.

There are two types of configuration in a Drupal site. First, simple configuration which stores basic key/value pairs such as integers, strings, and boolean values. Second, configuration entities, which we explored in this post. Basically configuration entities are more complex structures that define the architecture of our site. This would be things such as content types, views, and image styles.

Both types of configuration entities are exportable.

Where does this configuration live?

Site configuration lives in two places depending on its stage in life (no pun intended). There are two stages in a piece of configurations life:

  1. Staging

  2. Active

Active configuration lives in the database by default. It is the configuration that is currently being used by the site. Staged configuration lives on the file system by default.

When you make changes to the site within the web interface, for example changing the site name, you are changing the active configuration. This active configuration can them be exported and staged on another instance of the same site. The last piece is key:

Configuration is only to be moved between instances of the same site.

For example, I change the site name on our DEV environment and want to move this change to our TEST environment for testing.

Ok, let's talk workflows

There are a few ways we can manage the site configuration. Site configuration, like our code should follow a “flow up” model. That is, configuration will be committed to our git repo and moved up into higher order environments:

LOCAL ? DEV ? TEST ? PROD

In this workflow configuration changes will be made as far down the chain as possible. In this case on a developer's local environment. These configuration changes should be exported and committed to their own branch. This branch can then be pushed for review.

Once pushed these configuration changes will be “staged” on the DEV environment. A site administrator will need to bring these staged changes into the “active” configuration. There are two ways we do that today:

  1. Through the sites UI from under ‘admin/config/development/configuration’

  2. Using a drush command ‘drush cim’ command to import staged configuration to active.

From what we are seeing this seems to be the defacto workflow at this point.

Further workflow Ideas

I am thinking there could be some interesting workflows that could emerge here. One idea is to have a branch (or tag) that triggers configuration imports using drush and fires off some automated tests. If all passes then merge into another designated branch for movement to a live environment.

Another idea is to use some of the emerging contrib modules to manage different “configuration states”. I believe this was discussed in the config_tools projects issue queue. Using this idea we can tag known “good” configurations and move between different “configuration states” of a given site. I am thinking we could even have the configuration hosted in separate repo then our code, if that makes any sense.

Bottom Line  

The new configuration management system offers a powerful tool to move changes on our sites between different instances. It does not however define an exact workflow to follow. I look forward to talking to folks on how they leverage this system to coordinate the efforts of high performing teams!

If you or your team is using this in different ways we would love to hear about it!

Jun 29 2016
Jun 29

What feelings does the name Drupal evoke? Perceptions vary from person to person; where one may describe it in positive terms as "powerful" and "flexible", another may describe it negatively as "complex". People describe Drupal differently not only as a result of their professional backgrounds, but also based on what they've heard and learned.

If you ask different people what Drupal is for, you'll get many different answers. This isn't a surprise because over the years, the answers to this fundamental question have evolved. Drupal started as a tool for hobbyists building community websites, but over time it has evolved to support large and sophisticated use cases.

Perception is everything

Perception is everything; it sets expectations and guides actions and inactions. We need to better communicate Drupal's identity, demonstrate its true value, and manage its perceptions and misconceptions. Words do lead to actions. Spending the time to capture what Drupal is for could energize and empower people to make better decisions when adopting, building and marketing Drupal.

Truth be told, I've been reluctant to define what Drupal is for, as it requires making trade-offs. I have feared that we would make the wrong choice or limit our growth. Over the years, it has become clear that defining what Drupal is used for leaves more people confused even within our own community.

For example, because Drupal evolved from a simple tool for hobbyists to a more powerful digital experience platform, many people believe that Drupal is now "for the enterprise". While I agree that Drupal is a great fit for the enterprise, I personally never loved that categorization. It's not just large organizations that use Drupal. Individuals, small startups, universities, museums and non-profits can be equally ambitious in what they'd like to accomplish and Drupal can be an incredibly great fit for them.

Defining what Drupal is for

Rather than using "for the enterprise", I thought "for ambitious digital experiences" was a good phrase to describe what people can build using Drupal. I say "digital experiences" because I don't want to confine this definition to traditional browser-based websites. As I've stated in my Drupalcon New Orleans keynote, Drupal is used to power mobile applications, digital kiosks, conversational user experiences, and more. Today I really wanted to focus on the word "ambitious".

"Ambitious" is a good word because it aligns with the flexibility, scalability, speed and creative freedom that Drupal provides. Drupal projects may be ambitious because of the sheer scale (e.g. The Weather Channel), their security requirements (e.g. The White House), the number of sites (e.g. Johnson & Johnson manages thousands of Drupal sites), or specialized requirements of the project (e.g. the New York MTA powering digital kiosks with Drupal). Organizations are turning to Drupal because it gives them greater flexibility, better usability, deeper integrations, and faster innovation. Not all Drupal projects need these features on day one -- or needs to know about them -- but it is good to have them in case you need them later on.

"Ambitious" also aligns with our community's culture. Our industry is in constant change (responsive design, web services, social media, IoT), and we never look away. Drupal 8 was a very ambitious release; a reboot that took one-third of Drupal's lifespan to complete, but maneuvered Drupal to the right place for the future that is now coming. I have always believed that the Drupal community is ambitious, and believe that attitude remains strong in our community.

Last but not least, our adopters are also ambitious. They are using Drupal to transform their organizations digitally, leaving established business models and old business processes in the dust.

I like the position that Drupal is ambitious. Stating that Drupal is for ambitious digital experiences however is only a start. It only gives a taste of Drupal's objectives, scope, target audience and advantages. I think we'd benefit from being much more clear. I'm curious to know how you feel about the term "for ambitious digital experiences" versus "for the enterprise" versus not specifying anything. I'm hoping we can collectively change the perception of Drupal.

PS: I'm borrowing the term "ambitious" from the Ember.js community. They use the term in their tagline and slogan on their main page.

Jun 29 2016
Jun 29

CKEditor is a popular WYSIWYG (What You See Is What You Get). In Drupal default WYSIWYG editor is CKEditor. CKEditor has many of its own plugins.

Recently I got an opportunity to work for some top level media companies like Time Inc and Farm Journal with my Valuebound Teammates. It was a challenging experience , especially on the area of content creation and management work flow.  

We got a requirement where “Content Authors” should be able to upload the images in between  paragraphs of content. When the end user clicks on those images, the image has to be shown as a popup. So we decided to create a CKEditor plugin so that the users who are having  “Content Author” or “Content Editor” roles will be able to upload the image which will show up in a popup when it’s clicked. Because of this requirement, we were fortunate to develop a module called Simple Image Popup and  contribute back to Drupal Community.

Here we are going to see how to create a new plugin for CKEditor in Drupal 8, which inserts image wrapped in anchor tag.

Steps to create CKEditor plugin.

  1. Define and add basic plugin info in hook_ckeditor_plugin_info_alter() in your module file.
    File: my_module.module
    
     
  2. Define MyPlugin class which defines plugin, extending CKEditorPluginBase and implementing CKEditorPluginConfigurableInterface. In this plugin class we need to define the following methods:
    File: MyPlugin.php
    
    1. isInternal - Return is this plugin internal or not.
    2. getFile - Return absolute path to plugin.js file.
    3. getLibraries - Return dependency libraries, so those get loaded.
    4. getConfig - Return configuration array.
    5. getButtons - Return button info.
    6. settingsForm - Defines form for plugin settings, where it can be configured in ‘admin/config/content/formats/manage/full_html’. For example, this form shown below is where we can set the max size, width and height of the image, against which image will be validated when uploading an image.CKEditor Plugin setting form.
  3. Define client side plugin.js. Basic things we need to implement in plugin.js are:
    File: js/plugins/myplugin/plugin.js
    
    1. Add the new plugin to CKEditor. In beforeInit method we have to define our plugin command and add UI button which in turn triggers our plugin command on click of UI button as follows,
    2. Define routing for the dialog, which points to Form controller.
      File: my_module.routing.yml
      
    3. Define plugin dialog form and its form submit handler as we normally do in Drupal 8. In addition, on form submit we need to return ajax response command like below
      File: my_module\Form\EditorImagePopupDialog
      
      And whenever edit operation happens we need to populate existingValues json object in plugin.js file, so we can get those values in buildForm with the below line of code.

Finally configurations.

  1. Go to ‘admin/config/content/formats’, then click on configure action link for which format this plugin needs to be added.
  2. In configuration form, we can drag and drop newly created plugin button to CKEditor toolbar.
  3. Now, save the configuration form.
     

Hurray…! Now we can use our newly created CKEditor plugin. For more reference, find the contributed module, in which we have created CKEditor plugin for Drupal 8 Simple Image Popup.

Jun 29 2016
Jun 29

This one tripped me up on a recent Drupal 8 project.

Easy to miss when you're working in a development oriented environment with things like JavaScript preprocessing turned off.

A JavaScript file was being added just fine with aggregation turned off, but not getting added with it turned on.

While working on a Drupal 8 client project we were using our module's .libraries.yml file to add a custom plugin for Jquery Validation. Our plugin was using the Moment.js date library to add strict date checking so we could check for overflows. The default date validation in that plugin treats dates like 55/55/5555 as valid - because they are cast to valid JavaScript dates by the browser. We needed to detect overflows and report an error.

It was working all fine locally, but when I sent a Pull request, it didn't work in the Pull request environment (we have per pull-request environments).

After some head scratching I found the issue.

My libraries.yml definition looked like this:

moment_date:
  version: VERSION
  js:
    js/moment_date: {}
  dependencies:
    - clientside_validation/jquery.validate
    - mymodule/moment
    - core/modernizr

If you picked it, I've missed the .js suffix on the file name.

Locally I was working with developer optimised settings, so I had a settings.local.php with the following

$config['system.performance']['js']['preprocess'] = FALSE;

i.e. I was disabling JavaScript aggregation so I could rapidly iterate, something you'd normally do.

Problem was on the Pull Request environment JavaScript aggregation is turned on (as it should be).

And mysteriously this made a difference.

My libraries.yml file was just plain wrong, it should have been

moment_date:
  version: VERSION
  js:
    js/moment_date.js: {}
  dependencies:
    - clientside_validation/jquery.validate
    - mymodule/moment
    - core/modernizr

But with JavaScript aggregation turned off, my webserver was adding the file, sending moment_date.js when moment_date was requested - silently hiding the bug from me.

A tricky one, but one worth sharing.

Drupal 8 libraries JavaScript
Jun 29 2016
Jun 29

This week I worked on making the module a bit flexible via integrating pluggable systems into it. This is something we had planned initially while writing the architecture document for the module, but couldn’t pursue it earlier because our focus was on developing a working prototype first. But since that’s done, we’ve reached the perfect time for this development. It should be noted that the pluggable systems are important because Pubkey Encrypt deals with security, and it is essential for the module’s success to be as flexible as possible. In this way, users would be able to configure the behavior of the module as per their organizational security standards and other demands not provided by the out of the box functionality.

Accordingly, here are the two pluggable systems (i.e. plugin types) I added to the module:

  • Asymmetric keys generator: An implementation for this plugin type would address the responsibilities of Public/Private keys generation, encryption of a piece of content with Public key and decryption of a piece of encrypted content with Private key.

By having this logic encapsulated into a pluggable system, users would be able to use the asymmetric keys generator of their choice (e.g. OpenSSL library, Elliptic curve cryptography library etc.) simply by providing a corresponding plugin implementation.

  • Login credentials provider: An implementation for this plugin type would handle the selection of relevant user data attributes needed for key generation which Pubkey Encrypt would use during data encryption/decryption operations.

By having this logic encapsulated into a pluggable system, users would be able to use the login credentials of their choice (e.g. password, PIN etc.) simply by providing a corresponding plugin implementation.

For developing the pluggable systems, I referred to this really great article on D8 plugins, Unravelling the Drupal 8 Plugin System, provided by Drupalize.me. This in-depth article not only describes the higher-level overview of Drupal 8 plugins but also contains a step-by-step tutorial on creating your own plugin types along with some sample code. So I created the plugin systems and then added the configuration layer as an “Initialization settings form”. Through this form, users would configure and initialize the module so it could start working. See it in action here:

Pubkey Encrypt initialization settings form.

In my weekly meeting with mentors Adam Bergstein (@nerdstein) and Colan Schwartz (@colan), we discussed the overall architecture of the pluggable systems I implemented. We also made yet another design-related decision that we won’t be allowing anyone to change their choice of plugins once the module has been initialized. The reason is, that allowing for a plugin change after the module is initialized means re-initialization of all users’ keys and re-encryption of all data. And this is the kind of use-case we’ll never encourage as the process involved will have a lot of overhead on the module’s performance. So this basically means that if a user has chosen to use OpenSSL library for the generation of asymmetric keys, then he’s bound to use that for the lifetime of module. If he really wants to change any plugin, the only option available for him would be to uninstall and reinstall the module as per his desired configuration. I’ve created an issue on the D.O project page to formally capture this decision.

Restricting the change of plugins after the module has been initialized.

Then I wrote default plugins for the two pluggable systems, so to make the module behave as a plug-and-play solution for typical use cases. We’ll ship the following default plugins via a submodule within the module:

  • RSA-based asymmetric keys generator using OpenSSL php extension.
  • User passwords-based login credentials provider.

After integrating the pluggable systems into module, I thought it’d be really cool if I could make the “asymmetric keys generator” plugin type configurable from the UI. The reason is, that a keys generator plugin could ask for user configuration like key size, digest method etc. I couldn’t find any tutorial on how to do this, but I figured out that the Encrypt module provides one such configurable plugin type. So I used the source code from the Encrypt module for learning how to accomplish the task, but still got stuck in it for two days. Though I really enjoyed the learning process and after spending hours exploring Encrypt’s source code and running it step-by-step via a debugger for better understanding, I finally accomplished the task. I also tweaked the default asymmetric keys generator plugin to reflect this change so to make it easy for other developers to use this default plugin implementation as an example of how their plugin implementations can handle the user configuration. See it in action here:

An Asymmetric Keys Generator plugin configurable from the UI.

After that, I fixed the tests to have the module initialized before making any assertions. Re-running the tests revealed that everything is working completely as expected. Have a look at all the work I did this week here: Pubkey Encrypt - Week 5 work. My mentors have yet to review and merge the commits.

Jun 28 2016
Jun 28

Since the web was born, information technology (IT) professionals have been working to make sure their organizations had a presence online. In the past few years, we have seen a shift in those digital dollars - right onto the Marketing Department’s doorstep. This signals a larger pivot in thinking. Your website is no longer a stagnant or a “nice to have” piece of technology, but a dynamic, evolving hub for your company’s marketing, branding and lead generation efforts. The development of “decoupled” architecture serves to support this shift by giving marketers more flexibility to create components that provide unique user experiences across their customer’s journey. In simplest terms, “decoupled” refers to the separation between the back-end of your website (your CMS) and the front-end (or many front-ends). You can learn more in a recent article from Drupal’s founder, Dries Buytaert.

Here are 4 benefits that Enterprise Marketers should be excited about when leveraging this approach.
 

Experience Management

How often do you say “what if our website could…” and then dial yourself back because of time or resource constraints from your design or development team? A decoupled architecture makes “Yes” a far more often conclusion to support new ideas for your site. Drupal is traditionally more rigid in its design capabilities and while Drupal 8’s integration of Twig has provided a large leap forward, there are still limitations when you’re aiming to create unique, dynamic components to support your campaigns. With a decoupled system, Marketers are free to let their creativity reign, without running into limitations that previously existed.  
 

Flexibility for Constant Evolution

Making the decision for a website redesign is a huge commitment of time and resources. In many cases, marketing teams push their website past its expiration date. Teams are often forced to choose between accepting their website as it stands (even if the design is stale or not meeting expectations) or dedicating the resources for a redesign and potentially placing other strategic initiatives on the back burner.

However, when a website is built using decoupled architecture, Marketers have far more flexibility to upgrade the back-end technology powering a site or to update design and create new experiences independently of each other. You’ll have the opportunity to create and change experiences as you learn more about your customers and prospects by working with your design team. This allows your front-end team full control over the user experience by leveraging  their preferred tools and Drupal’s strength as a CMS. This means that marketers can engage designers based on their vision and strategy and break free of the limitations of a given tool and that designers can use the best tool to accomplish the desired feature. In our recent series on Weather Underground, Matt Davis gave a great example of how this worked with Drupal and Angular JS.
 

“Write once, publish everywhere” becomes standard

Drupal is designed with large organizations in mind when it comes to storing and organizing content in a single repository. In addition, Drupal 8’s upgraded publishing functionality provides contributors a more streamlined experience for content creation. You are now able to give content creators a streamlined editorial experience and leverage Drupal 8’s RESTful API to make it more straightforward than ever for external applications or services to interact with content on your Drupal site.  

Decoupled architecture requires Drupal’s core web services to provide data to the front-end, pushing content to other places becomes more manageable. This is relevant because once you publish content in an article, it can be available for use in many different places, including mobile apps, IOT devices, various feeds, and in other ways that haven’t been created yet.
 

Right tool for the right job

A recent study by Black Duck Software found that more than 78% of enterprises run on open source, with fewer than 3% indicating that they don’t rely on any open software. Given the key drivers for open source adoption are flexibility, scalability and speed, it’s no surprise that Drupal has become more popular than ever in recent years with Enterprise organizations. These organizations have learned that the more content you have, the stronger Drupal is at helping to categorize, store and structure that information.

What makes Drupal particularly unique is the back-end experience. When using a decoupled architecture to separate the front-end and back end, you open the door to a variety of potential programming languages and design philosophies to accomplish your goals. This means the options are limitless with  what your team can envision, what your UX/UI team can create, and who can help you create them.

Overall, decoupled architecture is a concept gaining popularity across the development community given the benefits and potential upside. In our next post, we’ll discuss the various options for decoupling, the differences and pros/cons of each.

Additional Resources

Real World Drupal 8 for Front End Developers | Blog Post
Drupal 8 for Marketers: SEO | Blog Post
An Overview of Drupal 8’s Business Benefits | Webinar Recording

Jun 28 2016
Jun 28

Hello Michigan Drupal folks and beyond,

The final call for sessions for this year's DrupalCamp Michigan will be July 5th. Please submit your session proposals before that time:

http://2016camp.michigandrupal.com/sessions

In the mean time take a look at some of the great sessions proposed by the community:

http://2016camp.michigandrupal.com/sessions/proposed

Jun 28 2016
Jun 28

I recently had to create a new layout that mimicked the Pinterest layout. Masonry to the rescue! (sorta...) With Drupal already crapping out the content via views, we could just use the Masonry views plugin right? Sorta. Well, it worked. ... sorta. There were problems, and I don’t like problems, only solutions.

I like a very NON-hacky way of doing things. Masonry views worked for the desktop screen size but failed miserably for anything smaller. We were working with a responsive design, so it was unacceptable. There was simply just no amount of tweaking the options and CSS that it came with, that I was happy with. I’m also not a fan of CMS plugins controlling layout. There tend to be crappy implementations and far less control. I don’t speak for everything, of course, just my experience.

I wanted to control.. as much as I could. So I abandoned the views plugin, and just decided to use the raw jQuery plugin, and use my own CSS.

This assumes ya know how to use requireJS and jQuery plugins.

Step 1 - The view.

So, the view just had to output the HTML, nothing else. Set the output format for the view to ‘Unformatted list’. Nice, just simple, clean Drupal output.

Step 2 - Including the jQuery plugin code.

I’m also not a fan of including boatloads of JS on every page so that you can use it “at some point” on some page on the site. Unnecessary load times, for all other pages.

RequireJS happiness ensued.

The main.js config file:

requirejs.config({
  paths: {
        // vendor
        'masonry': 'vendor/masonry.pkgd.min',

        // custom
'jquery': 'modules/jquery-global',
        'community': 'modules/community'
  }
});

require([
  'jquery',
  ], function ($) {
  'use strict';

   // DOM ready
  $(function() {

        // js loaded only on community page
        if ($('body').hasClass('page-community')) {
        require(['community']);
        }

  }); // DOM ready
});

We’re telling require where to find the libraries and specific module files, that has the code we need. Then when DOM has loaded, we check to see if we’re on a specific page, if so, load up the required JS. The ‘community’ page is where the masonry plugin is required. So, let's look at that file (community.js).

/**
 * Community
 * @requires jquery, masonry
 */
define([
  'jquery',
  'masonry'
], function ($, masonry) {
  'use strict';

  /**
   * object constructor
   */
  var Community = function() {
        this.init();
  };

  /**
   * init community module
   */
  Community.prototype.init = function() {
        var self = this;

        // init masonry
        $( '.view-community .view-content' ).masonry( { itemSelector: '.views-row' } );

  /**
   * DOM ready
   */
  $(function () {
        var community = new Community();
  });
});

So now we have the masonry jQuery plugin only loading up on the community page. By inspecting the output of that view on the page, I was able to figure out which elements to target for masonry to know which is which regarding content. The ‘.view-row’ elements were each ‘element’ of content, while the “.view-community .view-content” was the parent.

That just gets the all the JS working, but will most likely still look like poo (technical monkey term). -- Time to start slinging that poo around until we have something nice to look at. Yes, we can actually polish a turd.

Step 3 - CSS(SCSS) Kung-Poo

.view-community {
  max-width: 100%;
  margin: 0 auto;
  .view-content {
        width: 100%;
        overflow: hidden;
        .views-row {
        width: 48%;
        margin: 0 1%;
        margin-bottom: rem-calc(20);
        overflow: hidden;
        border-radius: 15px;
        background: $white;
        font-size: rem-calc(12);
        line-height: rem-calc(18);
        @media #{$medium-up} {
        font-size: rem-calc(16);
        line-height: rem-calc(26);
        }
        @media #{$small-portrait-up} {
        margin: 0 1%;
        margin-bottom: rem-calc(20);
        width: 48%;
        }
        @media #{$medium-up} {
        margin: 0 1%;
        margin-bottom: rem-calc(20);
        width: 31%;
        }
        @media #{$large-up} {
        margin: 0 1%;
        margin-bottom: rem-calc(20);
        width: 23%;
        }

Okay, now we have something decent to look at.

  • So for mobile views, the elements take up 48% of the horizontal screen space, effectively having two elements per ‘row’.
  • Moving up from that, we just increase the font-size.
  • Then up from that, (a tablet layout), we have effectively 3 per row, and the for desktop we have 4 per row.
  • So this is much cleaner, leaner than having to fiddle with the views masonry plugin. It allows us to have much more control over the plugin itself, and the CSS.

Sometimes, it pays to just go back to doing things manually, especially if you want more control.

Jun 28 2016
Jun 28
We loved Drupal Developer Days! slashrsm Tue, 28.06.2016 - 16:27

Last week part of the MD Systems team attended Drupal Developer Days in Milan.

Italian style dinner at Navigli in Milano. #drupaldevdays pic.twitter.com/CQOpIpmSGg

— Dragan Eror (@draganeror) June 23, 2016

I'd like to invite you to check our blog post to see how we liked it.

Jun 28 2016
gl
Jun 28

The Node.js integration Drupal module offers an API that allows developers to add real-time push notification functionality to their modules. Real-time communication could enable features like chat, pop-up notifications, or real-time content update. Chatroom is a great example of how a module can leverage Node.js. 

What does Node.js integration do?

When a visitor opens a page on which the Node.js module is enabled, the client-side JavaScript opens a socket connection between the visitor's browser and the Node.js server. The Node.js server runs the drupal-nodejs application that communicates with Drupal and passes data back and forth between the visitor and Drupal. This connection remains open as long as the visitor is on the page. This allows Drupal to push data to the visitor's browser in real-time so that the visitor doesn't need to refresh the page, and neither does the browser need to continually poll data using AJAX requests. 

Developers can leverage the Node.js Drupal module to push messages to the client side from their module (such as when content is updated), and write client-side JavaScript that responds to those messages (such as by updating the displayed content). In most cases, this fulfills all the real-time messaging needs. In more advanced use-cases, you may need to add custom logic on the Node.js server, such as when the socket connection is opened or the client is authenticated. This is the point where you will need to write an extension to the drupal-nodejs server application.

Writing an extension

An extension is a standard Node.js module, written in JavaScript, that lives in the /extensions subdirectory of the server application. Start by creating an empty JavaScript file in that directory. If your extension will consist of multiple files, or need other Node.js packages, you can create a directory instead, and place your files inside it. 

The drupal-nodejs application borrows the notion of hooks from Drupal, so your extension will need to implement certain hooks to modify the behavior of the server application. As is standard with Node.js modules, your custom functions will need to be exposed via the module.exports property. To be exact, hooks are methods on the object exported by your extension. The following hook methods are available:

  • alterRoutes(routes): Allows you to override route handlers defined by the application. The routes parameter is an object defined in /lib/routes.js. See that file to find out what handlers you can override. 
  • alterSettings(settings): Allows you to modify the settings loaded from the configuration file. The settings parameter corresponds to the settings defined in the nodejs.config.js file.
  • setup(clientManager): Invoked when the application starts so that your extension has a chance to initialize itself. Via the clientManager, you will have access to all the internal data that the application maintains, such as socket connections and channels. See /lib/client-manager.js for details.

To implement one of the hooks, attach a method with the same name to the object your module exports. For example:

// myextension.js

var myExtension = {};

myExtension.alterRoutes = function (routes) {
  // Modify built-in route handlers here...
};

module.exports = myExtension;

You can define your own routes by defining a .routes property on the exported object. This property needs to be an array of objects, each of which should contain the following properties:

  • path: The path that the route will handle.
  • type: The type of the request. May be "get" or "post".
  • handler: The callback function to call when this route is requested.
  • auth: Specifies whether the service key should be validated before requests to this path are served. The service key authentication depends on the path, so if this value is true, a prefix will be added to your path. E.g. the path /mypath will become /nodejs/mypath.

Custom routes could be used to add brand new functionality to the Node.js server, such as retrieving data that is not currently exposed. You would use these routes when making requests from Drupal to the Node.js server. The following is an example route definition.

// myextension.js

var myExtension = {};

myExtension.myRouteHandler = function (req, res) {
  // Handle request, and send response. 
  // res.send({text: 'Hello world.'});
};

myExtension.routes = [
  {
    path: '/mypath',
    type: 'get',
    auth: false,
    handler: myExtension.myRouteHandler
  }
];

module.exports = myExtension;

When the route above is defined, requests to the path /mypath will be routed to the myRouteHandler() method. Route handlers should follow Express standards. That is, they will receive the request and the response object, and they are supposed to send a response. The response should be a JSON object.

In addition to hooks and custom routes, the extension can listen to events that the application dispatches on certain occasions. These events are dispatched on the global process object, which is a built-in Node.js variable. The following is a list of events that the application dispatches. Shown in parentheses are the parameters that each event listener will receive.

  • client-connection(socketId): Dispatched when a new client socket connects to the server.
  • client-authenticated(sessionId, authData): Dispatched after the connecting client has been authenticated via Drupal.
  • client-to-client-message(socketId, message): Dispatched when a client socket sends a messages to another client.
  • client-to-channel-message(socketId, message): Dispatched when a client socket sends a messages to a channel.
  • client-disconnect(socketId): Dispatched when a client socket disconnects.
  • message-published(message, sentCount): Dispatched when a messages is published by Drupal to one or more connected client sockets.

To react to these events, attach a listener to the process object in the setup hook:

// myextension.js

var myExtension = {};

myExtension.setup = function (clientManager) {
  process.on('client-authenticated', function (sessionId, authData) {
    // React to authentication...
  });
};

module.exports = myExtension;

Finally, in order for your extension to be loaded, it will need to be listed in the extensions property in your nodejs.config.js file.

// nodejs.config.js

settings = {
  // ...
  extensions: ['myextension.js'],
  // ...
}

I hope this post will help popularize the Node.js integration module amongst developers. I would love to see more modules that rely on Node.js pop up. If you need assistance or have any suggestions, feel free to open an issue on GitHub (for the server application) or on drupal.org (for the Drupal module). 

Jun 28 2016
Jun 28

Last week, Sebastian and I attended Drupal Developer Days in Milan. An international group of 400 people gathered for a full-week conference in Italy to work and talk about Drupal 8.

The local team put up an outstanding conference, featuring a complete program with a week of sprints, high-quality talks and a lot more to like.

Sprinters

We could only attend from Thursday to Sunday, but the event already started Tuesday with 100 sprinters working on initiatives to move Drupal 8 and its contributed modules forward.

Drupal Dev Days Milano - Sprinters

A look at the sprint planning sheet highlights the variety of topics that different sprinters have been working on.

The UX sprint was probably the biggest one with Gábor Hojtsy, Peter Droogmans (attiks) and Bojhan attending. I was especially excited to see ifrik and Rachel Lawson (rachel_norfolk) work on improving the organization of the Drupal admin UI. See their plan issue “Restructure the Admin interface” for further details on that.

Drupal Dev Days Milano - UX

A lot has been improved related to the UX process of Drupal. You can find a good read here, follow the DrupalUX twitter account and get more info on the initiative page.  

The multilingual initiative has been sprinting as well. Check out the great #d8mi initiative page to find out more. Gábor Hojtsi even presented his experiences with the initiative at the WordCamp Europe in Vienna, the same weekend.

Related to the media initiative, Christian Fritsch from the Thunder core team has been sprinting together with people like Janez Urevc. Check out the initiative page or follow via twitter for more info.

The Search API sprints were packed again. Thomas Seidl, Markus Kalkbrenner, Joris Vercammen, Mattias Michaux and Christian Spitzlay amongst others have been working on issues for Search API, Facets, Search API Solr and Search API Solr Multilingual.

A lot more had been sprinted on during the week, almost impossible to give a precise overview. Some examples are Drupal Commerce 2 with Bojan Živanovi?, GraphQL with Sebastian Siemssen, Paragraphs with Miro Dietiker. As part of the #d8rules initiative, yanniboi and various others helped out with issues and we will announce our next initiative meeting soon via the #d8rules twitter account.

Sprints are really the key element that allow for collaboration between so many great minds. Its great to see more and more camps taking in sprints as part of their program and having Drupal Developer days as the leading format in that area.

Keynotes

There was a great variety in keynote topics. We built it, now what good is it? by Jeffrey A. McGuire, Evangelist at Acquia gave a deep dive into the new features of Drupal 8 and what they mean to our customers. Making a Drupal shaped dent in the universe by Bojan Živanovi?, Development Lead at Commerce Guys is a talk to show how cross-community has developed over the recent years. With Drupal getting off the island, Commerce 2 for example is taking a very forward-thinking approach by developing features not as Drupal modules but small, interoperable PHP libraries first.

Drupal Dev Days Milano - Keynote

On Friday, Data Triangulation: Moving beyond Qual and Quant by Razan Sadeq, User Researcher at Spotify brought in the perspective of an expert working for a big product. Razan was able to show by real world examples from her work at Spotify how UX can be driven by data successfully.

Following up, there was Transforming the experience: pixel by pixel by Alessia Rullo, Software solutions user experience lead at Hewlett Packard. In her keynote, Alessia talks about aesthetic considerations with regards to web design and UX.

Drupal Dev Days Milano - Attendees

Saturday’s keynote was Automating Access to Development by Jessica Rose, Developer Relations at DreamFactory Software. Jessica brought together a variety of interesting topics such as diversity and automation.

Sessions

Check out the program to find a list of outstanding sessions being presented during the “talk days” of the conference from Thursday to Saturday.

Sebastian’s talk Decoupling Drupal with GraphQL & Relay was packed as usual and gave a great opportunity to share the details about how we build a decoupled architecture based on GraphQL and Relay that talks to Drupal as a datasource. The slides are up already.

Drupal Dev Days Milano - GraphQL

I was excited to be able to talk about our experience at Amazee of using Scrum for project management. SOS - We need a Scrum process! Going from specification to collaboration is a walk through of how we managed the whole process of introducing the process and was a great opportunity to share hands-on experience of the learnings we had so far. You can find the slides here.

Are Geeks from Mars and Geekettes from Venus? - I was glad to be invited for a panel discussion on gender & diversity in tech led by Alessandra Petromilli. Together with Razan Sadeq, Kristof Van Tomme, Alessia Rullo and Jessica Rose we had inspiring discussions around the topic.
 

Conference

Besides the great experience of  sprinting & watching sessions, conferences are mainly about connecting with others from the community. The Drupal Dev Days team has made great effort to make sure all the required facilities to make this happen were provided. I’d like to especially highlight the quality of food. Good catering with healthy options makes sure that attendees don’t dehydrate and get the vitamins required to stay energetic over days and avoid the Drupal Flu.

Drupal Dev Days Milano - Food

The social program featured a Night at the museum @ Leonardo3, Galleria Vittorio Emanuele II with inspiring looks at all the impressive work that Leonardo Da Vinci did. Also many thanks to the Italian community for inviting everyone on Thursday evening for the official social event at a great bar in Milano!

Drupal Dev Days Milano - Museum

I was really excited to see #TourDeDrupal bringing together a motivated group of 8 cyclers. We rode over 50km along the Martesana canal and back into the city. On Sunday, Riccardo Bessone and I had the pleasure of cycling along Lago de Como and experiencing true retro cycling up to Madonna del Ghisallo.

Drupal Dev Days Milano - Tour de Drupal

Volunteers & Sponsors

It was especially great to see this size of event to be realized in Italy. In 2011 I had first met Claudio Beatrice (omissis) at DrupalCamp in Brixen/Bressanone with less than 50 attendees. The Italian community has organized a couple of camps over the last years and now, with Drupal Dev Days, they could really show that an international camp with 400 people can happen really well in Italy.

Drupal Dev Days Milano - Crowd

A successful Drupal event wouldn’t be possible without a lot of effort being put into the event. Having organized a DrupalCamp myself, I know how much of your free time you need to sacrifice to make it happen. A big thank you to Claudio (omissis), Marco (mavimo), Riccardo (bessone).

Here’s the full list of volunteers: Alessandra Petromilli, Alessandro Sibona, Andrea Pescetti, Antje Lorch, Chandeep Khosa, Chiara Carminati, Claudio Beatrice, Edouard Cunibil, Fabiano Sant'ana, Guillaume Bec, Julien Dubois, Kester Edmonds, Luca Lusso, Marcello Testi, Marco Moscaritolo, Paolo Libanore, Pierluigi Marciano, Riccardo Bessone, Simone Lombardi, Tamer Zoubi, Yan Loetzer, Yi Yuan, Zsófi Major.

Drupal Dev Days Milano - Sponsors

Also many thanks to all the sponsors.

Upcoming events

Which events are coming up after dev days? Here’s my short list:

Where are the next Drupal Dev Days going to be? Get in touch via the twitter account, they'll soon announce how new locations can sign up for the next year.

If you are interested in organizing a similar event, you might also be interested in checking the following presentation: Drupal Camp Organization: The Good Parts by Zsófi Major. Her slides are up already.

Drupal Dev Days Milano - Zsofi

Thanks again to all the volunteers of Drupal Dev Days Milan. Amazee Labs was glad to be a sprint sponsor. More pictures can be found on our flickr album. See you again soon!

Drupal Dev Days Milano - Milano

Jun 28 2016
Jun 28

As usual, Tuesday is the day to update you on the progress of Google Summer of Code 2016 project - Mailhandler.

Last week both mentors and students had to fill Google Summer of Code midterm evaluation. The evaluation happened after 5 weeks of work and consisted of questions about the chosen organization, program, mentors (for students) and students (for mentors).

I am happy to announce that I have passed the midterm evaluation. Yay! I would like to give thanks to my mentors Primož and Miro. They were supporting me with reviews, ideas and suggestions in the past weeks. I hope we will continue the great cooperation in the second phase of the project as well. Here is the review I received from my mentors:

Miloš is very diligent and capable of self organising. There were no instances where we needed to remind him of his obligations or upcoming milestones. This goes equally for the technical as for the non-technical side of the project. He is always prepared to investigate the subject very carefully and find the best solutions to his knowledge. As a result his code never feels sloppy or produced just for the sake to make progress. He genuinely cares about the project. Being very goal oriented he sometimes neglects the discussion part slightly. This could be improved by requesting more feedback before jumping to implementation.

This week, GSoC students will continue the coding until the final evaluation which is scheduled for the second part of August 2016.

Back to the project updates. The last meeting with my mentors was very productive. We were talking about the weekly goal and had the broader discussion about the second phase of the project.

More specifically, we discussed the possibility to introduce the user context as a core feature of Inmail. I was writing about Inmail’s concept of plugins (analyzers, deliverers, handlers). Each analyzer has an option to analyze the mail message that is being processed and update the properties of a shared result object. This would allow collaboration between Inmail analyzers. To discuss different approaches, I created an issue on this topic. For now, the properties are updated on MailhandlerAnalyzerResult object.

Based on the discussion with mentors, we decided to split huge MailhandlerAnalyzer into several smaller analyzers. A pull request with the implementation can be followed on Github. The following analyzers were created (sorted by defaults execution order):

  • PGP (Pretty Good Privacy) analyzer analyzes the PGP-signed email messages, verifies the signature, parses the mail body and sets the sender. Although there is specific BodyAnalyzer, for signed messages we have to parse the mail body to extract the signed text and PGP signature.

  • Entity type analyzer - we have a concept of detecting an entity type and bundle information for the mail subject. For now, we only support: [node][{node_type}]. Later on, we will extend it to support comments entities too. The purpose of this analyzer is to recognize [{entity_type}][{bundle}] pattern, extracts the metadata information, do the validation and update the subject - without metadata.

  • Sender analyzer uses a well-known feature of Mailhandler for Drupal 7. It extracts the mail address from From mail header field and finds the corresponding user. It is worth to mention that user is only set in case the user context is not already populated (by some other analyzer). This prevents us from changing the user context when it is set by PGPAnalyzer, for instance. Also, since this method is not entirely safe - From mail address can be faked by a malicious user, this analyzer is disabled by default.

  • Footer analyzer detects the mail footer/signature in a mail body and updates footer and body properties. Two most used footer separators are supported. This analyzer was described in the previous blog post.

  • Body analyzer works with the actual mail body. It has pretty limited functionality. It removes the white spaces before and after the body string using PHP’s standard method trim(). Also, in case processed body is not received as HTML, it replaces new lines \r\n with <br /> HTML tag. As the analyzer was implemented as a plugin, it can be easily extended.

MailhandlerNode is becoming much “cleaner”. Our algorithm has 3 steps:

  1. Get MailhandlerAnalyzerResult which contains the result of all Mailhandler analyzers

  2. Authenticate and authorize a user

  3. Create a node.

The original complexity from one analyzer is now shared between 5 independent Inmail analyzers. This architectural simplification was made thanks to the great Drupal 8 plugin API. If you are more interested in exploring this topic, Drupalize.me published a great article about Drupal 8 plugin system.

Next week, I am going to work on extending the test coverage for the module. The plan is to create one kernel test per each created analyzer. The existing MailhandlerNodeTest will serve as a general test of all Mailhandler analyzers and MailhandlerNode handler. Also, I will provide additional test coverage of the Mailhandler’s user interface.

Jun 27 2016
Jun 27

We already know that Drupal is more than just PHP. Now that the community has embraced the "proudly found elsewhere" mantra with the adoption of software projects outside the Drupal ecosystem, we're looking even further beyond. We want to hear about all the interesting ideas and projects you've been working on at the fringes of Drupal. We're not only interested in technical solutions, but also thoughts around what we can learn as a community from all the other people out there building things on the Internet.

There's an often used analogy about Drupal being like pieces of lego, where sites can be clicked together using community contributed modules and custom code. We invite you to zoom out further and explore how Drupal interacts as part of a larger set of systems that are powering large sites and solving complex problems. In the Horizons track, we are looking for sessions that don't necessarily fit into the traditional tracks, as well as those which potentially span across several.

One Piece Of The Puzzle

Have you or your team been working with technologies other than Drupal or even PHP? What challenges and successes have you had from integrating them with our favourite CMS? Interesting ways to get data in and out of Drupal, progressive and fully decoupled sites, working in a cross-disciplined environment — we want to hear about it!

Content Publishing

Drupal has some of the most powerful content modelling tools out there, but how does that fit into a world where we now have an uncountable number of devices and channels to publish to, whilst keeping the content authoring experience sane? How does this impact on other important areas of managing content, such as accessibility and portability?

Hello, world!

There's a whole Internet of smart people out there building software, and we're very interested in what we can learn from complementary, or even competing, platforms. We want to hear perspectives on how Drupal fits into the wide world of software, as well as how we manage ourselves as a community of developers, designers, businesses, managers and beyond.

I've Got An Idea, Hold My Beer

Something weird, wonderful, or seemingly off the wall that we haven't covered here? This is definitely the track for you!

So head over to the Horizons track description and get submitting. You have until 6th July at 23:59 (UTC +1) to get your proposals in. We can't wait to see what you come up with!

Propose your Session

-------
Sally Young
Horizons Track Chair
DrupalCon Dublin
 

Jun 27 2016
Jun 27

Follow up post, to catch up read the first post

This time I went to Drupal Dev Days in Milan to work some more on the new Field UI proposal. @Bojhan a UX specialist suggested to use images/tiles to make it easier to use, he started working on designing some images, while I adapted the code.

While changing the code @DaveReid found a solution for Allow plugins to declare field type dependencies, which got committed, got reverted and got committed in an adapted form, the problem was that we needed to be able to add a dependency on more than only a module.

We finally figured out all coding details and most of the images/icons are already done, so the new interface looks like this

Dream Fields UI

How can other modules provide a tile

Since it's plugin based contrib modules that provide a field can easily provide their own tile, as an example we'll use the address module

Add a file src/Plugin/DreamField/DreamFieldAddress.php with the following code

<?php
/**
 * @file
 * Add an address.
 */

namespace Drupal\address\Plugin\DreamField;


/**
 * Plugin implementation of 'address'.
 *
 * @DreamField(
 *   id = "address",
 *   label = @Translation("Address"),
 *   description = @Translation("This will add an input field for an address and will be outputted using the defaults."),
 *   provider = "address",
 *   preview = "images/address-dreamfields.png",
 *   field_types = {
 *     "address"
 *   },
 * )
 */
class DreamFieldAddress extends \Drupal\dream_fields\DreamFieldPluginBase {

  /**
   * [email protected]}
   */
  public function saveForm($label, $required, $values, $entityTypeId, $bundle) {
    $this->field_name = $this->createFieldMachineName($label);
    $this->widget_id = 'address_default';
    $this->entityTypeId = $entityTypeId;
    $this->bundle = $bundle;

    $this->field_storage_values = [
      'type' => 'address',
    ];

    $this->field_values = [
      'label' => $label,
      'required' => $required,
    ];

    $this->field_display_values = [
      'label' => 'above',
    ];

    $this->createFieldStorageAndField();
  }

}


Next steps

  • decide which field should be shown on this screen
  • provide a default image is a contrib module does not provide a preview image
  • decide on the wording of the description for each field

Contribute?

Have a look at the issue, the goal is to add this as an experimental module in the next release.

Jun 27 2016
Jun 27

Paragraphs has become a popular site building tool for Drupal. In the feedback to our recent blog post, some asked why the Chapter Three team has not fully embraced the module. Most of our Drupal 8 sites use Entity Construction Kit with Inline Entity Form (ECK/IEF) to achieve what others do with Paragraphs.

Slice TemplateThe Slice Template design could be created using Paragraphs or Inline Entity Form.

This post seeks to explain why one might choose one module (or set of modules) over the other for semi-structured content in Drupal 8.

We'll be using our colloquial term "slice" to refer to a paragraph-like entity created with the ECK/IEF approach.

 

Similarities

Both approaches allow for the creation of horizontal chunks of structured content that require no technical knowledge to create, and allow for flexible displays. Both work with Drupal's multilingual system. Both use Drupal's Entity API system, and are therefore fieldable. The theming experience of working with ECK and Paragraphs is similar; both return render elements and provide some template suggestions for bundles and view modes.

 

Site Builder Experience

Paragraphs
After installation, Paragraphs are immediately available to be added to nodes. If you neglect to add paragraph types, you are given a convenient link to go do so.

ECK/IEF 
The difference between a bundle and an entity can be a bit confusing the first time you use ECK/IEF.

First, set up ECK Entity types then Bundle types. Then add references to the Bundle type as a field on each Content type. Finally configure the form display on each Content type that uses Inline Entity Form. Additionally, each time you add a new Bundle type, you'll have to add it to each field that the type needs to make it available. The learning curve is small, but it exists nonetheless.

Winner: Paragraphs

 

Content Editing Experience

Paragraphs
On the form configuration page you can choose whether (1) all form items are opened completely, (2) each paragraph is accessed by accordion, or (3) users see exactly what they see on the front end. You can also choose the display of the paragraph type selector. 

ECK/IEF
While you'll have to use the Inline Entity Form Preview (IEFP) module if you want preview display, all the other form options provided by Paragraphs (and more) are available using ECK/IEF. IEFP also provides the ability to choose a configurable "Preview" view mode. While this is extra site building work, it facilitates a better content editing experience. Rich content parts can be condensed and rendered in a more "edit-mode" appropriate way. For example, images can be set to render at smaller sizes, and entity references can be shown as labels, instead of rendering directly inline, etc. This can be managed on a case by case basis.

Both 
Working with many attached entities can be a slow and downright painful experience. Drupal's TableDrag functionality allows editors to re-order content parts, but doesn't perform very well with many pieces of content. All of these modules, and Drupal in general, would benefit from an investment in improving TableDrag functionality.

Winner: Tie
Comparison of Slice vs Paragraph Content Editing ExperiencesInline Entity Form next to Paragraphs in "Preview" mode. The content editing experiences of Paragraphs and ECK/IEF can be very similar.

 

Revisions

Paragraphs
Entity Reference Revisions is a requirement for Paragraphs so it is innately revision-friendly without any extra configuration.

ECK/IEF 
Alas, there isn't any out-of-the-box support for revisions using ECK/IEF on Drupal 8 at the time of this posting. Contributors to this Drupal.org issue for Inline Entity Form, many of whom are Chapter Three employees, are working toward a solution. 

Winner: Paragraphs

Paragraphs 
Drupal's default search indexes Paragraph entities as part of their parent nodes without any extra configuration.

ECK/IEF
ECK entities are also indexed by core Drupal search. Just make sure that fields are being displayed, and users have permission to view the custom entities.

Winner: Tie

Paragraphs
This issue sums it up. If you want to reuse the same paragraph on multiple pages, you're out of luck. It's possible, though, to reference other kinds of entities inside a paragraph.

ECK/IEF 
You can easily reuse slices with the ICK/IEF set up. You can just as easily restrict that functionality from users. It's important to have strong naming conventions if your users can reuse entities. A potential drawback of the Entity system is that each entity/slice has a required title field whether you plan to display that title or reuse the content.

Winner: ECK/IEF

Paragraphs
Configuration options are limited to exactly what is expected of the module. Use the included Paragraphs Type Permissions module for more user-level control.

ECK/IEF 
With the ECK/IEF you have lots of options. You can limit which slice types are available to a field; you can change naming conventions in the UI; you can set permissions per type; you can choose whether or not the user can use existing slices; and much much more.

Additionally, ECK and IEF are useful for structured content that is not tied to a node nor should be classified as a paragraph type. In a recent project, we created Entities called "chunks" to hold things like accordion sets, newsletter links, calls-to-action, and featured content.

Winner: ECK/IEF

Paragraphs
Paragraphs are only accessible by visiting the referenced container (like the node).

ECK/IEF
Each Entity has its own url. But in most cases, there's no need for these types of entities to have one and it's best to use a module like Rabbit Hole to obscure it.

Winner: Paragraphs

Paragraphs
There are many blog posts, tutorials, and Drupal camp sessions dedicated to using the Paragraphs module as a site builder.

ECK/IEF
Beginner tutorials about ECK/IEF aren't as prevalent. If you get stuck on a custom feature, you may have to spend more time searching for answers. 

Winner: Paragraphs

 

Conclusion

The Paragraphs module is great for what it was designed. It is an easy-to-use solution to a common configuration problem. It is also the only Drupal contrib choice if you need structured content to be revisionable. Site builders without a development team, and those without the time or desire to dig in and customize the experience beyond Paragraphs' default offerings, will find it especially attractive.

Nearly the exact same functionality, however, can be achieved by using Entity Construction Kit and Inline Entity Form. While the initial set up may not be intuitive, and will take more time upfront to configure, it is also more extensible and customizable.

For smaller sites with simpler specs, Paragraphs might be all you need. If you're looking a more custom solution that can be extended in the future, Entity Construction Kit + Inline Entity Form is the way to go.

At Chapter Three, we build relationships with clients that often last for years. We know that priorities and technical specifications change. We typically choose ECK/IEF over Paragraphs either because of a particular specification in the initial build, or because we know we'll need more flexibility in the long-term. With a little more effort up-front, we deliver a first-rate content editing experience and meet the ever-changing needs of our clients.

Jacine LuisiJaesin MulenexDaniel Wehner, and Mark Feree contributed to this post.

Jun 27 2016
Jun 27

It’s often said that you can can find 80% of what you need to build a site in Drupal with a smart combination of Drupal core and the right contributed community modules.

Mastering site building in Drupal can save thousand of hours of development and coding time, reinventing a wheel that is already spinning perfectly in thousands of other websites.

However, site building is very similar to playing legos: you need to know which pieces exist, where they are, and how to make them fit. Moreover, you need to know the combinations already assembled for you that are ready to play with!

DrupalCon is the perfect situation for this! You can learn about new pieces, new combinations, and also to show and tell the world new recipes and strategies to solve and improve the most important problems that different stakeholders face when building complex sites.

In the DrupalCon Dublin Site Building track we are looking for sessions around key topics that are fundamental when creating complex and modern websites in Drupal:

  • Improving Accessibility, UX and Content Admin UI
  • Information Planning and Content Architecture, Applied Content Strategy
  • Configuration Management Best Practices, and beyond CMI core functionality
  • Layout and Theming using UI : Tools that allow you to build and control layout
  • Distros & Platforms: Come talk about the next platform you are building!
  • Recipes! There is always a recipe already baked in Drupal that can get others started easily. If you wish to showcase any of your special ways of putting modules to work the way you want, the stage is yours!

We are living in exciting times with new and improved solutions arriving with Drupal 8. We want to hear how it is working for you:

  • How are you using its new features related to Multilingual, Blocks, Context, Responsive Images, CMI, etc?
  • How did your site building experience changed with Drupal 8 from previous versions?
  • How can one resume the current state and usage of popular Site Building modules: Like Panels, Display Suite, Rules, Context, Media, Flag, Paragraphs, etc and newcomers to the Drupal scene introduced by Drupal 8?

If you are solving complex demands from content managers working in large corporate websites, adding flexibility and control to editorial backends while improving what is visible for the visitors, or simply making Drupal beat its competitors with killer and powerful ready-to-use functionalities, we want to hear from you in Dublin. Tell your story by submitting a session to the Site Building Track.

Submit your Session

-----------------------

Hernani Borges de Freitas
Site Building Track Chair
DrupalCon Dublin

Jun 27 2016
Jun 27

The Workflow Initiative was announced just over a month ago and since then I have been working on the first phases full-time. Here’s what I’ve touched:

In Drupal 8.1.x the RevisionLogInterface was introduced, but not used. In 8.2.x the Node entity will use it. Also BlockContent entity will use it.

When we make everything revisionable we’ll need all entities to get their base fields from the base class. So from 8.2.x all content entities inherit their base fields.

To help people make sensible decisions Node revisions will now be enabled by default.

We got into a pretty annoying issue when trying to add revision fields to entities which already had data because the revision field couldn’t be set to NOT NULL. Andrei wrote an awesome patch to allow an initial from field to be set. We therefore set the revision id as the entity id.

When we make everything revisionable we’ll need an upgrade path, to test this the Shortcut entity is being upgraded to revisionable by a new service. This has still not been committed, so reviews are welcome.

We’re trying to get Workbench Moderation into core as Content Moderation. Still lots to do to make this happen, but the patch is there with passing tests.

Initial work has also started to get an archive field into all entities. This will allow us to have CRAP (create, read, archive, purge) workflow, create a trash system, and replicate entity deletion through environments.

Please enable JavaScript to view the comments powered by Disqus.

blog comments powered by Disqus
Jun 27 2016
Jun 27

DDD is mostly for – surprise! – Drupal developers. This year it took place between 21 and 26 of June in Milan. People were on code sprints all week long and on Thursday, Friday and Saturday there were sessions and workshops as well.

I went to 2 sessions. The keynote of Bojan Živanovi? was about building reusable php libraries. Bojan is the architect behind Drupal Commerce 2 which is a prominent example of adopting the “leave the Drupal island” principle. They are not only advocating the usage of external solutions in Drupal but also creating libraries that are usable outside Drupal.

The session of Major Zsófi about organizing Drupal events could not have been given from a more authentic source. She shared her experience about the practical aspects of building a community and the importance of providing coffee.

All session recordings are or will be available online.

I attended three workshops. A really excellent one by Florian Loretan was about the trending search solution, elasticsearch. Pieter Frenssen had a workshop about Automated testing in Drupal 8. For me this proved to be the most valuable one since I could not keep up with the changes in this field since Drupal 7 and I need it in my contrib work. All my respects to Pieter who was able to present for 3.5 hours in a way that noone fell asleep even though we were just after lunch.

The third workshop I attended was my own 2 hours workshop about Caching in Drupal 8. I learnt a lot about this important topic during preparation and since only around one person left the room it might have been useful for the audience as well.

In the sprint room I joined the Commerce team. The team seemed to have been cursed. A laptop was stolen from the sprint site on Wednesday. Then on Thrusday night Bojan’s MacBook got also stolen from a restaurant with days of uncommitted work. In spite of this we could finish several issues in the Commerce, Commerce Migrate, Token and Address modules.

Sightseeing with drupalists

Sightseeing with drupalists

But the most important part of DDD was the social aspects. I met old friends and got to know new interesting people. Wednesday evening there was a quantitywise challenging dinner for speakers. On other nights we visited several parts of the beautiful city of Milano. Huge thanks to all the organisers, you did an amazing job! Hope to see you next year!

Jun 27 2016
Jun 27

On a recent Drupal 8 client project our client was building listing pages using views exposed filters and adding these to the menu.

This resulted in several menu URLs pointing to the same base path, but with the query arguments determining the difference.

However Drupal 8's default menu-trail calculation was resulting in the menu highlighting all instances when one of them was viewed.

Luckily the active trail calculation is done in a service and it was simple to modify the default behaviour.

Read on to see how we did it.

The problem

So the site included a view that displayed all of the different Venues the client managed, with exposed filters that allowed filtering the listing into groups.

The client used the URL generated by the filters to add different menu entries. For example there was a list of 'Community centres' in one section of the menu, linking to a pre-filtered view. In another section of the menu there was a link to 'Outdoor art spaces', also a link to a pre-filtered view.

However Drupal 8's default menu active trail calculation uses the \Drupal\Core\Menu\MenuLinkManager::loadLinksByRoute() method to calculate the active trail. As indicated by the name, this only loads matches based on the route name and parameters, but doesn't consider query arguments such as those used by Views exposed filters.

The solution

Luckily, the menu active trail calculation is handled in a service. This means we can override the definition and inject an alternate implementation or arguments.

Now there are two points we could override here, we could inject a new menu link manager definition into the menu active trail service, and change the way that loadLinksByRoute works to also consider query arguments - however the active trail service is heavily cached, and this would result in the first one to be cached and any subsequent ones to not work.

Instead we need to run our code after the values are fetched from the cache, so the logical point is to override Drupal\Core\Menu\MenuActiveTrail::getActiveTrailIds() method to filter out matches and their parents that don't match the current query arguments.

So to do this we need an implementation of \Drupal\Core\DependencyInjection\ServiceModifierInterface. Ours looks something like this:

<?php

namespace Drupal\my_module;

use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
use Symfony\Component\DependencyInjection\Reference;

class MyModuleServiceProvider implements ServiceModifierInterface {

  /**
   * [email protected]}
   */
  public function alter(ContainerBuilder $container) {
    // Get the service we want to modify.
    $definition = $container->getDefinition('menu.active_trail');
    // Inject an additional service, the request stack.
    $definition->addArgument(new Reference('request_stack'));
    // Make the active trail use our service.
    $definition->setClass(MyModuleMenuActiveTrail::class);
  }
}

For more information, see our previous blog post on overriding Drupal 8 service definitions.

Filtering on query parameters

Now we have our new active trail service, we need to filter out the links that match on route, but not on query arguments.

To do this, we need to get the query arguments from the current request. In our service alter above you'll note we injected an additional service into our active trail class, the request stack.

This allows us to get the current request and therefore the query arguments.

So first we need a constructor to handle the new argument, and a class property to store it in.

<?php

namespace Drupal\my_module;

use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\Menu\MenuActiveTrail;
use Drupal\Core\Menu\MenuLinkManagerInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Defines a class for menu active trail that considers query parameters.
 */
class MyModuleMenuActiveTrail extends MenuActiveTrail {

  /**
   * Current request stack.
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  protected $requestStack;

  /**
   * {@inheritdoc}
   */
  public function __construct(MenuLinkManagerInterface $menu_link_manager, RouteMatchInterface $route_match, CacheBackendInterface $cache, LockBackendInterface $lock, RequestStack $request_stack) {
    parent::__construct($menu_link_manager, $route_match, $cache, $lock);
    $this->requestStack = $request_stack;
  }

}

Now we have the pieces in place, we just need to add the code to filter out the links and their parents that don't match on query parameters.

/**
 * {@inheritdoc}
 */
public function getActiveTrailIds($menu_name) {
  // Get the existing trail IDs from the core implementation.
  $matching_ids = parent::getActiveTrailIds($menu_name);
  // If we don't have any query parameters, there's nothing to do here.
  if (($request = $this->requestStack->getCurrentRequest()) && $request->query->count()) {
    // Start with the top-level item.
    $new_match = ['' => ''];
    // Get all the query parameters.
    $query = $request->query->all();
    // Get the route name.
    $route_name = $this->routeMatch->getRouteName();
    if ($route_name) {
      $route_parameters = $this->routeMatch->getRawParameters()->all();

      // Load all links matching this route in this menu.
      $links = $this->menuLinkManager->loadLinksByRoute($route_name, $route_parameters, $menu_name);
      // Loop through them.
      foreach ($links as $active_link) {
        $match_options = $active_link->getOptions();
        if (!isset($match_options['query'])) {
          // This link has no query parameters, so cannot match, ignore it.
          continue;
        }
        if ($match_options['query'] == $query) {
          // This one matches - so we add its parent trail to our new match.
          if ($parents = $this->menuLinkManager->getParentIds($active_link->getPluginId())) {
            $new_match += $parents;
          }
        }
      }
    }
    // Replace the existing trail with the new trail.
    $matching_ids = $new_match;
  }
  return $matching_ids;
}

Wrapping up

Drupal 8's service based architecture gives us new levels of flexibility, personally I'm really enjoying building client projects with Drupal 8. I hope you are too.

Drupal 8 Menu active trail Views Request Stack Service Modifier
Jun 26 2016
Jun 26
Most Popular Drupal University Websites in the Middle East Most Popular Drupal University Websites

There are several interesting rankings of top government sites built with Drupal. However, Drupal is good not only for Ministries and NGOs - it is also a great choice for schools and universities. Harvard, Yale, MIT and many other of the most prominent schools worldwide choose Drupal as a CMS for their sites because of its scalability, flexibility and security.

Complete list of Drupal advantages

But what about the Middle East? Do Arab universities and schools realize the benefits that Drupal can give them or do they still use cheaper solutions? Only a deep dive into the knowledge pool of various universities’ websites can help us reach a conclusion. Thus, we made a detailed study into the same and prepared the list of 10 most popular Arabic educational Drupal websites according to Alexa global rank.

Being formatted in ascending order, the list contains the basic introduction about each university, its Drupal version, Alexa global rank and the general features of its website witnessed by a common visitor. Here are the top 10 universities located in Middle East.

10. Princess Sumaya University For Technology

 Princess Sumaya University For Technology

Alexa Global Rank: 293,597

Drupal Version:  7.3x

 

Founded by the Royal Scientific Society in 1991, Princess Sumaya University for Technology is actually the most prominent Applied Research Center situated in Jordan. It is a non-governmental and non-profit university that offers Bachelor & Master programs in all the engineering disciplines. Apart from this, the university offers higher education programs in Business Management as well.

Princess Sumaya University for Technology consists of four schools; each school delivers quality education in its specialized discipline. This means Computer Science, Engineering, Business Management, and Research each have their own specialized school at the university.

The university website is a unique blend of creativity and technical capabilities. The design itself displays an excellent thought process utilized in its development. The usability, user experience and easy navigation are the features this website contains. The high definition pictures of the university kept in homepage slide add a feather to the cap of this user-friendly website.

A homepage in 5.97 MB size takes only 4 seconds to load shows its feature of speed friendly website. Rather than filling the homepage with so many elements, the most prominent features such as e-services, e-learning, media, video gallery, sitemap etc. have been given a highlighted space. All other informative links have their perfect position in the header and footer.

9. German Jordanian University

 German Jordanian University

Alexa Global Rank: 276,566

Drupal Version:  7.3x

 

German Jordanian University, founded in 2005 in Mushaqqar, Jordan comes on 9th position among top 10 Universities in Middle East. The university was established with a motto of enhancing knowledge transfer between Jordan and Germany by blending together their best educational models.

Currently, the university is offering 20 undergraduate and graduate programs to approximately 5000 students in which female students are almost the half. The university has its own specific curriculum different from all the other Jordanian universities, because it has been developed in relevance to the German Applied Sciences model.      

Just like its unique curriculum and rich education methodologies, the Website of the German Jordanian University is also a unique one in its thought process. The best designed and the easiest usability makes it better than all the previous options. The homepage slide containing the real pictures of university students and campus displays everything you want to know about the university. The color theme, graphics and other technical elements are excellently utilized and thus, make it a user-friendly website.

The Homepage is 4.1 MB, but still takes only 3.34 seconds to load. Both the header and footer contain links that directly navigate you to the information you are looking for. Thus, the usability, user experience, and speed are better than your expectations. See the announcements slide below the university pictures. You are kept updated with all the latest announcements on the Homepage itself.

8. University of Bisha

 University of Bisha

Alexa Global Rank: 202,495

Drupal Version:  7.4x

 

The eighth position among top 10 universities in Middle East has proudly been secured by University of Bisha located in Saudi Arabia. Founded only a couple of years ago the university has achieved a worldwide recognition by offering quality higher education. Certain features such as quality education, modern infrastructure, students’ friendly campus especially for girls and latest educational & technical amenities are responsible for giving the best learning experience to students, here, at University of Bisha.

‘Simplicity dipped into soberness’ is the easiest phrase to describe its website in short. The homepage itself exhibits the uniqueness of thought process, utilized while developing the website. The very first positivity that hits a visitor is its multilingual accessibility. The website is accessible both in Arabic and English language making it easy for non-Arabic visitors to find the information they need.

Apart from this, the header is designed with a feature of easy navigation, especially for the students and faculty. Here the students and employees are given an easy navigation to the links they need as the information in these links each have its specific page. And in the footer every link has been individualized with a specific logo.  

When we look into the technical features of the website, we find it perfect here also. The homepage is made of 7.8 MB size that takes only 6.50 seconds to load making a speed-friendly. In a nutshell, the university website has all the features to recognize it as a user-friendly website.  

7. Gulf University for Science & Technology

 Gulf University for Science &amp;amp; Technology

Alexa Global Rank: 155,830

Drupal Version:  7

 

Founded in 2002, Gulf University of Science & Technology (GUST) commonly known as Gulf University is a private university located in West Mishref, Kuwait. It seems really surprising that a young University that celebrated its first commencement ceremony in June 2007 stands on the 7th position among the top 10 universities in Middle East.

Currently, Gulf University has been inculcating capable professionals in various technical and professional disciplines. Approximately 145 well-known academic faculty members from 31 different countries have been saturating their meticulous knowledge and skills to thousands of students.

The blue and white color combination of the website makes it catchy and attractive. The website has been developed in relevance to the usability and user experience. Though the heavy homepage of 2.4 MB slows down its speed as it takes 7.61 Seconds to load yet the easy navigation and smooth functioning makes a visitor forget the speed issue. And also, the website is available in English version only, it sometimes creates language problem for Arabic native speakers.

Simple but impressive exhibition of all the website elements and relevant links makes it a user friendly website. There is no hustle-bustle of content, sections, or links on the homepage. You will find only the required information on it. Thus, it can be called a cutting edge website that has the capacity to grab good reviews from the visitors.

6. Prince Sattam Bin Abdulaziz University

 Prince Sattam Bin Abdulaziz University

Alexa Global Rank: 38,831

Drupal Version:  8

 

Among top 10 universities in the Middle East, Prince Sattam Bin Abdulaziz University owns the proud position of being on the sixth rank. Formerly known as Prince Salman Bin Abdulaziz University or the University of Al-Kharj, Prince Sattam Bin Abdulaziz University was established in 2007 in the city of Al-Kharj, Saudi Arabia.

The current name of the university was adopted in the beginning of 2015. Currently, the university is delivering higher education to approx 30,000 students in 80 different programs. It is only the quality education that has brought various national and international accreditations for different programs.

The university has an excellently designed website that is built with the latest Drupal 8. It greatly speaks about the university, its features, academic programs, and guidelines for a new visitor. The header in the website contains everything in a nutshell. Whatever information is required related to administration, courses, jobs, research programs, and more, the header will provide a direct link to the same. Thus, the website features an easy navigation for a visitor.

Main reasons to migrate to Drupal 8

The homepage that acquires a size of 1.1 MB takes 4.2 seconds to load. It designates the website to be speed-friendly. The social media platforms of the university have been given a place at the right top. All the other useful links have been placed in the footer. The website, thus, provides a user-friendly experience as well. So, the overall experience of the website is very positive.

5. Majmaah University

 Majmaah University

Alexa Global Rank: 37,501

Drupal Version:  7.4x

 

Founded in 2009 in Al Majma'ah region, Majmaah University can be regarded as one of the youngest universities located in Saudi Arabia. Having a total number of 13 academic schools, the university has been established with a motto of expanding higher education around the region and providing quality education to the growing number of young graduates in the Middle East.

It is one of the only perfect utilization of educational resources and the unified efforts of management, faculty and students established just within 7 years; Majmaah University stands tall on the fifth rank among top 10 universities in the Middle East with Drupal website. Currently, the university offers diploma, bachelor, masters, and research programs in various disciplines.

The university website has also played a major role in bringing the university to its heights. The Website of Majmaah University is an outcome of rich creativity and professional capabilities. The beautiful layout of the website, the extraordinary color combination, and unique design concept is really a treat to the eyes when visited for the first time. The high definition picture on the homepage showing students from various streams brings an artistic touch.

In technical terms, the website is capable enough to provide an excellent experience to its users. A size of 1.5 MB takes only 1.28 seconds for the homepage to load. The header has all the sections and subsections with links that take the visitor directly on the page he/she wants. So the navigation feature of the website is just as a user likes. Thus, the website contains all the features of being speed-friendly and user-friendly.

4. King Khalid University

 King Khalid University

Alexa Global Rank: 30,282

Drupal Version:  7.4x

 

Being established in 1998 in Aseer region, KKU has evolved into a premier institution in Saudi Arabia just within a short span of time. The various factors such as modern infrastructure, latest educational amenities, a wide gamut of undergraduate, graduate and postgraduate programs, a large number of disciplines, meticulous faculty and much more have elevated the reputation of the university throughout the Middle East.

Recently, King Khalid University (KKU) has secured the 604 rank among top 700 universities in the world and also achieved a prominent position among the best universities in the Middle East. Inculcated from the merger of two schools, King Khalid University also enjoys the designation of the biggest academic institution saturating quality higher education to approx 72000 students.

The university website exhibits really a different design and thought process. The whole website designed on a white background looks so beautiful in the first look. The pictures have been utilized on the website just in accordance to the theme of the page.

The website’s homepage having a size of 3.0 Mb is overfilled with the informative links yet it only takes 5.36 seconds to load. And also, the visitors find it easy to operate due to its well designed header & footer. Thus, the website is sure to get good reviews from the visitors in relevance to the user experience.  

3. The University of Dammam

 The University of Dammam

Alexa Global Rank: 26,233

Drupal Version:  7

 

The third rank among the top ten Middle East universities goes to the University of Dammam located at Dammam, Saudi Arabia. The university that was established in 1975 with two colleges – College of Medicine and College of Architecture has now expanded into 21 colleges in the Eastern province. From graduate to research programs, the University of Dammam is providing quality education to approx 45000 students. Currently, the University has been offering a broad spectrum of bachelor, masters, and research courses in Medicine, Engineering, Science and Management and Arts disciplines.

The university website has been developed and maintained meticulously. The very first advantage of the website is its rich content framework. Every section, every landing page contains a rich informative content. Secondly, the color combination of the website is really fantastic. The beautiful combination of blue, white and cream colors make it look more beautiful. And the multicolored main menu on homepage looks like a rainbow on a white sky. Thirdly, each page link is available on the homepage that makes the website navigation an easy task. The header and the footer have all the required links that make it easy to navigate to the required page.

The website homepage takes only 3.20 seconds to load due to its speed-friendly size of 585.6 KB. Therefore,, the website is not only easy to operate but provides a speedy navigation as well. Thus, the website provides a better user end experience.

2. The American University in Cairo

 The American University in Cairo

Alexa Global Rank: 22,309

Drupal Version:  7.4x

 

Being established in Egypt in 1919, The American University in Cairo was founded by Charles A. Watson. Though AUC was the first English-University in the Middle East, yet it was established with a motto of contributing to the intellectual, social and cultural growth of the Arab World. In the beginning, it was both a preparatory school and a university with only men allowed to get admission.

Since its inception, AUC went through various changes and advancements that shaped it into the 2nd most famous university in the Middle East. Currently, AUC is spread in 260 acres having 25 departments and institutes, and offering approximately 36 undergraduate, 44 masters, and two research programs.

When it comes to the AUC website, the very first thing that strikes in a visitor’s mind is that the university website is so simple and sober. A beautifully designed yet an easily accessible website that makes a visitor grab his/her required information by going directly to the specific link. Both the main menu navigation and the footer have all the required links to navigate on the specific page you require. You can also see all the social media symbols on the footer that will direct you on the social platforms of the university.

The website saturates a pleasing user end experience due to its perfect design, impressive landing pages, good speed, and easy navigation. The home page is so impressively designed that it attracts a visitor to explore more into it. The real pictures of the university add beauty to the website. And mainly the homepage that is of 1.0 MB takes only 2.11 seconds to load. Thus, in terms of speed and navigation, the website is really user-friendly.

Vardot Introduces the American University in Cairo's New Website

 

1. King Saud University

 King Saud University

Alexa global rank: 6,098

Drupal version: 7.43

 

Established in 1957, King Saud University owns the pride of being not only the first but also the most famous University in Saudi Arabia. In 1953, Abdulaziz al Saud announced to establish the first higher education institution in Saudi Arabia to enhance the cultural and scientific knowledge in the country along with spreading Islamic faith among the coming generations. Subsequently, King Saud University was founded in Riyadh.

Today, the university has been accelerating higher education in all the streams such as Engineering, Medical Sciences, and Humanities and so on. Being a premier institution with 24 colleges, King Saud University has been ranked no. 1 in the Middle East. The greatest feature of the university is that it has separate colleges for girls just to initiate higher education among girls in a country where girls don’t enjoy much freedom in their social life.

The Website of King Saud University presents an actual display of the university itself. The very first feature of the university website is its compatibility in English language along with Arabic. It enables the visitors throughout the globe to find the information they require. Secondly, the website has been designed and executed in a way that stresses more on giving the detailed knowledge into everything rather than focusing on designs only. Thirdly, each informative topic on the website has a different page for it and is easily accessible for a visitor to find his/her relevant information.

If we talk about the user end experience, everything on the website such as design, speed, content, and information is capable enough to grab good reviews and a five-star rating from its visitors. The homepage size is only 1.3 MB that just consumes 3.50 seconds to load.  

Conclusion

As promised, we have presented a deep insight into every university’s basic information. Though all the information is just true as it is taken from reliable sources yet only the figures may differ sometimes according to the changing trends.

Although the most of these websites are relatively new, they have achieved great popularity and high rankings. On one hand their popularity depends on high academic level and number of students, but on the other hand Google doesn’t rank high websites that have problems with the code and are not SEO-optimized. The success of sites listed in this article is also achieved with their powerful CMS.

Drupal is the latest Content Management System in vogue these days. Having various versions, Drupal saturates the achievements for a website far above the expectations. And that’s the reason why most of the academic institutions or schools in the Middle East prefer Drupal distributions when building their websites.

If you have plans to build a site and achieve highest rankings, Drupal is the right fit for you. For assistance migrating to Drupal or building a modern website for your university, contact Vardot.

Jun 26 2016
JK
Jun 26

In this article, we will see how we built custom blocks in EK management tools suite with a sample basic block in a module called 'mymodule' used for demo. It can be used to display multiple content, static or dynamic as in the example above.

Create the block script

First we will create a script that will display some content within a block. the script file will be called MyBlock.php and is placed in /mymodule/src/Plugin/Block/.


/**
 * @file
 * Contains \Drupal\mymodule\Plugin\Block\MyBlock.
 */
namespace Drupal\mymodule\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Access\AccessResult;

/**
 * Provides a 'Custom module widget' .
 *
 * @Block(
 *   id = "my_block",
 *   admin_label = @Translation("My custom block"),
 *   category = @Translation("mymodule Widgets")
 * )
 */

The file header will contain the namespace of the file, the dependencies and most important, the annotations that define the block for discovery (more information about this in Drupal).

For the purpose of this demo, the content of the block will be very simple:

class MyBlock extends BlockBase {
  /**
   * Implements \Drupal\block\BlockBase::blockBuild().
   */
  public function build() {
 
  $items = array();
  $items['title'] = t('Custom block');
  $items['content'] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
          . "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. "
          . "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. "
          . "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
 
 
  return array(
    '#items' => $items,
    '#theme' => 'mymodule_block',
    '#attached' => array(
      'library' => array('mymodule/style.css'),
      ),
    );
 
  }
  /**
   * Implements \Drupal\block\BlockBase::access().
   */
  protected function blockAccess(AccountInterface $account) {
    if (!$account->isAnonymous() ) {
      return AccessResult::allowed();
    }
    return AccessResult::forbidden(); 
  }
}

We set a title and content text to be displayed in the block in the build() function. This block use a theme template called "mymodule_block" and a library with custom css style. We will not cover this part here. The blockAccess()  function control the visibility of the block and restrict it to authenticated accounts.

Display block

In order to demonstrate the display of the block, we created an empty page with tour /mymodule/block in mymodule.routing.yml, however, the block can be displayed in any page or region.

mymodule.block:
  path: '/mymodule/block'
  defaults:
    _controller: '\Drupal\mymodule\Controller\MyModuleController::BlockPage'
  requirements:
    _access: 'TRUE'

BlockPage() will just return an empty array in this sample module.

/**
 * @file
 * Contains \Drupal\mymodule\Controller\MyModuleController.
 */

namespace Drupal\mymodule\Controller;

use Drupal\Core\Controller\ControllerBase;


class MyModuleController extends ControllerBase {

    public function BlockPage() {
        return array();   
    }

}

Now we can navigate to the block layout management page of Drupal 8, /admin/structure/block, and install our custom block.

We place the block in "Content" of the page and click on the button to select the custom block we created:

We click on "Place block" for the selected block and configure the block to show on our custom page:

After saving, we can now navigate to our page /mymodule/block and see the block in action:

Block configuration file

The block can be set in yml configuration file in order to be installed with the module. In order to do that, simply go to /admin/config/development/configuration/single/export to export the block configuration that we just activated:

Copy the configuration script into a file called block.block.mycustomblock.yml and place it under /mymodule/config/install; the block will be activated at installation time.

We hope this block example is useful and feel free to add your comments or suggestion.

Jun 25 2016
Jun 25

Mastering Drupal 8 Views book cover

Gregg Marshall's Mastering Drupal 8 Views is one of the (I can only assume) many Drupal 8-focused books that will be released in the coming months. It is a very good deep dive into many of the hidden corners of the Views module, albeit with an interesting format. Not completely structured like a typical how-to software book, Gregg takes a bit more of a novel approach (pun intended) - he takes the reader on a journey through the Views module through the eyes of Lynn, a small business owner (Lynn's cat and Drupal consultant also have prominent roles). While some readers might find the story-ish elements distracting, they add a certain degree of warmth to the book - something I can only assume a subset of readers will more than appreciate.

The author does a nice job of setting the stage, identifying the intended audience for the book, and speaking directly to them (through the book's characters). There are sections of the book that may cause confusion with this structure, on several occasions I found myself reading long, multi-paragraph sections that I didn't immediately realize that a character was speaking, and not the author. It seems that the use of quotations to indicate when characters were speaking was not consistently applied.

While the technical content of the book is often well-written and clear, there are some places in the book where things seem out-of-order - none more so than the first lesson diving into the Views "settings" page - something that most people new to the subject don't need to consider until they need to modify the (very sane) default values. Another example early in the book has the author creating a new view "display" prior to a full explanation of what Views display are.

There are, however, many areas of great explanation on topics that I don't recall ever seeing in other Drupal-related books. Sections on the new "entity reference" and "REST export" display types stood out in the first few chapters, as well as some of the best explanations (and details) on the "table" format, and field rewrites (more on this in a bit).

There are several lessons that have starting points that aren't necessarily considered "best practice", including one that has the reader cloning the admin/content view as a starting point for a public facing view. In my opinion, the reader would be better served by starting a brand new view using the Views "wizard" interface. As a stickler for best practices, there were several things in the book that made me cringe a bit, including the use of the (outdated?) GMap and Location modules (instead of Geofield-related modules) and (even more so) the use of the admin area's "Install new module" functionality.

I found the discussion and lessons around contextual filters to be extremely effective. The story-ish nature of the book allowed the author to almost naturally introduce a problem that is elegantly solved with contextual filters. Along with relationships, contextual filters are often one of the major stumbling blocks in learning Views, and this book does as good a job as anything else I've read and taking the reader down in the deep, dark recesses of it ("Default value" options included!) The chapter on Views relationships is similarly structured and just as effective.

This is perhaps one of the only Drupal books I've read that purposely sends the reader (in this case, the main character as well) down a dead-end in order to introduce a new topic. I think that many readers will find this comforting, in that it allows the author to introduce a new topic in order to direct the reader to a solution.

As a big fan of display modes, combined with the fact that they are much more visible in Drupal 8, I hoped that the author would utilize them more often in the various lessons (instead of relying on adding fields to most views).

The book really shines in chapters that normally are only a small section in other Drupal resources. There is an entire chapter on field rewrites, and it is wonderful. The author takes Lynn and the reader through various examples, each exposing a new aspect of field rewrites. For anyone who doesn't dare dive into this section of Views field configuration, this chapter alone is worth the price of the book.

The chapter on all the settings in the "Advanced" fieldset is also something that the author covers extremely well. In most Views references, many of these settings are glossed over, but this book provides an almost ("aggregation" isn't covered as deeply as I hoped) complete reference to all the various available settings.

While the vast majority of the examples in the book are well structured, many of them depend on content types and other information architecture that exists on "Lynn's" site. While details of the information architecture are provided in an appendix, it would be very helpful for the author to provide them via GitHub or some other electronic mechanism to readers. Otherwise, it seems like a tedious and error-prone process for readers to recreate the information architecture on their own in order to follow the examples in the book.

The author does a nice job of walking the reader through the use of several Views-related contributed modules as well. For my taste, I think there should have been just a little more explanation about how various contributed modules fit together with Views. As an example, the fact that Views Slideshow provides a new display plugin is glossed over. I think it would serve the readers well to specifically mention that many Views related modules are simply plugins for various parts of the Views infrastructure. This would provide readers with a higher-level view of the Views ecosystem. That's a bit of a nitpick though, as this section is really, really solid.

One of the last chapters in the book covers theming views, and I think it doesn't go into enough details and/or examples. The section on adding CSS classes to various parts of a view is very useful, but the section on overriding template files feels incomplete.

Overall, this is a welcome addition to the Drupal family of books, and one that I can honestly recommend for users that feel like there are aspects of the Views module that are still a mystery to them. The novel-like structure of the book normally doesn't get in the way of the lesson, but for readers who normally doesn't read technical books front-to-back (instead cherry picking only chapters of interest), it might be a bit distracting. While this is properly identified as a Drupal 8 book, much of the content is also valid for Drupal 7, including some of (in my opinion) the strongest chapters.

Jun 25 2016
Jun 25

Drupal India Community have been talking about Pan India code sprint and with effort and cooperation of regional communities we were finally able to organise a combined sprint, we had participation from Mumbai, Jaipur, Delhi and Pune. This is an account of Pune sprint which happened at QED42 Office in Viman Nagar. We had a total attendance of 10 Drupalers out of which 2 were first time sprinters ( Congratulations Dhruvesh and Shreyal on attending your first sprint :) ).

The focus of the sprint was porting modules from D7 to D8 and trying to reach stable releases of some of the modules that were started in previous sprints. One of those modules was auto_entitylabel the issues were triaged prior to the code sprint, so we had less trouble getting around the issues & fixing them up. EOD, we were able to get a basic version of the module, which included integration with tokens.

Auto Entity Label Porting to Drupal 8

Ajit mentored Dhruvesh on autologout tasks and Dhruvesh contributed a fix to an issue in D8 version of the module & then backported it to Drupal 7 version as well.

Vishal mentoring shreyal

Sprint also included some code review work around heap_analytics module, which Nitesh  ported to Drupal 8 (https://github.com/nitesh11/heap_analytics). 

Ajit, Nitesh & Prashant sprinting

Overall, it was a productive sprint & we plan to continue the same on Last Saturday of every Month. Keep an eye on auto_entitylabel, jquery_carousel, heap_analytics if you are interested to use them in Drupal 8, couple of sprints and help from community we should be able to release stable versions of these modules :) we specifically need help on testing of these modules and reporting issues. 

Jun 25 2016
Jun 25

Creating an installation profile in Drupal 8 is quite easy according to my humble opinion. Why? Because of the Configuration Management System in Drupal 8. In Drupal 7 we had lot of amazing contributed Installation profiles like Commerce Kick Start, Open Atrium, aGov, etc. Here we are going to discuss about how to create the installation profile in Drupal 8 and the benefit of using an installation profile in our Drupal Development World. Before that let us find out the answers for the following questions….

  • What is the Usage of installation profile?

  • Why do we need to create installation profile?

  • When do we need to think about architecting an installation profile?

  • How to reduce the development hours by creating an Installation Profile or Distribution in Drupal 8?

Thank God, I was one of the fortunate to work along with my Valuebound team members for some top Media companies like Time Inc and FarmJournal Media. All of these companies have a lot of websites with similar basic features, so it makes sense to create an installation profile with the basic set of features / functionalities. Similarly, developing websites for Universities, each University will be having multiple websites for different departments and branches. By creating an installation profile or distribution for the same, with the basic set of features will ease the development and deliver the Websites on time. Why? Because it reduces more than 30% (minimum) of development time. Thunder is one of the best example of an installation profile / distribution created by the media publishing company Hubert Burda Media.

How to create installation profile in Drupal8?

There are couple of steps involved in it, which is

  1. Selecting the machine name for the installation profile.
  2. Creating the Structure.

Selecting the machine name for the installation profile.

In this step we can decide what should be the machine name for our profile. Suppose our profile name is ‘Example Profile’ and machine name for this will be ‘example_profile’. The machine name can contain only lowercase letter and underscore.

Creating the Structure.

The structure has following files.

  1. Profilename.info.yml
  2. Profilename.profile
  3. Profilename.install
  4. Config folder.
  5. Translation folder(optional).

All the above steps should be inside the ‘/profile/your_profile’ folder under your ‘Drupal root Folder’. Here our profile name is “Example Profile”, So we have to do the action under the following directory.

“Drupal_root_folder/profile/example_profile”

1) Creating the Profilename.info.yml

Here we are creating the ‘example_profile.info.yml’.

In the ‘example_profile.info.yml’, We are having the following terms.

  • name:  This the name of  your profile.
  • type: What type it is whether it is module, theme or profile. Here we having ‘profile’.
  • description: Describe about your profile / distribution.
  • distribution: (Optional) Declare your installation profile as a distribution, This will make the installer auto-select this installation profile. The distribution_name property is used in the installer and other places as a label for the software being installed.
  • dependencies: Required modules.

2) Creating profilename.profile

.profile file is very much like .module on the module. It has all the access like .module has. Here we having ‘example_profile.profile’

3) Creating profilename.install

In this file provide Install, update and uninstall functions for the profile.

4) Config folder

Config folder makes the difference from Drupal 7 to Drupal 8. Because of CMI in Drupal 8, it is very easy to add the features or function as config files under ‘config/install’ in your profile root directory. You can import the configuration from an existing site and keep it in in the ‘config/install’ folder. For an example we have created and exported the configuration for a view called “Example View For Example profile”. But we need to carefully follow the couple of steps which are mentioned below,

  • Copy all of the modules and themes listed within core.extension.yml into your profile's info file (using the new info file's format).
  • Delete core.extension.yml, file.settings.yml and update.settings.yml
  • Remove all of the UUIDs from your config files so that they don't conflict with those of new sites. Use phpstorm and  use following regular expression in the ‘Replace option under  Find in View options’. [View >> Find >> Replace]         
    “^uuid: .*\n”

Please check the following image for more clarity.

Installation Profile

Now our installation is ready to use.

The source of our example is: https://github.com/rakeshjames/example_profile

Conclusion:

If you are developing  ‘x’  number of websites having basic features / functionality / requirements which are similar, then it is always good to consider  creating an installation profile and Keep it. So that it will save at least 30% of overall development time. Which means you can use that time more effectively on your development to manifold your productivity.

Jun 24 2016
Jun 24
Your time is limited. By the time you finish this sentence, someone will visit and abandon your website. Unless you give your visitors a reason to stick around, they're gone. High bounce rate is an indicator of visitors' lack of interest.

It may be absolutely fine for a user to check out one page, especially if it's a press release or another event driven piece of content. But if your goal is to build a relationship with your visitors, one and done won't cut it.


Here are some of the most common problems in website design:

  1. There's no clear path. You want to extend a warm welcome to your visitors. Give them an easy way in and through. Too much competition for attention is a turn off. When you provide too many options, the functional result is no options.
  2. Outdated design. Your site was state of the art in 2009. It's got a header, a couple of sidebars, and a big chunk of information running down the center. Guess what? It looks like it's nearly a decade old. Because it is. Time to refresh with current design thinking. The layout of a page has evolved over the past decade. These days the best sites break up content into smaller, digestible bits.
  3. Overused stock images and icons. If visitors see the same image on multiple sites, it erodes trust. That picture of people sitting around the conference table? They sure get around to a lot of offices!
  4. Too many textures and colors. You are trying to add interest, but you just add clutter. Limit colors and fonts. Maintain a thematic color scheme. For professional sites, try to limit the variety of fonts to three or fewer.
  5. Design for the wrong reasons. Always begin by identifying your target audience and customizing design and content. You may want your site to look "modern" or like another site you've seen, but if you haven't checked in with what your audience needs and wants, you can fail miserably.
  6. Cute that doesn't cut it. When your links have adorable, witty names, the experience gets tired fast. Links that don't make much sense are not user friendly and won't ingratiate you with your visitors. Be practical and basic when naming links. Make it easy for people. Design for multiple visits. A rotating banner is cool the first time, and maybe the second, but at some point it's just a stale eyesore. Monotonous calls to action.
  7. Your site isn't optimized for mobile. You shouldn't need to be reminded of this, but numbers don't lie. Mobile is overtaking desktop. It's increasingly likely that your visitors see your site on a tiny screen. If they have to pinch and stretch to read, they'll find a better source of information. Be sure to test your site on smartphone and tablet.
  8. You play hard to get. If you want customers to find you, make sure your address, phone number and hours of operation are easily accessible on your site. Too often, that information is hidden or completely absent.
Thanks to Zivtech's UX/UI Designer Jen Rovner for co-writing this article.
Jun 24 2016
Jun 24

For those of you who know me well, you know I do not like to play around with code all that much or even use command line tools if I can avoid it. There are many reasons for this but mostly I am just not that comfortable setting up, maintaining and using these type of tools.  That being said I do like to site build in Drupal….A LOT :). 

Lately I have been creating and managing Drupal 8 sites with Pantheon and using a Git client called GitKraken to manage my version control workflow and I have to say the experience has been FANTASTIC!

With these three components I am able to:

  • Create a brand new Drupal 8 site
  • Export/Import my sites configuration
  • Have a fully version controlled workflow with dev, test and live environments
  • Generate SSH keys
  • Clone / create a local repository
  • Stage and commit changes
  • Pull & Push code to a dev environment

All without ever touching a line of code or a command line!  Want to learn more??

If you said YES then you are in the right place.

Following this intro post there will be a three part weekly series where I will walk you through my experiences with setting up a new Drupal 8 site on Pantheon, managing configuration changes with Drupal 8, and managing a Git repository with GitKraken.

This is a great set up/intro for beginners looking to work with Drupal 8 and keep their work versioned controlled (which we should all do) or for folks like myself who would just rather use a GUI as opposed to command line tools.

Jun 24 2016
Jun 24

One of the first questions I get asked when teaching a Drupal theming class is which base theme to use. The answer has always starts with the unsatisfying: "It depends". Now that I'm teaching Drupal 8 theming, we have a couple new base themes in core added to the mix: classy and stable.

You can learn the difference between the two and how to use them in this previous post.

For those without a strong preference for a base theme, starting out with Classy is a great option. You get a lot of great theming features out-of-the-box with Drupal core:

  • Normalize.css and modernizr.js in core
  • Cleaner, more accessible markup
  • HTML5 tags
  • Templates easily located in core themes
  • More consistent classes for HTML components

So skipping the contrib base theme and extending Classy is a good choice. You get some good defaults, and then you get to define in your theme:

  • Which regions you want
  • The layout (either a custom one, or by adding a pre-defined grid CSS)
  • The structure of your own CSS or SASS files
  • The extra classes you need to add to implement the design

This approach has lots of advantages:

  • Drupal 8 core is awesome
  • You get understanding, control over what’s added in your theme
  • You're adding fewer customizations that you aren't aware of
  • There's less code to maintain
  • It's easier to on-board new themers

Using a contrib theme like Bootstrap is a great option if you're working with a team that's familiar with Bootstrap, and you want to make it super easy for them to keep doing what they're doing. Or, if you need a lot of layout options and want the ease of working with a pre-existing grid system. Using the Bootstrap theme, as opposed to adding the grid CSS directly to your custom theme also allows you to take advantage of the many theme settings it provides.

Otherwise, if you're creating a new theme for Drupal 8, it's a great opportunity to give the Classy theme a try!

Here are the slides from my talk on this topic at Drupal North. You can also check out the follow-up webinar I'm doing on creating layouts for Drupal 8 on Monday, June 27th at noon.

Jun 24 2016
Jun 24

Give yourself a pat on the back for making it to the finish line of another busy work week!

Welcome back to Episode 11 of The Mediacurrent Friday 5. This week, VP of Sales Josh Linard joins host Mark Casias to discuss 5 Problems Large Enterprise Face in Their Digital Transformation. 

He covers some key issues that can arise, such as: centralizing to one platform, unnecessary licensing fees, collecting actionable data, being in a position to quickly respond to that data, and long-term budget planning.

Check out the video below to learn more!

[embedded content]

Have a topic that you think would make a great video? Feel free to send us your thoughts to [email protected] and stay tuned for Episode 12 in two weeks. Enjoy your weekend!

Additional Resources
The Best (and worst) Question in a Drupal Sales Presentation | Blog Post
Friday 5: 5 Minutes on Getting to Know Your Website | Video
Top Reasons Why Enterprise Marketers Love Drupal | eBook

Jun 24 2016
Jun 24

The oddity of this field can create problems. The summary has no format of its own, it shares a format with the body. So you can't have a simple format for the summary and a more complex one for the body. The link to expose and hide the summary on the edit form is a little non-intuitive, especially since no other field behaves this way, so it's easy to miss the fact that there is a summary field there at all. If you are relying on the truncated text for the summary, there's no easy way to see in the node form what the summary will end up looking like. You have to preview the node to tell.

I wanted to move away from using the legacy body field in favor of separate body and summary fields that behave in a more normal way, where each is a distinct field, with its own format and no unexpected behavior. I like the benefits of having two fields, with the additional granularity that provides. This article describes how I made this switch on one of my legacy sites.

Making the Switch

The first step was to add the new fields to the content types where they will be used. I just did this in the UI by going to admin > structure > types. I created two fields, one called field_description for the full body text and one called field_summary for the summary. My plan was for the summary field to be a truncated, plain text excerpt of the body that I could use in metatags and in AMP metadata, as well as on teasers. I updated the Manage Display and Manage Form Display data on each content type to display my new fields instead of the old body field on the node form and in all my view modes.

Once the new fields were created I wanted to get my old body/summary data copied over to my new fields. To do this I needed an update hook. I used Drupal.org as a guide for creating an update hook in Drupal 8.

The instructions for update hooks recommend not using normal hooks, like $node->save(), inside update hooks, and instead updating the database directly with a SQL query. But that would require understanding all the tables that need to be updated. This is much more complicated in Drupal 8 than it was in Drupal 7. In Drupal 7 each field has exactly two tables, one for the active values of the field and one with revision values. In Drupal 8 there are numerous tables that might be used, depending on whether you are using revisions and/or translations. There could be up to four tables that need to be updated for each individual field that is altered. On top of that, if I had two fields in Drupal 7 that had the same name, they were always stored in the same tables, but in Drupal 8 if I have two fields with the same name they might be in different tables, with each field stored in up to four tables for each type of entity the field exists on.

To avoid any chance of missing or misunderstanding which tables to update, I went ahead and used the $node->save() method in the update hook to ensure every table gets the right changes. That method is time-consuming and could easily time out for mass updates, so it was critical to run the updates in small batches. I then tested it to be sure the batches were small enough not to create a problem when the update ran.

The update hook ended up looking like this:


<?php
/**
 * Update new summary and description fields from body values.
 */
function custom_update_8001(&$sandbox) {

  // The content types to update.
  $bundles = ['article', 'news', 'book'];
  // The new field for the summary. Must already exist on these content types.
  $summary_field = 'field_summary';
  // The new field for the body. Must already exist on these content types.
  $body_field = 'field_description';
  // The number of nodes to update at once.
  $range = 5;

  if (!isset($sandbox['progress'])) {
    // This must be the first run. Initialize the sandbox.
    $sandbox['progress'] = 0;
    $sandbox['current_pk'] = 0;
    $sandbox['max'] = Database::getConnection()->query("SELECT COUNT(nid) FROM {node} WHERE type IN (:bundles[])", array(':bundles[]' => $bundles))->fetchField();
  }

  // Update in chunks of $range.
  $storage = Drupal::entityManager()->getStorage('node');
  $records = Database::getConnection()->select('node', 'n')
    ->fields('n', array('nid'))
    ->condition('type', $bundles, 'IN')
    ->condition('nid', $sandbox['current_pk'], '>')
    ->range(0, $range)
    ->orderBy('nid', 'ASC')
    ->execute();
  foreach ($records as $record) {
    $node = $storage->load($record->nid);

    // Get the body values if there is now a body field.
    if (isset($node->body)) {
      $body = $node->get('body')->value;
      $summary = $node->get('body')->summary;
      $format = $node->get('body')->format;

      // Copy the values to the new fields, being careful not to wipe out other values that might be there.
      if (empty($node->{$summary_field}->getValue()) && !empty($summary)) {
        $node->{$summary_field}->setValue(['value' => $summary, 'format' => $format]);
      }
      if (empty($node->{$body_field}->getValue()) && !empty($body)) {
        $node->{$body_field}->setValue(['value' => $body, 'format' => $format]);
      }

      if ($updated) {
        // Clear the body values.
        $node->body->setValue([]);
      }
    }

    // Force a node save even if there are no changes to force the pre_save hook to be executed.
    $node->save();

    $sandbox['progress']++;
    $sandbox['current_pk'] = $record->nid;
  }

  $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);

  return t('All content of the types: @bundles were updated with the new description and summary fields.', array([email protected]' => implode(', ', $bundles)));
}
?>

Creating the Summary

That update would copy the existing body data to the new fields, but many of the new summary fields would be empty. As distinct fields, they won't automatically pick up content from the body field, and will just not display at all. The update needs something more to get the summary fields populated. What I wanted was to end up with something that would work similarly to the old body field. If the summary is empty I want to populate it with a value derived from the body field. But when doing that I also want to truncate it to a reasonable length for a summary, and in my case I also wanted to be sure that I ended up with plain text, not markup, in that field.

I created a helper function in a custom module that would take text, like that which might be in the body field, and alter it appropriately to create the summaries I want. I have a lot of nodes with html data tables, and I needed to remove those tables before truncating the content to create a summary. My body fields also have a number of filters that need to do their replacements before I try creating a summary. I ended up with the following processing, which I put in a custom.module file:


<?php
use Drupal\Component\Render\PlainTextOutput;

/**
 * Clean up and trim text or markup to create a plain text summary of $limit size.
 *
 * @param string $value
 *   The text to use to create the summary.
 * @param string $limit
 *   The maximum characters for the summary, zero means unlimited.
 * @param string $input_format
 *   The format to use on filtered text to restore filter values before creating a summary.
 * @param string $output_format
 *   The format to use for the resulting summary.
 * @param boolean $add_elipsis
 *   Whether or not to add an elipsis to the summary.
 */
function custom_parse_summary($value, $limit = 150, $input_format = 'plain_text', $output_format = 'plain_text', $add_elipsis = TRUE) {

  // Allow filters to replace values so we have all the original markup.
  $value = check_markup($value, $input_format);

  // Completely strip tables out of summaries, they won't truncate well.
  // Stripping markup, done next, would leave the table contents, which may create odd results, so remove the tables entirely.
  $value = preg_replace('/(.*?)<\/table>/si', '', $value);

  // Strip out all markup.
  $value = PlainTextOutput::renderFromHtml(htmlspecialchars_decode($value));

  // Strip out carriage returns and extra spaces to pack as much info as possible into the allotted space.
  $value = str_replace("\n", "", $value);
  $value = preg_replace('/\s+/', ' ', $value);
  $value = trim($value);

  // Trim the text to the $limit length.
  if (!empty($limit)) {
    $value = text_summary($value, $output_format, $limit);
  }

  // Add elipsis.
  if ($add_elipsis && !empty($value)) {
    $value .= '...';
  }

  return $value;
}
?>

Adding a Presave Hook

I could have used this helper function in my update hook to populate my summary fields, but I realized that I actually want automatic population of the summaries to be the default behavior. I don't want to have to copy, paste, and truncate content from the body to populate the summary field every time I edit a node, I'd like to just leave the summary field blank if I want a truncated version of the body in that field, and have it updated automatically when I save it.

To do that I used the pre_save hook. The pre_save hook will update the summary field whenever I save the node, and it will also update the summary field when the above update hook does $node->save(), making sure that my legacy summaries also get this treatment.

My pre_save hook, in the same custom.module file used above, ended up looking like the following:


<?php

use Drupal\Core\Entity\EntityInterface;

/**
 * Implements hook_entity_presave().
 *
 * Make sure summary and image are populated.
 */
function custom_entity_presave(EntityInterface $entity) {
  
  $entity_type = 'node';
  $bundles = ['article', 'news', 'book'];
  // The new field for the summary. Must already exist on these content types.
  $summary_field = 'field_summary';
  // The new field for the body. Must already exist on these content types.
  $body_field = 'field_description';
  // The maximum length of any summary, set to zero for no limit.
  $summary_length = 300;

  // Everything is an entity in Drupal 8, and this hook is executed on all of them!
  // Make sure this only operates on nodes of a particular type.
  if ($entity->getEntityTypeId() != $entity_type || !in_array($entity->bundle(), $bundles)) {
    return;
  }

  // If we have a summary, run it through custom_parse_summary() to clean it up.
  $format = $entity->get($summary_field)->format;
  $summary = $entity->get($summary_field)->value;
  if (!empty($summary)) {
    $summary = custom_parse_summary($summary, $summary_length, $format, 'plain_text');
    $entity->{$summary_field}->setValue(['value' => $summary, 'format' => 'plain_text']);
  }

  // The summary might be empty or could have been emptied by the cleanup in the previous step. If so, we need to pull it from description.
  $format = $entity->get($body_field)->format;
  $description = $entity->get($body_field)->value;
  if (empty($summary) && !empty($description)) {
    $summary = custom_parse_summary($description, $summary_length, $format, 'plain_text');
    $entity->{$summary_field}->setValue(['value' => $summary, 'format' => 'plain_text']);
  }
}  
?>

With this final bit of code I’m ready to actually run my update. Now whenever a node is saved, including when I run the update to move all my legacy body data to the new fields, empty summary fields will automatically be populated with a plain text, trimmed, excerpt from the full text.

Going forward, when I edit a node, I can either type in a custom summary, or leave the summary field empty if I want to automatically extract its value from the body. The next time I edit the node the summary will already be populated from the previous save. I can leave that value, or alter it manually, and it won't be overridden by the pre_save process on the next save. Or I can wipe the field out if I want it populated automatically again when the node is re-saved.

Javascript or Presave?

Instead of a pre_save hook I could have used javascript to automatically update the summary field in the node form as the node is being edited. I would only want that behavior if I'm not adding a custom summary, so the javascript would have to be smart enough to leave the summary field alone if I already have text in it or if I start typing in it, while still picking up every change I make in the description field if I don’t. And it would be difficult to use javascript to do filter replacements on the description text or have it strip html as I'm updating the body. Thinking through all the implications of trying to make a javascript solution work, I preferred the idea of doing this as a pre_save hook.

If I was using javascript to update my summaries, the javascript changes wouldn't be triggered by my update hook, and the update hook code above would have to be altered to do the summary clean up as well.

Ta-dah

And that's it. I ran the update hook and then the final step was to remove my now-empty body field from the content types that I switched, which I did using the UI on the Content Types management page.

My site now has all its nodes updated to use my new fields, and summaries are getting updated automatically when I save nodes. And as a bonus this was a good exercise in seeing how to manipulate nodes and how to write update and pre_save hooks in Drupal 8.

Jun 24 2016
Jun 24
Installing drupal-vm on windows

An OSTraining member asked how to use the Drupal VM environment on Windows.

In this tutorial, we will install D8 in a few simple steps.

Download

First you will need to download:

Install

1# Install Vagrant and Virtualbox. 

You must make sure these are up to date in order for the vm to run correctly.

2# Extract the Drupal-VM from github into the location you wish to install the local Drupal VM.

3# Open Now command prompt with administrative powers:

  • In windows search type com and right click on the command prompt and select run as administrator 

4# cd into the folder with the administrative command prompt

with my setup that would be :

cd d:\drupalvmtest\drupal
cd..
d:

Initiate Vagrant

vagrant up

This can take 5+ minutes depending on how good your machine is. But it is 100% automated, so you can leave it working and check back later.

Once completed you will have status report with 4 options. If failed=0, everything has completed successfully and you can continue.

Making the VM accessible via the browser

Open up notepad with administrative powers (see step 3).

Navigate to C:\Windows\System32\drivers\etc.

Change the open type to All Files (*.*).

Select hosts, go to the end of the file and add 192.168.88.88 drupalvm.dev . Save the file and close it.

Check the vm is working

Enter drupalvm.dev in your browser should bring up the drupal 8 main page.

Login

By default the login and password are admin and admin

For more information check out the official website


About the author

Daniel is a freelance web designer who works from the UK and is a keen user of Drupal with a passion for Drupal 8.


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