Author

Roy
May 30 2016
May 30

After a couple of weeks of setting up with mostly free-format meetings in IRC we’re going to try a more structured format for our weekly UX meetings:

  • First half hour: people can introduce a problem + proposed (possible) solution
  • Second half hour: we review any work that has progressed over the past week. Often a core committer will be around to provide guidance or even actually commit changes that are good to go.

We did a first ad-hoc version of this last week, including a hangout with screen sharing. It worked really well, was productive and a lot of fun. Seeing the same thing in action is helpful when discussing user interface changes!

Next one is coming up and people from Acromedia will present on a topic and outline their proposed solution. For the second part I’m hoping we can review the “Place block” experimental module patch.

The meeting will take an hour. Here’s a calendar for the date and time.

Want to join? Join the UX channel on drupal.slack.com. Get an automatic invite here. We’ll link a hangout from there and make sure we’re broadcasting live so at least everybody who wants can follow along and use Slack for background chat.

See you there!

xjm
May 30 2016
May 30

Start: 

2016-05-31 12:00 - 2016-06-02 12:00 UTC

Organizers: 

Event type: 

Online meeting (eg. IRC meeting)

The monthly core patch (bug fix) release window is this Wednesday, June 01. Drupal 8.1.2 will be released with dozens of fixes for Drupal 8. There will be no Drupal 7 bugfix release this month.

To ensure a reliable release window for the patch release, there will be a Drupal 8.1.x commit freeze from 12:00 UTC Tuesday to 12:00 UTC Thursday. Now is a good time to update your development/staging servers to the latest 8.1.x-dev code and help us catch any regressions in advance. If you do find any regressions, please report them in the issue queue. Thanks!

To see all of the latest changes that will be included in the release, see the 8.1.x commit log.

Other upcoming core release windows after this week include:

  • Wednesday, June 15 (security release window)
  • Wednesday, July 06 (patch release window)
  • Wednesday, October 5 (scheduled minor release)

Drupal 6 is end-of-life and will not receive further releases.

For more information on Drupal core release windows, see the documentation on release timing and security releases, as well as the Drupal core release cycle overview.

May 30 2016
May 30

How to Improve Performance with HTTP cache headersIn this blog post I will show you a simple technique to improve your web application performance by modifying headers. Please keep in mind, if you're using HTTP reverse proxy caching applications such as Varnish you might harm your application performance or your settings could be ignored.

This technique could help improve page loads for authenticated users where reverse proxy caching disabled.

Important: Drupal already already provides all the required headers when Performance settings properly configured. This is information is generic and could be very helpful for decoupled projects or any other frameworks.

There are two primary cache headers, Cache-Control and Expires. You can set caching either time-based, content-based or on Expire date.

Cache-Control

The Cache-Control general-header field is used to specify directives that MUST be obeyed by all caching mechanisms along the request/response chain.

Settings

Example header:
Cache-Control: max-age=900, public

public - Indicates that the response MAY be cached by any cache, even if it would normally be non-cacheable or cacheable only within a non- shared cache.

private - Indicates that all or part of the response message is intended for a single user and MUST NOT be cached by a shared cache. This allows an origin server to state that the specified parts of the response are intended for only one user and are not a valid response for requests by other users. This parameter doesn't provide the same level of privacy as SSL does.

max-age - Indicates that the client is willing to accept a response whose age is no greater than the specified time in seconds. Unless max- stale directive is also included, the client is not willing to accept a stale response. (The value is in seconds)

See all available options RFC 2616

Expires

Note: If both Expires and max-age are set max-age will take precedence.

This header parameter tells the browser when to next retrieve the resource from the network.

Example:

Cache-Control:public
Expires: Mon, 25 May 2016 11:31:12 GMT

Time-based

Last-Modified - The Last-Modified entity-header field indicates the date and time at which the origin server believes the variant was last modified.

Example:
Last-Modified: Wed, 25 May 2016 11:45:26 GMT

If-Modified-Since - The If-Modified-Since request-header field is used with a method to make it conditional: if the requested variant has not been modified since the time specified in this field, an entity will not be returned from the server; instead, a 304 (not modified) response will be returned without any message-body.

Example:
If-Modified-Since: Wed, 25 May 2016 11:45:26 GMT

Content-based

ETag - Short for "entity-tag", the ETag is a unique identifier for the resource being requested, typically comprised of the hash of that resource, or a hash of the timestamp the resource was updated. Basically, this lets a client ask smarter questions of the CDNs, like "give me X if it's different than the ETag I already have."

Note: This tag is useful when for when the last modified date is difficult to determine.

Cache-Control:public, max-age=604800
ETag: "4345717de182e49e8d7bd9994af537ed" 

On subsequent browser requests the If-None-Match request header is sent with the ETag value of the last requested version of the resource.

If-None-Match: "4345717de182e49e8d7bd9994af537ed"

Drupal 8 Example

/**
 * Example Even Subscriber.
 */
class AddCustomHTTPheaders implements EventSubscriberInterface {

  /**
   * Sets extra HTTP headers.
   */
  public function onRespond(FilterResponseEvent $event) {
    $response = $event->getResponse();
    $current_user = \Drupal::currentUser();
    // Set Cache-Control for authenticated users
    if ( !$current_user->isAnonymous() ) {
      $response->headers->set('Cache-Control', 'public, max-age: 604800');
    }
  }

  /**
   * [email protected]}
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = ['onRespond'];
    return $events;
  }

}

Please read How to Register an Event Subscriber in Drupal 8 to learn more about the code example. And download Drupal 8 module to see how this can be implemented.

Useful links

  1. Increasing Application Performance with HTTP Cache Headers
  2. HTTP caching - Web Fundamentals - Google Developers
  3. Analysis of HTTP Performance problems
  4. Bloated Request & Response Headers
  5. Improve Performance with Cache-Control Headers
  6. Caching Tutorial
  7. A Guide to Caching with NGINX
  8. RFC 2616 - 14.9 Cache-Control
May 30 2016
May 30

Dries Buytaert, the creator and project lead of Drupal, and co-founder and CTO of Acquia, wrote a blogpost, 'Turning Drupal outside-in' three months ago that caused a large stir in the Drupal community. This post was particularly interesting for us as a Drupal development shop and active members of the international Drupal community because the future of our company is largely determined by the future of Drupal. In his writing, Dries discussed how the user experience of the Drupal platform be improved and how the CMS itself can be simplified, made easier to understand and easier to use.

After his first post, Dries wrote two more, ‘Examples of how to make Drupal “outside-in' and 'Handling contect in 'outside-in', where he thoroughly examined UX-related problems and even gave suggestions about how to transform some parts of Drupal. 

This is not the first initiative to target UX improvements in Drupal. But why is this topic important at all? Most of you have probably seen this funny - but valid - illustration that compares Drupal's learning curve to some other CMSs.

CMS learning curve

That is, to understand, manage and develop Drupal requires a lot, and as shown in the image above, many people give it up on the way. Despite Drupal being a well documented system-- there are only a few questions that you cannot find an answer to in the developer's guide-- we must state that creating the first few pages, understanding Drupal specific terminology, or finding some settings can cause a lot of headaches for a beginner.
I believe there are two reasons for it. First of all, Drupal was made by developers, by taking developers' needs into consideration (and this left some traces on the user interface as well). Second is that Drupal is also prepared to handle very complex solutions, which results in making the whole system complex.

At this year's DrupalCamp in London there was a UX session about this topic. The speakers showcased Wordpress's user experience by conducting a test. They gave a task to a friend of theirs to put together a website for a certain purpose in Wordpress and they presented the results and compared them to Drupal's out-of-the-box experience in the following discussion.. Similar to the reactions to Dries's first blogpost, a passionate debate developed between the 40-50 attendees about how this comparison is valid, what the target audience of Drupal is, and what kind of needs this target audience has. Should everything be drastically changed for the better user experience, or should it be an iterative process with smaller steps forward? I've been to many talks in the last few years, but I've never been to such a passionate one like this, and even though there was no conclusion in the end, and it became obvious that there are a lot of things to do in this area.

At that time nobody knew the answers to the questions and doubts that arose, but a few months later, half a year after releasing Drupal 8, Dries launched research about the state of Drupal. 2900 responses were submitted to this survey by content managers, developers, decision makers of smaller companies and larger enterprises, beginners and experts as well. The results were presented in his keynote at DrupalCon New Orleans.

Who should we favor

An important part of the research focused on the types of unresolved problems and which are most important for different target groups. If you are interested, you can watch the whole Driesnote and check the slides.

What can we do?

At Cheppers we've been doing graphic design for websites and services since the beginning, and we expanded our designer team with UX specialists at the beginning of 2015. Thanks to this, during the last year and a half, we got the chance to participate in UX research several times, in planning and in the realization, so I was able to closely observe how useful (furthermore, irreplaceable) UX research is when planning a website or a web service.

After Dries's first blogpost about this topic I started wondering how our UX team could take part in the process of improving Drupal's UX. After several discussions, we agreed that it would be useful to see the source of the problems and then come up with a suggestion to the solution. For this, research was definitely inevitable.
There was a similar usability test in 2015 at the Usability Lab of University of Minnesota, of which the results were presented at DrupalCon Barcelona last September, and which came with 100+ issues related to usability.


Our own research was prepared to make sure it covered the previously mentioned usability test, but it was partially simplified, and we also changed the tasks as we thought this could help us discover even more fundamental problems. We also wanted to include not only developers in our tests, so our own UX/UI team members participated in the process as well, as they are pretty much unfamiliar with the terminology and usage of Drupal. We asked for external help to do the tests: a huge thank you goes to Ákos Fülöp, the UX Designer who prepared, conducted the research, and analyzed the results. All tests were performed in a quiet room and were recorded to video, while Ákos was taking notes for the analysis. Here's the summary:

The purpose of this usability test was to analyze the latest version of Drupal 8 and the potential to turn the current developer-centric system into a more user-friendly one. The goal is to create a balance between the current, highly-modifiable system and other easy-to-use CMS systems, e.g. WordPress.

This usability test was about creating a landing page with general steps that are required for most websites, like installing the system, creating a post, etc... with people who did not have previous experiences with Drupal’s front end.

The test team had 10 participants from Cheppers, including 3 designers and 7 backend / cloud engineers who had to go through two slightly different tasks. There was only one rule: they could only use their computer for help, just like in real situations.

Designer tasks:

  1. Install Drupal 8 with the standard option.
  2. Rename the site and add a description to it.
  3. Create a “Contact Us” page with the provided content and place it in the main navigation.
  4. Create an article with the provided content (image and text).
  5. Change the logo in the header.

Developer tasks:

  1. Install Drupal 8 with the standard option.
  2. Rename the site and add a description to it.
  3. Change the article’s length on the front page to maximum.
  4. Add a new user with admin role.
  5. Display how many users are there currently on the site in the sidebar.

At the end, we summarized the problems according to how many participants faced each one and how long they had been stuck with each task. To prioritise the results we used the red routes methodology:

Priority grid

Issues

Installation Issues

It is not clear if the password strength box is a list of suggestions or mandatory. Major High percentage of the users haven't noticed the password strength box, just scrolled over to the next field. Normal User complained that the system let him to set a weak password as an admin. Normal The yellow after-installation instruction is incomprehensible for most of the users. Minor People don't really understand what is the "Advanced" subtab is good for. Minor The loading indicator at the installation showed 100% when the process haven't been finished. Minor "Why is my password weak? It is usually strong on other websites" Minor People complained that they couldn't find an option to see the exact process (like a terminal). Minor People tried to navigate with the side-bar to the previous steps. Minor It is not clear, that the site name will appear on the theme after installation. Minor

Content Issues

"Article is a content type". So many people added a new content type and they didn't understand why it's not visible on the front page. Critical "What is the difference between an article and a basic page?" The help texts were not so helpful. Major After the user created the first article to the site from the main page, he was confused how to create another one, because he couldn't find that button anymore. Normal People only realized that the alternate text is a mandatory to the images when they tried to publish the article.

Normal

Resizing an image was also a confusing task, most of the people wanted to see around the image adding button. Normal People are trying to put the basic page to the main navigation from the right sidebar near to the WYSIWYG editor. Normal "What is the difference between manage form display and manage display?" Minor When a dropdown opens with suggestions or previous contents it is impossible to click on them, Minor "What is caption means in this case?" Many of the participants searched for some help. Minor "Which box should I use? The top one (WYSIWYG) or the bottom (under the WYSIWYG editor)". Minor

Content Type Issues

"The article length settings must be in the configuration, like the other settings." Normal Because the article is visible on the frontpage, people expected to change their attributes from the "appearance" menu. Normal Article was understood as a block and some of the participants wanted to change the article length in the block menu. Minor Few participant wanted to edit the article length right from the editor (WYSIWYG's right sidebar) Minor After setting the teaser's length to default, users got confused why the "read more" button is still on the frontpage. Minor

UI Issues

There were many situations when the participant found the right answer for his issue (a step by step tutorial) but because of the UI element issues, can't pass it. Critical The dropdown options on different buttons are almost invisible, just only a few users opened it. Major The subtabs are looks like just texts, especially when there are a classic tab navigation around it. Major There is no visible difference between the front page and the article page and in few situations it caused some misunderstandings. Major There are some misused UI elements on different pages. E.g: users searched for an upload image button and not a "used default logo" checkbox when they wanted to change the site icon. Major The 3 admin menu after the installation shocked the user. They needed a few minutes to understand which menu is for what type of actions. Normal The hover edit option was mostly discovered accidentally on the front page. Normal The edit button on different blocks shows different options and it confused the users. Normal The UI elements are sometimes not consistent, e.g: most of the CTA buttons are blue, except the "place block" button, which is grey. Normal A few people started to fill the search fields and click on the blue CTA (e.g. add user). Minor The green success feedback banner is not disappearing after time, and people thought that it is an automatic autosaving. Minor Some popup boxes have a horizontally splitted text line at the bottom. UI bug Minor

Appearance Issues

People didn't know what "Bartik" title means on the "Appearance" page. Normal People didn't know what "Seven" title means on the "Appearance" page. Normal

Menu Issues

People tried to first create a link (for the menu) and after it the connected article. Unfortunately drupal works in the opposite way. Critical "Why do I have to know the link ??" Users thought they have to know the page's exact link to connect it. Major Nobody understood why nothing is happening after clicking repeatedly to the circle in the right side of the link field. Normal People got confused, when they tried to add a menu to the frontpage and saw the "enabled" checkbox checked in. "it makes no sense" Normal When people tried to create a link to the frontpage, they didn't know what is the dropdown with "parent link" text for. Minor If the user duplicates a link it hard to decide which was the first. Minor

Help Issues

"This page is useless, I can't find anything here!" User tried to find a solution for his problem, but after 5 minutes still haven't found anything. Major People get confused and left the page because of the "too much text". "I don't have time to read this" Normal After opening the help page, users immediately changed it to Google. Normal Only 20% of the users opened the help page, others started with Google. Normal Users are looking for a Google style search on the help page, because they don't know what is their problem. Normal

Taxonomy Issues

After the installation, the users got stuck because Drupal's taxonomy, they didn't knew where to find what. Critical People don't understand the "slogan" and they can't predict what will change. Critical People got confused after reading the different region names when they tried to add a new block. Major "Is basic page = landing page?" User asked when tried to add a new block. Normal Blocks were understood as plugins. Normal People don't understand the "weight" and what it is good for. Minor "It is confusing, that the system calls the users sometimes "People", and sometimes "Users". What is the difference?" Minor

Block Issues

The "visibility box" only confused the users, because it worked in the opposite way, than they expected. Critical People don't understand what is the "visibility box" good for, and why is it highlighted. Major Blocks were understood as content, so they tried to add a new one as it would be an article. Normal "Sidebar second is under sidebar first" People only read the list, but don't really know where they place the blocks. Normal Some users tried to find the blocks in the "Appearance" menu, because "it is visible on the website, so it must be here". Normal The "Block regions" page is not helpful for the users, still have no idea, which region is good for them. Normal

Site Information Issues

After changing the site name on the site information page, user wonderred why it's not changed on the front page. Major People want to edit the description from the main page by editing the block (still couldn't find the howto). Major "The name, title and the logo should be in the appearance, like in other systems" Normal Site description was understood as a content, and most of the people started the searching in the content menu. Minor "Site description = account settings" Another misunderstanding about drupal compared with other similar systems. Minor

We then compared our results with the test's results from 2015. There were obvious matches:

  • In general, terminology of Drupal is confusing. 
  • Where to search for information and how to find it?
  • Content creation after creating the first content item.
  • What's the difference between manage form and manage form display?
  • The 'Edit' button shows different options on different blocks, it's confusing.
  • Order of creating links in main navigation and connecting it to pages. 
  • Is Basic page a landing/the front page?
  • How does 'weight' work and what is the logic behind it?

These are just some highlights, but there were a lot of other items on our lists that appeared in the original test results as well and covered a similar area of Drupal. We also found a lot of issues not previously documented, which is not a surprise, as the tasks were not the same in the two tests.

What are the next steps?

A website dedicated to Drupal UX was launched recently. Various ways to join the initiative are mentioned on the front page of the site, and we're going to join the discussion to figure out how we can take part in planning and the implementation. We will suggest creating a UX research template with suggestions that help unify the main research. We would also like, with the help of the community, to find solutions to the problems discovered during our own research and create issues for the problems, a was the case with the Minnesota research.

It’s wonderful that we can take part in the contribution in this way as well, and I am excited to see what results will we get within the next few months, as the solution to this complex problem is long awaited. 
I want to encourage everyone interested in the process and the results to join the communication channels mentioned on drupalux.org, and take part in building Drupal and making it better, so anybody who joins the Drupal community can have a system that is enjoyable to use and improve.

Sidenote:

Andor Dávid, our lead Drupal developer, also deserves a huge shout-out, as he took part in figuring out the test tasks, and he also presented the correct solution of solving them to Ákos Fülöp, the conductor of the tests. I am also very grateful for my colleagues’ limitless patience for taking part in the research as test subjects.

May 29 2016
May 29

On a previous post I explained how we are using BigPipe in Drupal 7 (Cheap Pipe (sort of BigPipe) in Drupal 7). Besides all the known benefits of big pipe, there is a less known side effect that might help you fight spam.

Those out there fighting for conversion optimization know that captcha based form protection is a conversion killer (even with the new NoCaptcha from Google). That's why you should always be looking for ways to protect your web application from bots without real users noticing or their workflows being affected.

Even non-intrusive method such as Honeypot or Hidden Captcha are becoming less effective as bots get more sofisticated.

For us, what has been working very well historically against SPAM is using real e-mail verification when capturing cold leads.This basically consists in trying to deliver a fake message to the e-mail address submited to the form. Addresses used by SPAM bots usually do not exist or have been throttled by the e-mail provider. Of course, e-mail verification is the last stand after being able to go through a set of non intrusive form protection techinques (such as honeypot and/or hidden captcha).

A recent change in one of our customer's applications resulted in an increased number of fake leads being sent to Sendy that were able to pass e-mail verification as they were using valid and not throttled e-mail addresses. If you don't know what Sendy is, it's a self-hosted "simple Mailchimp" that can bring massive savings to e-mail based marketing.

So we decided to  force BigPipe on the block that renders the new lead capturing form, and SPAM submissions stopped inmediately. This makes some sense. Content that is rendered using BigPipe is loaded into the DOM through AJAX. I guess that - for performance reasons - most bots probably don't use a full emulated browser and rely on parsing/scanning the HTML response from the server to perform automatic form submissions. What used to be a plain rendered form, is now this to the eyes of the bot:

May 28 2016
May 28

The Drupal community is very special because of its culture of adapting to change, determination and passion, but also its fun and friendship. It is a combination that is hard to come by, even in the Open Source world. Our culture enabled us to work through really long, but ground-breaking release cycles, which also prompted us to celebrate the release of Drupal 8 with 240 parties around the world.

Throughout Drupal's 15 years history, that culture has served us really well. As the larger industry around us continues to change -- see my DrupalCon New Orleans keynote for recent examples -- we have been able to evolve Drupal accordingly. Drupal has not only survived massive changes in our industry; it has also helped drive them. Very few open source projects are 15 years old and continue to gain momentum.

Drupal 8 is creating new kinds of opportunities for Drupal. For example, who could have imagined that Lufthansa would be using Drupal 8 to build its next-generation in-flight entertainment system? Drupal 8 changes the kind of end-user experiences people can build, how we think about Drupal, and what kind of people we'll attract to our community. I firmly believe that these changes are positive for Drupal, increase Drupal's impact on the world, and grow the opportunity for our commercial ecosystem.

To seize the big opportunity ahead of us and to adjust to the changing environment, it was the Drupal Association's turn to adapt and carefully realign the Drupal Association's strategic focus.

The last couple of years the Drupal Association invested heavily in Drupal.org to support the development and the release of Drupal 8. Now Drupal 8 is released, the Drupal Association's Board of Directors made the strategic decision to shift some focus from the "contribution journey" to the "evaluator's adoption journey" -- without compromising our ability to build and maintain the Drupal software. The Drupal Association will reduce its efforts on Drupal.org's collaboration tools and expand its efforts to grow Drupal's adoption and to build a larger ecosystem of technology partners.

We believe this is not only the right strategic focus at this point in Drupal 8's lifecycle, but also a necessary decision. While the Drupal Association's revenues continued to grow at a healthy pace, we invested heavily, and exhausted our available reserves supporting the Drupal 8 release. As a result, we have to right-size the organization, balance our income with our expenses, and focus on rebuilding our reserves.

In a blog post today, we provide more details on why we made these decisions and how we will continue to build a healthy long-term organization. The changes we made today help ensure that Drupal will gain momentum for decades to come. We could not make this community what it is without the participation of each and every one of you. Thanks for your support!

May 27 2016
May 27

Serving Drupal’s opportunity

The release of Drupal 8 creates many opportunities for organizations worldwide to build something amazing for complex web solutions, mobile, SaaS, the Internet of Things, and so much more. The Drupal Association is excited to work with the community to create these opportunities.

In our mission to support the Drupal Project, the Association unites our global open source community to build and promote Drupal. We do this primarily by using our two main resources: Drupal.org, the center of our community’s interactions, with 2 million unique visitors a month; and DrupalCon, which hosts over 6,000 attendees a year and provides the critical in-person acceleration of ideas.

Both foster the contribution journey that makes amazing software, and the evaluator’s adoption journey that encourages people to use Drupal across industries to create amazing things. As I mentioned in my recent blog post, achieving our mission helps the community thrive into the future and realize their Drupal dream.

With the release of Drupal 8, we have an opportunity to reflect on how the Association leverages these assets to work for Drupal’s current and future opportunities. Working with our board of directors, we determined that the Association needs to:

  • Re-assess the Project’s needs, and find new ways to support and meet those needs
  • Address a structural issue, to be a more sustainable organization

To do this, the Drupal Association board and I made hard choices. Having invested heavily in supporting the Drupal 8 release and exhausting available reserves, we recognize that the Association now must right-size the organization and balance our income with our expenses. The biggest impact is the elimination of seven positions, reducing our staff size from 24 to 17 employees. Also as part of this reduction, we have reorganized staff to better address the Project’s needs now that Drupal 8 is released.

While we do have our eye on a bright future for the Project through these changes, we’re also painfully aware that we’re not just eliminating positions. We’re saying goodbye to seven people who are important to us—whose contributions we value more than we can describe. We’re impacting the lives of people we care about—people who’ve given a lot to the Project and to others in our community.

Making the Drupal Association sustainable

In early 2014, the Association began investing reserves in building an engineering team for two main reasons: to address critical issues that were slowing down the production of Drupal 8, and to modernize Drupal.org. In doing so, we purposefully created a structural deficit, with the hopes that we could grow revenue to meet the cost of this investment before we drew down our reserves.

Because of this investment, we were able to accelerate the release of Drupal 8 through a roadmap of features like semantic versioning, DrupalCI (continuous integration testing for the projects we host), better search and discovery capabilities, numerous issue queue improvements, and issue credits, all of which positively impacted the release of Drupal 8. In addition, the engineering team has addressed years of technical debt and incorporated more modern services in the site that have made it more reliable and faster around the world.

While revenue grew from 2014 to 2015 by 14%, it didn't grow enough. Last year, we acknowledged that we did not meet the revenue goals that would sustain this investment. We addressed it with a retrenchment designed to extend our runway and see if we could increase revenue sufficiently. All told, while we have accomplished both revenue diversification and growth, it wasn’t enough to fully replace the investment. Then in spring 2016, several things happened on the revenue front that created a significant budget gap:

  • Sponsored work: The Association funded Engineering resources by accepting sponsored work to build Composer endpoints for Drupal projects. After that project was completed, we were unable to line up an additional sponsored project to continue underwriting the Engineering team.
  • The Connect Program: This new experimental program designed to connect software companies with service providers for partnership and integration opportunities did not meet its revenue goals.
  • DrupalCon: DrupalCon New Orleans ticket sales did not reflect the increase we were expecting this year, and we have revised our DrupalCon Dublin ticket sales projections accordingly.

Chart: 2010-2016 revenue and expense trend

"CAGR" means compound annual growth rate.
2016 data is projected revenue and expenses.

Addressing this structural deficit required a reduction of both labor and non-labor expense. Labor is our biggest cost, and we can’t create alignment without cutting roles at the Association. Holly Ross, our Executive Director, Josh Mitchell, CTO, and Matthew Tsugawa, CFO, offered to step down and contribute their salaries to the reduction, as they saw that a smaller organization doesn’t require a full leadership team. Additionally, we are losing three staff members from the Engineering team, one from the Events team, and one from the MarComm team. We are working with these staff members to help them through their transition.

Our second biggest expense is rent. We are working to eliminate the physical office in Portland, Oregon—moving staff to a virtual, distributed team—but those efforts will likely not introduce savings until 2017. We already work with distributed staff and community members around the world, so we have the know-how and tools like Slack and Zoom in place to support this change when it happens.

While these staff reductions are painful today, they correct the structural problem, bringing expenses in line with income. We have conservatively reforecasted revenue to reflect any impact this staffing reduction may have. We can see with our forecasts that the layoffs result in the Association being on healthy financial ground in 2017.

What happens next?

Leading up to now, we invested in tooling to help the community release Drupal 8. Now that Drupal 8 has shipped, the Project has new needs, which are:

  • Promote Drupal 8 to grow adoption
  • Sustain Drupal.org so the community can continue to build and release software

Drupal.org is our strongest channel for promoting Drupal, given that it’s the heart of the community and organically attracts hundreds of thousands of technical decision makers. It provides the biggest opportunity to guide evaluators through an adoption journey and amplify Drupal’s strength in creating new business opportunities through solutions like “DevOps and Drupal” or “Drupal for Higher Education.” These new services on Drupal.org will help evaluators, create value for our partners, and increase revenue for the Drupal Association.

We can also use Drupal.org to better promote DrupalCon. It’ll help grow ticket sales and attract more community members to that special week of in-person interaction, accelerating their adoption and contribution journeys.

Additionally, we’ll expand our efforts to attract more evaluators to DrupalCon. We can accelerate their adoption journey through peer networking and programming that helps them understand how Drupal is the right solution for their organization. We do this today with our vertical-specific Summits (like the Higher Education Summit) and we can do more through relevant sessions and other special programming. And while the Drupal evaluators are there, we’ll connect them with Drupal agencies who can help them realize their Drupal vision.

One thing about our work won’t change: our commitment to the tools you use to build Drupal every day. Though the Engineering team is smaller after today, they will make sure the tools and services you need to build and release the software are supported. That includes things like the issue queues, testing, security updates, and packaging.

Right now, we’re focused on the team as we go through this transition. Once the transition is complete, we’ll be looking at the Project needs and making sure we align our work accordingly. When we make changes, we’ll be sure to keep the community updated so you know what our primary focus is and how we are working towards our vision of Drupal 8 adoption across many sectors.

In the meantime, I invite you to tell me your thoughts on this new focus and how the Drupal Association can best help you.

May 27 2016
May 27

Any time there are major new versions of software, some of the tooling surrounding the software requires tweaks before everything works like it used to, or as it's documented. Since Drupal 8 and Drush 8 are both relatively young, I expect some growing pains here and there.

One problem I ran into lately was quite a head-scratcher: On Acquia Cloud, I had a cloud hook set up that was supposed to do the following after code deployments:

# Build a Drush alias (e.g. [subscription].[environment]).
drush_alias=${site}'.'${target_env}

# Run database updates.
drush @${drush_alias} updb -y

# Import configuration from code.
drush @${drush_alias} cim vcs

This code (well, with fra -y instead of cim) works fine for some Drupal 7 sites I work on in Acquia Cloud, but it seems that database updates were detected but never run, and configuration changes were detected but never made... it took a little time to see what was happening, but I eventually figured it out.

The tl;dr fix?

# Add --strict=0 to resolve the error Drush was throwing due to alias formatting.
drush @${drush_alias} updb -y --strict=0

# I forgot a -y, so Drush never actually executed the changes!
drush @${drush_alias} cim -y vcs

For the first issue, Acquia cloud generates its own Drush alias files, and in all the aliases, it includes some options like site and env. It seems that Drush < 8 would just ignore extra options like those... but Drush 8.x throws an error and stops execution for the current task because of those extra variables. Using --strict=0 tells Drush to squelch any erros thrown by those extra options. Eventually, I'm guessing Acquia Cloud's Drush aliases will be made to be fully-compatible with Drush 8.x, but this workaround is fine for now.

For the second issue, it was just my boneheadedness... if you're running any command that requires a prompt non-interactively (e.g. through an automated system like cloud hooks), you have to add the 'assume-yes' option, -y, just like I used to with fra -y in Drupal 7!

Before, I would get the following error message on every Cloud deployment:

The following updates are pending:

custom module :
  8001 -   Add customizations.

Do you wish to run all pending updates? (y/n): y
Unknown options: --site, --env.  See `drush help                         [error]
updatedb-batch-process` for available options. To suppress this
error, add the option --strict=0.
Unknown options: --site, --env.  See `drush help cache-rebuild` for      [error]
available options. To suppress this error, add the option --strict=0.
Finished performing updates.                                                [ok]

Even though it says 'Finished performing updates', they didn't actually get run. Now it runs the updates without any issue:

The following updates are pending:

custom module :
  8001 -   Add customizations.

Do you wish to run all pending updates? (y/n): y
Performing custom_update_8001                                                                              [ok]
Cache rebuild complete.                                                                                      [ok]
Finished performing updates.                                                                                 [ok]

May 27 2016
May 27

Over the last few Drupal releases, the Webform module has been the standard for creating robust forms and surveys. While this venerable module has served the community’s needs quite well, major releases of Drupal often afford the opportunity to take a fresh look at how common problems are solved, leveraging new technologies and concepts introduced in the release.

Baked into Core

Since Drupal 4.6, Drupal Core has shipped with a basic contact form module that had limited functionality. Finally, the contact module got some much-needed attention in Drupal 8. Contact forms are now fieldable entities, allowing us to build forms with the same fields we build content types, taxonomies, and other entities with.

Building Out the Form

Forms are created and managed by navigating to Structure->Contact Forms in the Admin menu. From here, choose “Add contact form.”

Drupal 8 Contact Form Admin

This takes us to a form for setting the name of the form, email addresses for submissions to be sent to, and optionally an auto-reply message to the submitter. Once saved, we are taken back to the Contact Forms admin page. 

Add Contact Form

This gives us a basic form with Sender Name and Email, a Subject field, and a basic text area for a Message. To add fields to our new form, we need to select the “Manage Fields” option in the Operations dropdown. From here, we can add any of the field types available on the site.

Add fields

Form Display

To customize how the form is displayed, we want to select the “Manage Form Display” option in the Operations dropdown. This will allow us to change the order of the fields for the form, change configurations for each field, and allow us to disable any fields that are provided by default that we don’t want to use.

Form Display Admin

Manage Display

Similar to Form Display, if we want to change the order and display of fields in the submission emails, using the “Manage Display” option will allow us reorder or hide fields from showing in the submission email.

Display Admin
Submission Storage and Export

Everything we’ve covered so far is great if we want to build out a form and start getting submissions by email. However, if we want to save and view submissions in the site or want to export the submissions in bulk, we need to look to some contributed modules to fill in the gaps.

Contact Storage Module

As its name implies, the Contact Storage module addresses the need for a central location from which content editors can review and manage form submissions on the site. The module also provides Views integration as well as some additional customization options for our forms. The default configuration provides these features for us, so we can install the module and start benefitting from it immediately.

Submission Exports

We now have robust forms and a place to centrally store their submissions, with Views giving us the ability to build out lists of submissions. What we’re still missing at this point is a way to download the submissions in bulk, and it’s fairly common to want such an export in a format like CSV that can be loaded into a spreadsheet application. To achieve that, we can put our Views integration to use, along with Drupal 8’s REST Module, and the CSV Serialization module. 

Once these modules are installed, create a new view of Contact Messages and check the “Create a REST Export” option, providing the path we will navigate to trigger the export. Then hit Save and Edit to continue configuring the view.

Create new View

In the format section of the view configuration page, we see the format is set to “Serializer”. Here, we want to configure the settings for Serializer, and select the “csv” format.

View Format Settings

REST Export Style Options

At this point we have a working view that will export all submissions as a CSV. We can leave the view set to show content as “Entity,” which will export all fields for the submission, or we can switch the display to “Fields,” which will allow us to specify the fields we want in the export, and how they are formatted.

With exports now provided by Views, we can create custom exports for specific forms, or we can utilize Exposed Filters and Contextual Filters to provide an export that works for all forms, allowing users to choose how they want the export filtered.

More Form Solutions in Contrib

If we need to provide robust survey forms now, the approach covered here is currently the most stable and ready to implement. If this solution doesn’t meet your use case, it might be worth taking a look at eForm, the Drupal 8 version of the Entityform module introduced in Drupal 7. There is also still some discussion of a Drupal 8 port of the Webform module, so it’s possible with enough interest we could have a few different solutions for providing front-facing forms to end users.

While building forms will be a bit different in Drupal 8 compared to previous versions, the experience is more in line with what we’ve come to expect from building Content Types and other fieldable entities. This provides the opportunity for more flexibility and functionality when building front-facing forms, and the Views integration provides the opportunity to present and export the submitted form data just the way we need.

May 27 2016
May 27

entity metadata wrapper

How many times have you been in a preprocess function or a custom module trying to get the value, or editing an entity? If you’ve had the pleasure to work with Drupal code before, my guess is plenty!

This is a very common process for things like checking against a custom field value to determine layout, send information to a third party API (i.e. client CRM, or analytics tracking) or, like we do here at TAG, include content changes in a release script.

As flexible and powerful as this process can be, dealing with the endless arrays that Drupal provides is tedious and unreliable. Lets look at this snippet of code for example:

$body = $node->body[LANGUAGE_NONE][0][‘value’];

The obvious problem here with getting the value of a node’s body field is the language handling. If at any point the entity gets translated, the code will have to be updated. I also personally think that it’s not very clean.

Thankfully, entity_metadata_wrapper is here to rescue us. This is a entity_api function, so that module will have to be installed and enabled. In your code you can then do the following:

$node = entity_metadata_wrapper(‘node’, $nid); // The first argument is the entity type. The second is the entity ID or the entity object if it’s already loaded.
$body = $node->body->value(); // The body of the node in a much cleaner and maintainable way.

You can also easily set values like this:

$node->body->value =New body value’;

Or even better, by using the setter method:

$node->body->set(New body value’);

Don’t forget to save by using the new save method:

$node->save();

Dealing with a field with multiple values like a list? No problem! Just try this:

foreach ($node->field_list->getIterator() as $delta => $list_item) {
    $label = $list_item->value();
}

Dealing with entity references? No problem! The referenced entity is "wrapped" as well, and can be treated the same way. Check out this example with a node reference field:

$referenced_nid = $node->node_reference->raw(); // This returns the id of the referenced entity.
$referenced_node = $node->node_reference->value(); // This returns the referenced entity object.
$referenced_title = $reference_node->title(); // The referenced entity’s title.

Overall, you can see how this way of dealing with Drupal entities is much more elegant and effective. It personally saves me a lot of time and the grief of having to look at endless arrays and dealing with undefined index errors.

There is much more to this that can be found on the drupal.org documentation page here.

As always, don’t hesitate to correct me or ask questions in the comments section. I look forward to hearing your thoughts on the matter!

May 27 2016
May 27

We made it to the finish line of another busy work week!

Thanks for joining us for Episode 9 of The Mediacurrent Friday 5. This week, Community Lead Damien McKenna discusses 5 Tips for Improving Your Site's SEO with the one and only Mark Casias.

He provides some great pointers on the following topics: Submodules, Configuration, Content types, Vocabularies, Users, Oh My!, The Front Page, and Most Important Meta Tags. Watch the video below to learn more.

[embedded content]

Is there a topic that you'd like to learn more about? Send us your thoughts to [email protected] and stay tuned for Episode 10 in two weeks. Have a great weekend!

Additional Resources
How to Improve your Conversion Path Optimization | Blog Post
Mediacurrent's Crash Course in SEO and Drupal | Webinar
SEO Keyword Strategy | eBook

May 27 2016
May 27

A lot of thanks to the commerce guys for contributing the Drupal commerce module to Drupal community, which took drupal to a different level in the CMS world. Its very exciting, Commerce 2.x which is the Drupal 8 version of drupal commerce. As like any other drupal developer / architect, I am also excited about Commerce 2.x

Thank God, I was one of the fortunate ones to attend the Commerce Guys session on DrupalCon New Orleans 2016, the very first session after the release of ‘8.x-2.0-alpha4’  version of drupal commerce. It was an amazing session, which made a lot of things clearer,a lot of unanswered questions were answered by the Commerce guys themselves. Here we are going to discuss about the take away of the Commerce Guys session on DrupalCon New Orleans 2016.
 

No more Commerce Kickstart in Drupal 8, Why?

No more Commerce Kickstart in Drupal 8,because Commerce 2.x is developed as loosely coupled by using a lot of PHP 5.4+ libraries like tax [tax library], addressing [addressing library powered by Google’s dataset], intl [internationalization library powered by CLDR data], zone [zone management library]. Using composer we can create a new site as like commerce kick start in Drupal 7. For that we have to use the following command.

$ composer create-project drupalcommerce/project-base mystore --stability dev

 The above command will download Drupal 8 + Commerce 2.x with all dependencies to the ‘mystore’ folder. Before running the above command please make sure you have installed composer globally on  your system.

How to install Commerce 2.x on existing site?

For Installing Commerce 2.x in existing Drupal8.x site,  we need to do the following steps.

Step 1: Add the Drupal packagist repository which allows Composer to find Commerce and the other Drupal modules. For that run the following command, 

$ composer config repositories.drupal composer https://packagist.drupal-composer.org

Step 2: The following command will help us to download the required libraries and modules (Address, Entity, State Machine, Inline Entity Form, Profile).

$ composer require "drupal/commerce 8.2.x-dev"

Step 3: Enable the modules “commerce_product commerce_checkout commerce_cart commerce_tax” , Use drush or drupal console

Read more about the commerce documentation on: http://docs.drupalcommerce.org/v2/

The above steps help you to install the commerce 2.x on the existing site. Moreover  that in Drupal 8 commerce 2.x  requires lot of contrib modules developed and contributed by commerce guys themselves. The following ones are the famous ones.

  1. Inline Entity Form
  2. Address
  3. Profile
  4. State Machine

What is new in Commerce 2.x?

  1. Currency Management :  Integrated the Unicode CLDR project. So it is easy to use the currency inside and outside the US.                                                                                     
  2. Price Formatting: Price format  varies from country to country and language to Country.  Like German(Austria) Vs German(Germany)                                                                       
  3. Taxes: Imports the tax rates automatically on country basis depending upon the product like B2B, B2C, digital or physical products.                                                                           
  4. Stores: Multiple stores in same Drupal Commerce Instance, hence there will be majorly two types of use cases, first one is where User can create their own stores based on their own products. Which means multiple cart from multiple stores, from the buyer’s perspective. The Second one being this, that the Company has billing location in multiple countries.                                                                                                                                
  5. Products: Instead of nodes we hare having Product entity itself. On the production creation page using inline entity to create individual product variations. And those variations holds the SKUs and sets of attributes.                                                                  
  6. Product Attributes: In Commerce 2.x product attributes are its own entities, So it is easy to edit, delete, create new attribute from. Suppose you want to add the attributes to the product variation type,  you have to edit the respective production variation type and select the checkbox under the ‘Attributes’. So it is easy to use different form of modes to display fields.                                                                                                                           
  7. Order and Line Item Types: This will provide the option to have separate order types for different types of products like physical and digital products, event registration, training payment etc. So it s provide different checkout flow, different workflow, different logic  or different experience to the customers.                                                                                  
  8. Order Editing: Order is in step by step. Right columns provide the IP address  and the geo location of the order.                                                                                                            
  9. Add to Cart Forms: In the add to cart forms,we can have the variation attributes fields and line item fields as well. Now we have full control add to cart forms powered by Form display mode and field widget plugin.                                                                                   
  10. Shopping Carts: If you having multiple shopping carts, the ui will help to see and checkout each of them separately.                                                                                        
  11. Shopping Cart block: Easily customizable shopping cart block.                                           
  12. Checkout Flows: You can define your own custom checkout flows.                                    
  13. Improved Checkout UX:  It provides the option to do checkout as a guest user, or can also be registered as a new user while doing checkout.                                                       
  14. Payments: Under active development, Currently integrating Braintree and Authorize.Net as reference implementations.                   

Conclusion

Early in 2017 or even before Commerce 2.x will be fully functional. Commerce 2.x  with Drupal 8 will make a difference in the ecommerce world.

Image credits: https://www.flickr.com/photos/comprock/26392816934/in/pool-drupalconneworleans2016/

May 27 2016
May 27

Part 1: Architecture
Part 2: Installation & Configuration
Part 3: Video & Playlist Management
Part 4: Including Videos & Playlists in Drupal content

In this multi-part blog series, we are covering the various aspects of the new Brightcove Video Connect module for Drupal 8. Part 1 consisted of an Architecture summary and discussed the Technical approach used during the development of the module. Part 2 detailed the Installation & Configuration steps required to get the module up and running properly. This third part illustrates the management of Videos & Playlists and discusses some of the changes compared to the Drupal 7 version of the module.

Video listing

Once videos have been “imported” from Brightcove or uploaded through Drupal, a listing becomes available in an intuitive interface (with a similar layout to Brightcove’s own Studio interface) located in a tab right next to Drupal’s main Content tab:

Brigthcove Videos list in admin_content

The new listing pages allow you to manage videos in a streamlined manner - something that wasn’t possible in the previous Drupal 7 versions as the video listings were limited and only accessible through an overlay while Attaching a video to a node.

Video upload and edit

When uploading a new video (or editing an existing one), a major improvement over previous Drupal versions is that the upload/edit screen is no longer presented in an overlay - but in the same layer as the other configuration screens:

Add/Edit Brigthcove Video

As can be seen above, tags now include an autocomplete feature. The Related Link URL now also includes autocomplete, letting you search for Drupal nodes:

Autocomplete related link URL

The video upload section has been improved by allowing a wider variety of audio and video container formats, and both the video and image source files can now be replaced with new files on existing assets:

Video upload section

The Availability section has also been improved with a new calendar dropdown:

Video availability section

Finally, not only can videos be uploaded and edited in an efficient manner, but also deleted (deleting Brightcove videos wasn’t possible in the previous Drupal 7 versions):

Video delete

Playlist listing

A listing similar to the Brightcove Video is also available for Playlists:

Playlist listing

Smart Playlist edit

Tags are also autocompleting in the Smart Playlist edit screen as can be seen below:

Smart Playlist tag autocomplete

Manual Playlist edit

Manual Playlists also feature an autocompleting field - this time for the individual videos to be included in the playlist:

Manual Playlist tag autocomplete

Part 4 of this multi-part blog series will demonstrate how to include Brightcove Videos & Playlists in Drupal content.

May 27 2016
May 27

Without further ado, hierbij wat mij opviel aan Drupal modules de afgelopen maand:

1. Hide submit button

Voorkom duplicate content doordat mensen twee maal op de Save button klikken. Deze module zorgt ervoor dat de Save button niet meer dan één keer aangeklikt kan worden, door hem onbruikbaar te maken na de eerste klik.

Download (Drupal 7)

2. Magnific Popup

Maakt automatisch een mooie, snelle galerij met afbeeldingen aan. Met mogelijkheden om de afbeeldingen uit te vergroten op verschillende manieren.

Hij maakt gebruik van de lichtgewicht jQuery lightbox library Magnific Popup en implementeert een Drupal field waarmee je vervolgens afbeeldingen kunt toevoegen aan content.

Download (Drupal 7 & Drupal 8)

3. Mail Verify

Een betere manier om ingevoerde e-mail adressen te verifiëren. De Drupal 8 core verifieert alleen op basis van format, deze module verifieert op een geheel andere manier: hij probeert daadwerkelijk verbinding te maken met betreffende e-mail server om te checken of het ingevoerde e-mail adres ook daadwerkelijk bestaat.

Gebruik deze module niet als primaire bescherming tegen spam, anders loop je kans dat je server wordt ge-greylist. Zet dus voor web formulieren (bv contact, sign-up) bijvoorbeeld Mollom en Honeypot in als primaire spam protectie.

Download (Drupal 8)

4. Search exclude nid

Het kan nodig zijn om bepaalde nodes uit te sluiten van de zoekresultaten in Drupal, simpelweg omdat deze niet relevant zijn.

Download (Drupal 7 & Drupal 8 dev)

5. Facebook Comments Block

Biedt de mogelijkheid om Facebook reacties te laten plaatsen op pagina’s in je Drupal website. Hier zijn meerdere modules voor beschikbaar, maar deze maakt het je gemakkelijk door zijn eenvoudige configuratie. Deze Drupal 8 module gebruikt tevens het systeempad (node/xx) en niet de url alias, waardoor de reacties blijven staan; ook als je de url alias wijzigt.

Download (Drupal 7 & Drupal 8)

Gerelateerde module: wijzig je de url alias van een Drupal pagina? Zorg dat je de Redirect module geïnstalleerd hebt, zodat die automatisch een 301 -permanent redirect aanmaakt. Op deze manier houd je de SEO van betreffende Drupal pagina in tact.

6. Require Login

Zorg ervoor dat jouw complete Drupal website afgeschermd wordt: alle bezoekers moeten inloggen voordat zij content te zien krijgen. Handig voor een Drupal social intranet, of voor het afschermen van testomgevingen.

Download (Drupal 7 & Drupal 8)

7. Dynamic Entity Reference

Een Drupal module waarmee je een entity reference field kan aanmaken waarmee je kunt refereren naar meerdere entity types in plaats van slechts één.

Download (Drupal 7 alpha & Drupal 8 rc4)

8. Field Hidden

Biedt de mogelijkheid om een ‘hidden’ veld toe te voegen: < input type="hidden" / >. Bezoekers zien dit veld niet, waardoor je het kunt gebruiker om verborgen informatie in formulieren mee te geven. Meestal is dit systeeminformatie.

Download (Drupal 7 & Drupal 8)

9. Double field

Soortgelijk aan de Field collection module, maar dan lichtgewicht: splits je veld op in twee delen. Een voorbeeld waarom dit handig kan zijn:

Download (Drupal 7 & Drupal 8 rc1)

10. Classy paragraphs

Soms wil je een optioneel een extra class toevoegen aan een specifieke paragraaf in een stuk Drupal content, zodat het de juiste styling krijgt. Maar je wilt je content managers niet vermoeien met het schrijven van HTML.

Deze module biedt de oplossing: hij genereert een extra knop in de tekst-editor, waarmee Drupal een extra HTML class toevoegt op gekozen paragraaf.

Selecteer zelf de styles die je beschikbaar wilt hebben.

Deze module is afhankelijk van de Paragraphs module.

Download (Drupal 7 beta1 & Drupal 8 alpha1)

11. Supercookie

Binnen de Drupal core is het lastig om álle unieke gebruiker te tracken, voornamelijk als zij allemaal uit één gebouw (en dus één IP) je Drupal website bezoeken. Dit komt door de manier waarop de Drupal core omgaat met sessions en cookies.

Deze module implementeert een andere manier voor Drupal om met cookies om te gaan, waardoor wél alle unieke gebruikers van je Drupal website te tracken zijn.

Voornamelijk voor marketing doeleinden kan deze informatie handig zijn.

Download (Drupal 7 & Drupal 8)

12. Serial field

Voeg een veld toe waarin de numerieke waarde automatisch oploopt, los van Drupal’s ‘node id’ autonummering. Dit kan handig zijn voor bijvoorbeeld factuurnummers. Dit veld kan gedeeld worden tussen verschillende content types; de waarden zullen uniek blijven, dwars door die content types heen.

Download (Drupal 7)

Wrap up

Alrighty, that's it voor nu. Volgende maand weer een aflevering van 'coole Drupal modules', so stay tuned!

May 27 2016
May 27

Easy Drupal Development with Drush ScriptingWhether you work on one Drupal site or multiple, it is often necessary for your local dev environment to be slightly different from your site's server.  Perhaps you need to disable Secure Pages because you don't want to set up SSL on your local environment, or there are modules specific to your website's server config.  If you work on multiple sites in a sporadic fashion its possible you need to synchronize your local database with the dev server between tasks, that way you aren't missing any updated configurations.

Sure, you can pull this off manually by grabbing the database, reloading your local, and updating your Drupal site's config; but why not add a little automation to help out?

Using a Shell Script with Drush

Recently I was setting up a local environment and had the opportunity to use a script created by Colan Schwartz. If you are running Linux or OSX then you can easily use this script and modify it to your own needs.  If you haven't done much shell scripting, or you use an alternative OS such as Windows, you may want to get a quick overview from howtogeek.com

Now that you're an expert on shell scripting you should check out Colan's very well documented script on gitlab. You may need to update the command path variables

# Set command paths.
DRUSH=/usr/local/bin/drush
GZIP=/bin/gzip
CUT=/usr/bin/cut
GREP=/bin/grep
ECHO=/bin/echo
DATE=/bin/date
SUDO=/usr/bin/sudo
CHOWN=/bin/chown
ID=/usr/bin/id
MKDIR=/bin/mkdir

Also, the default USER_WEB settings may be incorrect for you setup and your web server user is not one of: php-fpm, nginx, apache, or www-data.

The MODULES_DISABLE variable controls what modules are disabled on your local environment, and you can modify MODULES_ACQUIA and MODULES_ADVAGG with your own variables and module lists.  

If you'd like to test out the script make sure you have a backup of your code and databases.  Once you get the base settings adjusted for your setup, updating the settings for subsequent sites will be quite easy.  Running the script executes the following commands:

  1. Saves a cache-cleared dump of the destination database (DB) as a backup.
  2. Overwrites the destination DB with the source's.
  3. Updates the DB schema.
  4. Imports the latest configuration saved in code.
  5. Disables modules that shouldn't be enabled during development.
  6. Enables modules that are helpful for development.
  7. Clears all caches.
  8. Overwrites the destination's files directory with the source's.
  9. Runs cron.

I hope this helps your development workflow, if you were able to adjust the script for your specific setup please share your results.  Happy scripting!

Some additional items:

If all you need to do is rebuild your local dev environment then check out this cool project which turns the process into a simple drush command: Drush Rebuild.

Here are a few other scripts that you might find useful or inspirational:

May 26 2016
May 26

By Steve Burge 26 May 2016

How to Build a Drupal 7 Jobs Site

This new class, "How to Use the Bootstrap Framework", teaches you how to use the world's most popular design framework in the world.

Bootstrap is an HTML, CSS and Javascript framework that allows you to create clean-looking websites.

Bootstrap provides pre-built code that solves many of the tricky elements, such as responsiveness, that slow down web projects.

This class is the perfect introduction for anyone who wants to start using Bootstrap.

These videos will show you how to use Bootstrap's grid system, and responsive features. You'll also learn how to customize forms, menus, buttons and text.

Start a free trial!

Intro video for the Bootstrap Class

How to take the Bootstrap Class

If you're already an OSTraining member, you can click here to take the Bootstra Class.

Start a free trial!


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.


May 26 2016
May 26

At the end of 2012, Larry Garfield wrote a blog post entitled “Getting Off the Island in 2013,” in which he speculated that, in order to stay relevant, Drupal needed to adapt and become more open. My interpretation of the post was that although Drupal has always been open source, in many ways its community had been closed off, sometimes ignoring the larger web development community. Garfield’s post was poignant, even prophetic—that was four years ago. Today, Drupal 8 is gaining steam: it has incorporated many components of the Symfony framework and discussion about including a new, more robust, Javascript framework in core is a hot topic. Drupal is reinventing itself, and in doing so it’s securing its position as the go-to CMS.

That’s why when I saw the new Horizons track in the Drupalcon NOLA program this year, I was stoked. The creation of the interdisciplinary Horizons track represents a shift in the Drupal community towards supporting and adopting and learning from technologies that are changing the way we build websites. It’s a way for the community to “get off the island” and see what’s going on in other areas of our industry.

One of my favorite sessions in the Horizons track was “Amazing User Experiences with Drupal and Ember,” in which Ed Faulkner showed how the power of Ember.js with Drupal makes seemingly complex features very approachable. His live demos showed how with Ember.js a few lines of Javascript could create a user experience that feels like the future. Likewise, in “Elm - Frontend with Guarantees,” Amitai Burstein explained how the Elm language brings the benefits and predictability of functional programming to front-end development. If it compiles, it just works!

The best part of these sessions was that the presenters resisted the temptation to dogmatically bash Drupal, avoiding terms that have become low-grade insults like “monolithic” and “tightly coupled.” Instead, they showed that other frameworks, tools, and techniques can pick up the slack when Drupal falls short—Ember, React, Angular, Elm, and even GraphQL can have a place in the Drupal ecosystem.

Having worked with Drupal since 2010, I’ve had the opportunity to see it grow and evolve over the years. From my humble beginnings integrating with SOAP services (remember those?), to implementing complex SPAs (Single Page Applications) with Backbone.js and RESTful webservices with Node.js, my work with Drupal has always happened at the “messy edges,” as the DrupalCon program put it so aptly. But I’ve come to find that the most exciting work happens in the “messy edges”—When you begin pushing a piece of software to its limits, you know you’re building something exciting; it’s part of what makes web development interesting.

So, I have high hopes for the Drupal project. The Drupal community is self reflective enough to see the flaws in the project and brave enough to reinvent itself—we’ve seen that with Drupal 8. Is there work to be done? Yes. But based on the sessions I saw and the discussions I heard at DrupalCon, I believe this community has what it takes to not only survive, but thrive.

jam
May 26 2016
May 26
I sat down with Ally Gonthier the first time I visited Acquia's then-new downtown Boston headquarters in mid-2015. At the time, she was preparing to leave her job as Support Coordinator at Acquia to enter Acquia's Drupal/tech bootcamp, known as Acquia U. When I returned to Boston in the spring of 2016, I took the chance to talk with her again about her experiences at Acquia U and what had become of her in the meantime. Below is a transcript of our before and after conversations.
May 26 2016
May 26

Drupal 8.1.0 was released on April 20th. (Read the full release notes.) There are a few exciting things about this release. At the top, this is the first time Drupal has done a scheduled feature release using the new semantic versioning and pre-set release schedule. Instead of 8.1, we have 8.1.0, and we got the release out on schedule! (Learn more about the Drupal 8 release schedule and semantic versioning.) This feature release added some CKEditor WYSIWYG enhancements, added some APIs, an improved help page, and two new experimental modules: Migrate Drupal UI and BigPipe.

One of the big advantages to these 6-month feature releases is that we can add new things to Drupal core over time instead of having to wait for the next big version. This means Drupal core will change more over its life than previous versions. One of the downsides of this is that documentation and learning materials may get out of date more quickly. We’re excited about the possibilities of Drupal 8 releases and we’re dedicated to having the most up-to-date and accurate tutorials you can find. To keep on top of things, we are reviewing all of the Drupal 8 releases to see where our tutorials need to be updated, and we’re making sure we stay involved in the core issues and processes so we are aware of big changes that may be coming. This is the most exciting release cycle Drupal has ever had, and we’re loving the energy and the challenge of keeping up with it toe-to-toe. So without further ado, here is a brief summary of the big changes in 8.1.0 and a look ahead at some things that might be coming down the road.

BigPipe

The Drupal 8 BigPipe module provides an advanced implementation of Facebook's BigPipe page rendering strategy, leading to greatly improved perceived performance for pages with dynamic, personalized, or un-cacheable content. This is a huge win for Drupal 8, and will make your sites load super fast. You can see the difference it makes in a short demo video on the BigPipe documentation page. The work on this has been happening for over a year and while it didn’t get into the initial 8.0.0 release, it’s very exciting to see this in Drupal core now. For an in-depth look at BigPipe in Drupal, watch the DrupalCon New Orleans BigPipe session video.

Migrate

The other big feature in Drupal 8.1.0 is improvements to the migration system, which is how we handle upgrades now. There is now a user interface for running migrations, which was a sorely missing feature. (Though, do keep in mind that more migration improvements need to be made.) There has been a lot of work in this space and we’ve been working on upgrade/migration tutorials for a few months. Part of our delay was the tricky space that the migration in core was in, which made it difficult to ensure we had the most accurate tutorials for coming versions of Drupal core. With the 8.1.0 release knocking we decided to push things along by funding Mike Ryan (creator of Migrate module) to make migrations more solid for 8.1.0, and dedicating some of our own Will Hetherington’s time to assist in the effort.

Specifically, we had Mike spend his time making sure the final core migrate issues for 8.1.0 got guided in, and working to get the Migrate Tools and Migrate Plus contributed modules working well with the new release. This is particularly important since not having these two projects functional would severely limit the usefulness of the Migrate work in core.

Aside from the actual code work that Mike cranked out, we also go 2 great blog posts; one by Mike, Migration update for Drupal 8.1, and the other by Will, Custom Drupal-to-Drupal Migrations with Migrate Tools.

You can also see the fruits of our labor on the Migrate front with the first of several parts for our new Drupal 8 Migration Guide, led by Will.

Drupal 8.2.0

We had our first successful feature release, and 8.2.0 is scheduled for October 2016. It remains to be seen what lands in that release, but we are keeping an eye on important developments. Of course, there is also still room for more improvements to Migrate and so we plan to keep working in the migration space over the coming months. One of the new, interesting things to watch is a project to simplify the theme and render system by using a component library. It's still very much in the planning phase, so we have no idea if it can even possibly make it in to the next version yet. (Here is the main issue on Drupal.org if you want to follow along.) We’re particularly interested here at Drupalize.Me because we have an extensive Theming Guide published and this would definitely be something where we’d need to update our previously published tutorials. Rest assured we’re keeping our finger on the pulse.

May 26 2016
May 26

By Steve Burge 26 May 2016

How to Build a Drupal 7 Jobs Site

This week, we're happy to add a new and much-requested class to the OSTraining library, How to Use the Twig Template Engine.

Twig is a very powerful template engine for PHP. Twig is safe, fast, easy-to-learn and is used by many different platforms. Drupal 8 uses Twig by default, plus we've also come across wonderful examples of Twig being used in WordPress and Joomla.

In this class, you'll learn how to use Twig for your projects.

In the first half of the class, you'll see how to install and configure Twig. You'll then explore Twig's syntax, including filters, comments, math operators and more.

In the second half of the class, you use if/else statements, includes statements and extensions to create powerful and flexible layouts.

Start a free trial!

Intro Video for the Twig Class

How to take the Twig Class

If you're already an OSTraining member, you can click here to take the Twig Class.

Start a free trial!


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.


May 26 2016
May 26

How to Register an Event Subscriber in Drupal 8Events in Drupal 8 allow for different components of the system to interact and communicate with each other. One system component dispatches the event at an appropriate time; many events are dispatched by Drupal core and the Symfony framework in every request. Other system components can register as event subscribers; when an event is dispatched, a method is called on each registered subscriber, allowing each one to react.

Most of the hooks from previous versions of Drupal were removed in Drupal 8 in favor of Events. Example: hook_init() or hook_boot() which now can be done by registering an event subscriber.

I will use the following structure for the example module:

my_event_subscriber/
  - my_event_subscriber.info.yml
  - my_event_subscriber.services.yml
  - src/
    - EventSubscriber/
      - MyEventSubscriber.php

Standard my_event_subscriber.info.yml file for the module:

name: Register an Event Subscriber
type: module
description: 'Example: How to Register an Event Subscriber in Drupal 8'
core: 8.x
package: Other

Define a service tagged with 'event_subscriber' in the my_event_subscriber.services.yml.

services:
  my_event_subscriber:
    class: '\Drupal\my_event_subscriber\EventSubscriber\MyEventSubscriber'
    tags:
      - { name: 'event_subscriber' }

src/EventSubscriber/MyEventSubscriber.php contains a class that implements \Symfony\Component\EventDispatcher\EventSubscriberInterface

/**
 * @file
 * Contains \Drupal\my_event_subscriber\EventSubscriber\MyEventSubscriber.
 */

namespace Drupal\my_event_subscriber\EventSubscriber;

use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Event Subscriber MyEventSubscriber.
 */
class MyEventSubscriber implements EventSubscriberInterface {

  /**
   * Code that should be triggered on event specified 
   */
  public function onRespond(FilterResponseEvent $event) {
    // The RESPONSE event occurs once a response was created for replying to a request.
    // For example you could override or add extra HTTP headers in here
    $response = $event->getResponse();
    $response->headers->set('X-Custom-Header', 'MyValue');
  }

  /**
   * [email protected]}
   */
  public static function getSubscribedEvents() {
    // For this example I am using KernelEvents constants (see below a full list).
    $events[KernelEvents::RESPONSE][] = ['onRespond'];
    return $events;
  }

}

Here is a list of KernelEvents constants:

KernelEvents::CONTROLLER; // The CONTROLLER event occurs once a controller was found for handling a request.
KernelEvents::EXCEPTION; // The EXCEPTION event occurs when an uncaught exception appears.
KernelEvents::FINISH_REQUEST; //The FINISH_REQUEST event occurs when a response was generated for a request.
KernelEvents::REQUEST; // The REQUEST event occurs at the very beginning of request dispatching.
KernelEvents::RESPONSE; // The RESPONSE event occurs once a response was created for replying to a request.
KernelEvents::TERMINATE; // The TERMINATE event occurs once a response was sent.
KernelEvents::VIEW; // The VIEW event occurs when the return value of a controller is not a Response instance.

There are more events available. More event constants.

How to dispatch an event

$dispatcher = \Drupal::service('event_dispatcher');
$dispatcher->dispatch($Event_Name, $Optional_Event_Object);

Useful links

May 26 2016
May 26
When you spin up sites for a living, velocity is important. The developers at Acquia understand this, which is why we’re always looking for ways to make website development simpler and easier. Because that equals faster.Many of our customers are already using these tools and practices. But we’d like to spread the word further.We know you’re facing really challenging situations. We’ve got tools that will help you get past them, without taking up an entire afternoon. We can speed you up, and speed up your team.
May 26 2016
May 26

Most people think that using the drush command-line tool is only something hardcore developers do, but it turns out it's also super-helpful for site builders and theme developers too! In my experience, using drush will speed up from 3 to 10 times usual Drupal Admin tasks, compared with visiting the Drupal admin pages in the browser. 

In this article, I'll list the Drush commands I use everyday in my Drupal theme development and site-building process. If you have more of them on your pocket, I will appreciate you comment them as I would love to add them to the list.

As a requirement for executing all of the following commands, you must first ensure to have Drush installed for your Drupal development environment. Fortunately, Acquia Dev Desktop and Pantheon.io, Drupal VM, and standard dev environments all come with drush pre-installed.

Without further ado, let's dive into my favourite commands, with both D7 and D8 versions where appropriate.

Clear the Caches

Whether you are loading new template files, adding new libraries or editing your main theme .info file's structure, you will always need a fast Cache clear.

Drupal 7

# run cache-clear on all caches
$ drush cc all

Drupal 8

# run cache-rebuild
$ drush cr

In my personal experience, you may need to clear Drupal Caches between 5 - 15 times a day.

Download and enable any contrib module

With more than 13.000+ Drupal 7 & 8 contrib modules at Drupal.org, that odds are that you're not using one of them are pretty slim! Fortunately, drush makes installing modules from Drupal.org can be done really fast thanks to Drush using the following commands:

Drupal 7 & 8

# Download a module
$ drush dl pathauto

# Enable the module
$ drush en pathauto

Because smart themers are also lazy, they'll be happy to hear that you can do both the download and enabling in a single command:

$ drush en pathauto -y

Keep in mind, every drush command accepts a "-y" argument to skip all yes/no confirmations.

Import & Export Database Backups

The fastest way to backup all your site data is doing a database dump. As a good practice, always clear the caches first, to keep the size of the database "dump file" to a minimum. Depending on the site structure and data, this diference can result in up to a 70% reduction on the SQL dump file size.

Drupal 7 & 8

# Export the DB to a backup file
$ drush cc
$ drush sql-dump > dump.sql

# Delete all data in your database (MAKE SURE YOU TRUST YOUR BACKUP!)
$ drush sql-drop

# Import the DB from a backup file
$ drush sql-cli < dump.sql

Import & Export Site Configuration to Code

Until a site goes live, we do our best to develop without a database dump (Gasp!). When building a new dev or staging environment, we start from an empty databse, and migrate in all our sample content. Then we use either Features module (in Drupal 7) or Configuration Management (in Drupal 8) to import ALL site configuration (content types, fields, views, variables, and everything else) from the code. Here's how drush plays a role:

Drupal 7, using Features module

# Assuming you use Features site wide for Content Types, Contexts, Views...
# Revert all enabled features by overriding current DB config with the features code
$ drush features-revert-all

# Update all feature modules code based on your current DB config
$ drush features-update-all

Drupal 8, using Configuration Management

# Export the configuration to the "config/site" sample folder
$ drush config-export --destination=config/site

# Import the configuration from the "config/site" sample folder
$ drush config-import --source=config/site

Downloading and Enabling the Drupal Theme

As with a module, you could manually visit Drupal.org, downloading the theme, extract it to to the appropiate folder, then visit "Admin > Appearance" to set it. But after you see how easy it is with drush, you'll never do it any other way.

Drupal 7

# Download a theme/module
$ drush dl bootstrap

# Enable the theme/module
$ drush en bootstrap

# List all Installed Themes
$ drush pm-list --type=theme

# Set the theme to be the "default one" or the "admin one"
$ drush vset theme_default bootstrap
$ drush vset admin_theme seven

Drupal 8

# Download a theme/module
$ drush dl bootstrap

# Enable the theme/module
$ drush en bootstrap

# List all Installed Themes
$ drush pm-list --type=theme

# Set the theme to be the "default one" or the "admin one"
$ drush config-set system.theme default bootstrap
$ drush config-set system.theme admin bootstrap

Update Drupal Core + Contrib Modules

Always keeping core and contrib modules up-to-date is the most tedious admin task I know. Turns out that drush has a single command that does everything for you! As a bonus, there's a second command that does a full site archive (code, database, and files) that you can restore from if anything goes wrong!

Drupal 7 & 8

# Export the DB, code, and site into a timestamped and zipped tar archive 
$ drush archive-dump

# Run the entire update process
$ drush up

Generate Sample Content

As described by Blair Wadman in his blog post How to create dummy Drupal content with Drush and Devel, we can create a bunch of dummy nodes to test our Views, Display Modes and see the actual layout in action.

Drupal 7 & 8

# Download and Enable Devel module
$ drush en devel -y

# Enable Devel Generate Sub-module
$ drush en devel_generate -y

# Generate 50 random nodes, with up to 10 comments each
$ drush generate-content 50 10

Other Drush Capabilities...

As mentioned before, these are kind of the most popular Drush commands I use every day, but there's so much more to explore in the following resources:

Gratuitious terrible jokes

Finally, I learned that my colleage Alex Dergachev once did an intro Drush talk at a Drupalcamp Montreal 2010, where he organized his slides around sinister-sounding "Soviet drussia" jokes. We're including these here for posterity.

In Soviet Drussia...

  • Dog watches you
  • Cron executes you
  • Variable gets you
  • PHP evaluates you
  • Core hacks you
  • Module uninstalls you
  • Caches clear you
  • Content manages you
  • Terrible joke ruins you

Let us know if he missed any stinkers.

May 26 2016
May 26

Drupal 7 and below came with an optional module you can use in your input formats - the "PHP Filter". This allows you to put PHP code into the content of your webpages, and Drupal will process the PHP before rendering the page.

PHP Filter - a Bad Idea ™

Put like that, you're probably wondering why on earth anyone would want to do that. The content of a webpage, in a Content Management System (which is how Drupal is often used) should be just that - the content. Only in a manually coded site would you put the website logic (the server-side PHP) in the same place as your content.

Well, precisely. And there are other reasons why it's a bad idea.

1. Security. Any PHP code in a module can be run through various automated or manual checks to make sure you've written good, secure code. Maybe even your webserver runs tools that scan for possible signs of malware. PHP code in your content is buried deep in the database, where it won't get checked.

2. Debugging. If you find a page of your site is not working as it should, you need to identify where things go wrong. It makes the job a lot more complicated if there's PHP code in page content, as well as in the other places where it ought to be.

PHP Filter - a Commonly Used Feature

In spite of this, it's very common for people to use the input filter. Classically, when someone knows some PHP, but is just beginning to learn Drupal, they find some logic they want in their website that they can't work out how to do it. At least, they can't work out the "Drupal way" to do it. So they go for the obvious work-around - put the logic into the Body of whatever page they're creating.

But, eventually, you learn better ways of doing things, and you learn just why the PHP filter is a bad idea, so you want to disable it on your site. Before disabling the "PHP filter" module, you need to make sure that none of your current website content uses it. How do you go about this?

You need to run some database queries to make sure you've caught them all.

Step 1: Find the input formats that use the PHP filter

The PHP Filter is simply one formatter that you can use in an "Input Format" (like "Filtered HTML" and so on). Most people would only enable the PHP Filter in a single text format that they have created especially for this task, maybe named something like "PHP Code". But don't bet on it. Some sites may have enabled the PHP Filter on other Text Formats as well.

SELECT * FROM `filter` WHERE module = 'php' and status = 1

(Note - if you're using a prefix for your tables, you'd obviously need to prefix the table name 'filter'. If you use prefixes, you'll know what I mean, so I'm only going to point this out once in this post.)

This will show you all the input formats that use the PHP filter. In my case, I only had one, and it was Input Format number '2' (look in the 'format' column of what this query spits out.)

Step 2: Find all nodes that use those input formats

We now need to find all nodes that use this input format.

SELECT * FROM `field_data_body` WHERE body_format = 2

or, if you are checking for multiple input formats:

SELECT * FROM `field_data_body` WHERE body_format IN (2, 5)

This will show you all the nodes in your site that use those input formats.

Look at the 'entity_id' column. That will tell you the node ID of each node.

Step 3: Fix those nodes so that they don't use the PHP Filter

Now you need to go to each of those nodes in turn and fix them. They need to be on a different Text Format, one that doesn't use the PHP Filter at all. To load each node, go to yoursite.com/node/nnnn, where nnnn is the node ID you just found in the database.

How to get rid of the PHP from the node will depend on why you originally used the PHP code.

It may be that you aren't even using PHP in some nodes, and you can just change the Text Format to a different one, check it still looks OK, and move on to the next node. Or it may be that your PHP use was so simple you can do without it. Sometimes, you may need a module from Drupal's contrib repository, or even a custom-coded module. That's beyond the scope of this guide.

Step 4: Don't forget blocks

Oh yes.

It's just possible (:cough:) that you might have added a custom block to your site, and put some PHP code in there as well.

SELECT * FROM `block_custom` WHERE format = 2

From the results of that query, you can probably find the block in the Blocks Administration screen of your Drupal site.

But, in case you have a lot of blocks, the 'bid' column gives you the block identifier. You can load this page: yoursite.com/admin/structure/block/manage/block/[bid]/configure, where [bid] is the block identifier you got from your query.

Step 5: Tidy up

That's it. You can now edit the text formats which had the PHP filter in, to either delete them or disable the PHP filter. Then you can disable the PHP Filter module from your site.

Have I missed anything? Are there other common places where PHP code might lurk in the database? Please plug any gaps in the comments section below.

May 26 2016
May 26

What do you get when you put two Project Managers in one hotel room for a week at DrupalCon? A lot of work, a lot of laughter, and a lot of learning. Don’t worry, we didn’t kill each other… yet.

With our days spent in sessions and nights spent on Bourbon Street or answering client emails (not at the same time), DrupalCon New Orleans was a truly illuminating experience. I came to LevelTen a year ago not even knowing what “Drupal” was -- and in the past year I have truly come to understand the power behind the Drupal platform and the community.

My Three Big Takeaways from DrupalCon 2016:

  1. You are not alone in your frustrations.

  2. You don’t know what you don’t know.

  3. Knowledge is power.

You are not alone in your frustrations.

From a Project Management standpoint, this was incredibly helpful to understand: someone else has been through exactly what you’ve been through -- and they didn’t die, either.

In On Inheriting Someone Else's Mess: Lessons Learned from a Rescue Project, Marcus Iannozzi from Message Agency explored the difficulties of taking on someone else’s project. I particularly related to his concept of “wounded trust”: when a client who has had a bad experience worries, not only that you won’t deliver, but that you are actively trying to take advantage of them. Sound familiar? From an inside sales perspective, I deal with this often.

Perhaps the most illuminating part of this session actually came from the Q&A portion. Someone asked if, knowing what he knows now, Marcus would take on this project again. Without hesitation, he said “No.”

Takeaway: Hindsight is always 20/20.

In Becoming a TPM: Dos and Don'ts of Technical Project Management, Jessi Fischer (Pantheon) and Anne Stefanyk (Kanopi Studios) showed an impressive display of cat GIFs as the basis of a comparison of Technical Project Management to herding cats. They discussed that the key to good TPM is to communicate effectively with a non-technical audience and employ strategies for risk mitigation. Don’t leave your developers out to dry, and take responsibility for the team as a whole.

Takeaway: When you put cats in a presentation, I am 1000% more likely to pay attention.

In How To Grow Support To Become A Cornerstone Of Your Business, John Ouellet and Katy Pool from Kalamuna touched on both good and bad clients, while also discussing how to structure support contracts to function as a lead-in to larger projects. Have a tough client? They suggest either learning how to say no, implementing another team member as the PM, or parting ways with the client.

Takeaway: The dreaded “support” contract can be beneficial for your business if you have the right team and the right framework.

You don’t know what you don’t know [and I didn’t know any of this].

In a BoF covering Event Organization & Sponsorship called “Mo Money, Mo Sponsors,” focusing particularly Drupal and other tech Camps, representatives from Pantheon, Acquia, and FFW seemed to agree on one thing: if you want to get your camp sponsored, you need data. This includes who will be attending your event and their demographics, but also a marketing plan that covers how you will be attracting new people to your camp.

Takeaway: Pantheon doesn’t care if you put their name on a shirt or a poster. Offering face time with potential clients or new hires is one of the most valuable things you can offer.

In Recruiting and Retaining Dedicated Volunteers, Stephanie from Amazee Labs covered how to find, train, and retain a great volunteer staff. She made a great Stone Soup analogy that boiled down to this: individually, people may not have much to give as far as talents, availability, or interest, but if you maximize on their desire for something great, you can create it.

Takeaway: Offload enough responsibility on your volunteers so that you can jump in if something goes wrong without causing something else to break.

Knowledge is power.

In GE Energy Connections & FFW: Delivering Business Results Beyond Clicks, Conversions and Revenue, Brent Bice (Agency) and Holly Bounds (Client) teamed up to offer both agency and client perspectives on moving to Drupal. Holly was gracious enough to speak with me for a few minutes afterwards from a sales point-of-view on how they were convinced to move to Drupal and to work with FFW. She mentioned that one of the big pieces that FFW was able to offer was knowledge: for example, teaching her the difference between a configuration and a customization allowed her to prioritize what they needed and cut costs where configurations were sufficient.

Takeaway: The modern client wants to feel empowered, even if you’re doing all the work. Taking the time to teach them certain things can have a large ROI.

My first year at DrupalCon was one for the books -- and not just because of the Pantheon party, or the beignets, or getting soaked in the rain with my teammates. Connecting with hundreds of like-minded people in person really reinforced the community foundations of Drupal for me, and helped me to better understand both the current state of Drupal shops, and the opportunities that we have to grow and change in the future.

Check out the rest of our DrupalCon[densed] 2106 series! No matter who you are, we've got your perspective covered.

May 26 2016
May 26

Raspberry Pi Dramble Cluster with Mini Raspberry Pi Zero Cluster

Another year, another field trip for the Pi Dramble—my 5-Raspberry-Pi cluster! I presented a session titled Highly available Drupal on a Raspberry Pi Cluster at php[tek] 2016, which just so happens to have moved to my hometown, St. Louis, MO this year!

For this presentation, I remembered to record the audio using a lav mic plugged into my iPhone, as well as iShowU to record what was on my screen. Sadly, I didn't have a secondary camera to capture the Pi Dramble itself, but you can glance at all the other 'Let's build a Pi Cluster' videos if you want to see it in action!

Here's a video recording of the presentation:

[embedded content]

And here are the slides:

If you haven't yet seen the Dramble, check out all the details at http://www.pidramble.com/.

It was a fun and lively session, and I thank the php[tek] organizers for allowing me to share my passion for electronics, Ansible, PHP, and Drupal with another great group of people. I'll be giving another talk tomorrow, on a completely unrelated topic, ProTips for Staying Sane while Working from Home.

May 26 2016
May 26

XHProf is a profiling tool for PHP code – it tracks the amount of time and memory your code spends in each function call, allowing you to spot bottlenecks in the code and identify where it’s worth spending resources on optimization. There are have been a number of PHP profilers over the years, and XDebug has a profiler as well, but XHProf is the first one I’ve successfully managed to configure correctly and interpret the output of.

I had run across a number of blog posts about using XHProf + Drupal, but never actually got it to work sucessfully for a project. Because so much of the documentation online is incomplete or out-of-date, I thought it would be useful to document my process using XHProf to profile a Drupal 8 custom module here. YMMV, but please post your thoughts/experiences in the comments!

How to find documentation

I find the php.net XHProf manual entry super-confusing and circular. Part of the problem is that Facebook’s original documentation for the library has since been removed from the internet and is only accessible via the WayBack Machine.

If there’s only one thing you take away from this blog post, let it be: read and bookmark the WayBack machine view of the original XHProf documentation, which is at http://web.archive.org/web/20110514095512/http://mirror.facebook.net/facebook/xhprof/doc.html.

Install XHProf in a VM

If you’re not running DrupalVM, you’ll need to install XHProf manually via PECL. On DrupalVM, XHProf is already installed and you can skip to the next step.

sudo pecl install xhprof-beta

Note that all these commands are for Ubuntu flavors of linux. If you’re on Red Hat / CentOS you’ll want to use the yum equivalents. I had to first install the php5-dev package to get PECL working properly:

sudo apt-get update
sudo apt-get install php5-dev

And, if you want to view nice callgraph trees like the one below you’ll need to install the graphviz package sudo apt-get install graphviz

Image of a sample XHProf callgraph

Configure PHP to run XHProf

You need to tell PHP to enable the xhprof extension via your php.ini files. Usually these are in /etc/php5/apache2/php.ini and /etc/php5/cli/php.ini. Add the following lines to the bottom of each file if they’re not there already. You will also need to create the /var/tmp/xhprof directory if it doesn’t already exist.

[xhprof]
extension=xhprof.so
;
; directory used by default implementation of the iXHProfRuns
; interface (namely, the XHProfRuns_Default class) for storing
; XHProf runs.
;
xhprof.output_dir="/var/tmp/xhprof"

Lastly, restart Apache so that the PHP config changes take effect.

Set up a path to view the XHProf GUI

The XHProf GUI runs off a set of HTML files in the xhprof_html directory. If you’ve been following the install steps above, you should be able to find that directory at /usr/share/php/xhprof_html. Now you need to set up your virtual host configuration to serve the files in the xhprof_html directory.

I find the easiest way to do this is just to symlink the xhprof_html directory into the existing webroot of whatever site you’re working on locally, for example:

ln -s /usr/share/php/xhprof_html /var/www/my-website-dir/xhprof

If you’re using DrupalVM, a separate vhost configuration will already be set up for XHProf, and the default URL is http://xhprof.drupalvm.dev/ although it can be changed in your config.yml file.

Hooking XHProf into your module code

Generally, the process of profiling a chunk of code using XHProf goes as follows:

  1. Call xhprof_enable()
  2. Run the code you want profiled
  3. Once the code has finished running, call xhprof_disable(). That function will return the profiler data, which you can either display to the screen (not recommended), or…
  4. Store the profiler data to a file by creating a new XHProfRuns_Default(); object and calling its save_run method.

In the case below, I’m profiling a module that implements a few Drush commands from the command line which I’d like to optimize. So I created _modulename_xhprof_enable() and _modulename_xhprof_disable() functions – the names don’t matter here – and then added a --profile flag to my Drush command options which, when it is set to true, calls my custom enable/disable functions before and after the Drush command runs.

Here’s what those look like in full:

<?php
/**
 * Helper function to enable xhprof.
 */
function _mymodule_enable_xhprof() {
  if (function_exists('xhprof_enable')) {
    // Tell XHProf to track both CPU time and memory usage
    xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY,
      array(
        // Don't treat these functions as separate function callss
        // in the results.
        'ignored_functions' => array('call_user_func',
          'call_user_func_array',
        ),
      ));
  }
}

/**
 * Helper function to disable xhprof and save logs.
 */
function _mymodule_disable_xhprof() {
  if (function_exists('xhprof_enable')) {
    $xhprof_data = xhprof_disable();

    //
    // Saving the XHProf run
    // using the default implementation of iXHProfRuns.
    //
    include_once "/usr/share/php/xhprof_lib/utils/xhprof_lib.php";
    include_once "/usr/share/php/xhprof_lib/utils/xhprof_runs.php";

    $xhprof_runs = new XHProfRuns_Default();

    // Save the run under a namespace "xhprof_foo".
    //
    // **NOTE**:
    // By default save_run() will automatically generate a unique
    // run id for you. [You can override that behavior by passing
    // a run id (optional arg) to the save_run() method instead.]
    // .
    $run_id = $xhprof_runs->save_run($xhprof_data, 'xhprof_mymodule');

    echo "---------------\nAssuming you have set up the http based UI for \nXHProf at some address, you can view run at \nhttp://mywebsiteurl.dev/xhprof/index.php?run=$run_id&source=xhprof_mymodule\n---------------\n";
  }
}

The echo command here works fine for a Drush command, but for other tasks you could log the run url using watchdog.

Note: Another way to run XHProf on a Drupal site is using the XHProf module, but I haven’t had great luck with that.

Viewing profiler results

If everything is configured correctly, when you run your module you should get a run ID output either to the screen (via echo, as above, or however you’ve configured this logging). Visit the URL you configured above for xhprof, and you should see a list of all the stored runs. Clicking on a run will bring up the full profiler report.

Sample screenshot of an XHProf profiler report

Now what?

Now you’ve got all this data – how to make sense of it? What to do with it? Stay tuned for more discussion of how to interpret XHProf results and a real-world example of profiling a D8 module, next week!

About the author

Tim Stallmann

Recent posts by Savas

May 20, 2016

The ins and outs of the talks, sessions, parties, and more from Drupalcon New Orleans 2016.

Apr 20, 2016

A peek under the hood at our website’s commenting app, Squabble.

Mar 22, 2016

Savas Labs will host 4 lightning talks at the American Underground @Main for the next TriDUG meetup.

May 25 2016
May 25

The Aaron Winborn Award was created in 2015 after the loss of one of one of the Drupal community’s most prominent members, Aaron Winborn, to Amyotrophic Lateral Sclerosis (also referred to as Lou Gehrig's Disease in the US and Motor Neuron Disease in the UK). Aaron’s commitment to the Drupal project and community made him the epitome of our unofficial motto: "Come for the code, stay for the community". The Community Working Group with the support of the Drupal Association came together to honor Aaron's memory by establishing the Aaron Winborn Award, which annually recognizes an individual who demonstrates personal integrity, kindness, and above-and-beyond commitment to the Drupal community.

Nominations were opened in March, giving community members the opportunity to nominate people they believe deserve the award, which were then voted on by the members of the Community Working Group, along with previous winners of the award.

We are pleased to announce that the 2016 recipient of the Aaron Winborn Award is Gábor Hojtsy. During the closing session of DrupalCon New Orleans, Community Working Group members presented the award to Gábor. The award was accompanied by a free ticket to DrupalCon, which he donated to Bojhan Somers.

Gábor was described in his nomination as an "amazing community connector" who is passionate about empowering others, stepping aside and allowing others the space and support to lead, and celebrating even the small wins that people who work with him achieve. The stellar work and leadership he displayed on the D8 Multilingual Initiative, managing sprints, Drupal events and setting up localize.drupal.org are just a few of the ways that this tireless Drupal contributor has been making an enormous impact in our community for more than a decade.

We hope you will join us in congratulating Gábor, who has demonstrated personal integrity, kindness, and above-and-beyond commitment to the Drupal community in abundance.

May 25 2016
May 25

[embedded content]

At this month's Sydney Drupal meet up I did a presentation about Search in Drupal 8. In the video, I explain three ways you can create a search page, they are as follows.

1. Core Search

The core Search module which comes with Drupal has some new functionality in Drupal 8. The biggest change is the ability to create custom search pages without using any other module.

2. Views Filter

A common way to build search pages in Drupal 7 was to create a views page and use the "Search Keywords" filter in views. This can still be done in Drupal 8 and best of all Views is now part of core.

3. Search API

The Search API module is used to create powerful search pages and it's highly extensible. It is the module to learn and use for building search pages.

I hope this presentation helps and that you enjoy the video.

Like what you see?

Join our free email list and receive the following:

  1. Discover our best tutorials in a 6 part series
  2. Be notified when free content is published
  3. Receive our monthly newsletter
May 25 2016
May 25

by David Snopek on May 25, 2016 - 11:26am

As you may know, Drupal 6 has reached End-of-Life (EOL) which means the Drupal Security Team is no longer doing Security Advisories or working on security patches for Drupal 6 core or contrib modules - but the Drupal 6 LTS vendors are and we're one of them!

Today, there is a Moderately Critical security release for XML sitemap to fix a Cross-Site Scripting (XSS) vulnerability.

The module doesn't sufficiently filter the URL when it is displayed in the sitemap.

This vulnerability is mitigated if the setting for "Include a stylesheet in the sitemaps for humans." on the module's administration settings page is not enabled (the default is enabled).

Download the patch for XML Sitemap 6.x-2.x (also works with 6.x-2.1, the latest release), 6.x-1.x or 6.x-1.2.

If you have a Drupal 6 site using the XML sitemap, we recommend you update immediately! We have already deployed the patch for all of our Drupal 6 Long-Term Support clients. :-)

If you'd like all your Drupal 6 modules to receive security updates and have the fixes deployed the same day they're released, please check out our D6LTS plans.

Note: if you use the myDropWizard module (totally free!), you'll be alerted to these and any future security updates, and will be able to use drush to install them (even though they won't necessarily have a release on Drupal.org).

May 25 2016
May 25
It's my pleasure to introduce Acquia Bolt, a development tool for generating new Drupal projects using a template derived from our Professional Services' best practices.We began building and using Bolt internally over the past year. Our goal was to codify a set of tools and conventions that would allow us to:
May 25 2016
May 25
It's my pleasure to introduce Acquia BLT, a development tool for generating new Drupal projects using a template derived from our Professional Services' best practices.We began building and using BLT internally over the past year. Our goal was to codify a set of tools and conventions that would allow us to:
May 25 2016
May 25

Dropcast: Episode 20 - Kind of a big deal

This episode we hit a land mark of twenty episodes, so instead of picking on Mario the entire time, we talk about our favorite moments at Drupalcon in New Orleans. Of course this is funny since half of us didn't actually attend the 'Con. Other episode titles considered: "Bob and Mario live vicariously through Mark and Ryan"


Episode 20 Audio Download Link

Updates:

Mediacurrent Blog Mentions:

Topic Drupalcon Moments Mark:

Topic Drupalcon Moments Ryan:

Topic Drupalcon Moments Mario:

Topic Drupalcon Moments Bob:

Pro Project Pick:

Drupal News:

The Final Bell:

May 25 2016
May 25

Other than a quick sample of blocking a specific file extension using the 'nomask' option, the documenttation for Drupal's file_scan_directory() does not help much with how to bock content from certain directories.  The documentation says

The preg_match() regular expression of the files to ignore.'

So it leaves you to believe that any regex should work.   So setting

$options['nomask'] = "#(/deleted/)#"

should block any directory named 'deleted'.  The problem is, it doesn't work that way.   In file_scan_directory() the regex is not run against the full path of the file, it is only run against the directory or filename recursively.  It is not evaluating  'directory1/subsection/deleted/index.html' , where the regex above would definitely come back with a hit and reject the item.  It is first evaluating, 'directory', then 'subsection', then 'deleted'...   It does not get a hit on deleted because it is missing the slashes on each side.

One possibilty would be to remove the slashes from the regex like this:

$options['nomask'] = "#(deleted)#";

But without the slashes, it would not only reject the directory 'deleted', it would reject the directory 'not-deleted'  and the file 'faq-why-my-account-was-deleted.htm' which might have undesired consequences.

The trick to get it to reject only 'deleted' as a directory and its contents is to restrict the regex to only the start and end of the string being evaluated. like this

$options['nomask'] = "#^(deleted)$#";

and if you wanted to block 'deleted' and another directory like '_vti_cnf' it would look like this:

$options['nomask'] = "#^(deleted|_vti_cnf)$#";

May 25 2016
May 25

While I have had the privilege of attending a number of DrupalCons and camps over the years, I cannot remember one with as many sessions and BOFs (birds of a feather) on the topic of security. In addition to the security talk on the program schedule, I had a great time chatting with individuals in the hallways and a few security focused companies in the exhibit hall. 

I wasn't able to attend all of the sessions and BOFs mentioned below, but I want to highlight my favorite takeaways from the ones I worked into my schedule.

Simplifying Security: Protecting your Clients and your Company covered some common security myths that will surprise many technical and non-technical alike. Make sure to catch the video of the session.

Watch the Hacker Hack dives into the mind of a hacker and how it isn't like the movies. Spoiler alert: The end results can be just as dire for your website and associated data. The session was interactive with video examples of the hacker(s) in action. I plan to watch this session on video again as it was full of interesting details.

Data Security in Drupal 8 was a BOF led by Rick Hawkins. Rick talked about a number of security improvements in Drupal 8.

There was also a lively discussion about data encryption techniques and challenges with securely storing encryption and API keys.

Meet with Security Team Members and Ask Security Questions was led by Michael Hess and other members of the Drupal security team. This BOF was a great reminder that there are still so many ways to get involved in the Drupal community. The article How to join the Drupal Security Team has lots of details on getting involved. Even if you don't want to join security team, the last section of the same page, "Improve Drupal's security from outside the team," is pure gold. So many ways to get involved. The BOF attendees asked questions and discussed Drupal security team processes and how the team dealt with Drupageddon and other security incidents.

It is great to see the awareness of security rising in the community as Drupal continues to drive more enterprise websites and applications. I think that all of the Drupal and related hosting infrastructure best practice discussions will help enterprise and non-enterprise install bases. This kind sharing is one of the many things I love about being part of an open source community.

Security-related sessions and BOFs I didn’t attend

In summary

The number of sessions and interest in security at Drupalcon confirmed to me that attendees realize security is no longer a checkbox within a list of requirements. Security should be an ongoing part of any software development process, just as we do with UX, digital strategy, content architecture, etc. I am looking forward to taking what I have learned to continue educating our clients and the Drupal community on the importance of protecting websites and applications. 

Additional Resources
Highlights from Drupalcon New Orleans | Mediacurrent Blog Post  
The Real Value of Drupalcon | Mediacurrent Blog Post    
How to Prepare Your Team for Drupal 8 | Mediacurrent eBook 

May 25 2016
May 25

Your company’s business development team just announced a new Drupal project has been given the green light, and you will be the project manager. What do you need to do to help your development and strategy teams succeed in giving the client the best possible experience and product? You need to ask the right questions.

3 questions to ask regardless of the CMS in play

The project manager of any technical project, leveraging Drupal or some other CMS, should first and foremost ask:

1. Where is the Statement of Work (SOW) and how do I access it?

The SOW should:

  • lay out the scope of the project, including functionality, travel and training expectations;
  • provide you with a start and expected end date;
  • tell you the budget;
  • explain the agreed upon change order process to handle any new requirements that may come up during the project.

PM Tip: Tap into the knowledge of those who came before you!

In addition to the written knowledge in the SOW, don’t forget to speak to the business development team about their interactions with the client. Did the client mention any pain points? Does the anticipated launch date correspond with a business need and is therefore a “must have” instead of a “nice to have?” Any insight into the personalities of the various stakeholders? And remember to talk to your fellow PMs too– have they worked on similar projects or with similar clients?

2. What project management methodology are you using for this project - Agile, Waterfall or something in between?

If you use Agile, your project plan will need to account for the collaborative nature of the project – expect more back and forth discussions and meetings with stakeholders throughout the process. If using Waterfall, you should account for the upfront requirements gathering that needs to take place before the development can begin. Either way, your project plan should fit the needs of both the client and your internal team to get the project done right.

PM Tip: Click here to find out more about Agile.

3. What are the best talent resources you have available to fit the specific needs of this project?

Based on the SOW, who is going to be on your team? You should consider not only the special talents of your available resources but also the preferred working styles of the team members, and how they will mesh with the client and each other. It goes without saying that you should provide a front end developer if the contract includes applying a design, for example, but there are subtler considerations too. Maybe the client has expressed an interest in knowing how things work instead of just seeing the end result of the technology. In this scenario, you’d try to engage a developer who wants to share his or her knowledge and enjoys client interactions.

PM Tip: Nothing beats a real conversation!

Get to know your development and strategy teams by picking up the phone or walking over to have a face to face conversation. Reading a bio or an IM thread is great but nothing beats talking to the person – simple human to human interaction is still the best indication of who the person is behind the talent.

Questions to ask for a Drupal CMS

In addition to the aforementioned considerations, a project manager about to start a Drupal CMS project could benefit from knowing the answers to a few more questions:

1. In what platform is the current site built and which version of Drupal is the most appropriate for the client’s needs?

2. What are the hidden “it happens by magic” moments in this new project – aspects of the project that the client might not recognize as heavy lifts or even considerations for your team and therefore might not directly call it to your attention?

Your Client’s Customers and Other Vendor Relationships

A project manager must establish a foundational understanding of the client’s customers and have a full view of all third-party vendor relationships in the mix. This process sometimes involves decoding client requests:

CRM

  • Client says “We have members or donors and want to track their behavior.”

Single Sign on or other API

  • Client says “We have members who want to login once and be able to see everything across the online communities we provide them.”

SOLR Search Functionality

  • Client says “We have members who want to login once and be able to search the content in all uploaded files and conduct mini searches within our publications to find what they need quickly.”

Security

Every client must be satisfied that the security measures behind their new Drupal website are aligned with their unique business needs. Many times, clients take security for granted but it is the project manager's job to make sure a client's trust is earned and proven well-placed:

HTTPS

  • Client says “We need to be secure.”

eCommerce

  • Client says “We need to be secure because we are collecting money.”

High Availability Server

  • Client says “We need to be secure because we are collecting a crazy amount of money from our 1 million transactions a day.”

Event Tracking

  • Client says “We need to be secure because we are collecting a crazy amount of money from our 1 million transactions a day for our multiple concert events each week.”

In the end, the worst thing a project manager can do is ask nothing and just hope the project works itself out. A project team’s success and a client’s great experience is made or broken largely in between the sentences of the contract and outside the negotiation meeting room. Asking questions and truly listening to the answers given can only lead to good things for your project. In the case of communication, you can never have too much of a good thing.

Additional Resources
One Word to Save Your Project |Mediacurrent Blog
How to Budget a Drupal Project |Mediacurrent Blog
17 Tips for Leading Effective Conference Calls |Mediacurrent Blog 

May 25 2016
May 25

Today I will describe a way to handle multiple teams with their own private file folders using the IMCE module.

Let’s pretend that we have to develop a website called awesome-website.com which consists of three (or more) different teams. The team structure could look as followed:

Website Groups

Every team should only be allowed to edit their own pages but no page from any other team. Therefore it would also make sense to separate the team’s file folders so that the files can be stored separately to secure its privacy.
Of course, we could simply add three IMCE profiles and define their folder access rights individually there. But what about when working with 10 teams? Or 50? Or even more? Then we definitely would prefer a more flexible solution.
Thankfully, IMCE ships with the ability to define user folders by PHP execution, how awesome! But in order to achieve this, we’ll have to set up teams as taxonomy terms first and reference them from our user entities.

Setting up the “Teams” taxonomy vocabulary

First things first: Let’s create a new taxonomy vocabulary called “Teams”. For every team that we will have on our website, we have to create a new taxonomy term in this vocabulary.
Before adding any teams as taxonomy terms though, we’ll have to add a new field called “FTP Folder” to the taxonomy vocabulary.
This field will specify the name of every team’s root folder. So, naturally it shouldn’t contain any spaces or other wicked special characters and it should be URL readable.
In order not to face any unusual results later, it is recommended to configure this field as required.

Afterwards, we can add our three terms, “Team Alpha”, “Team Beta” and “Team Gamma”.
As value for their FTP Folders, we use “team-alpha”, “team-beta” and so on.

That’s it for the taxonomy part! Now let’s link this information to the team’s users.

Adding a taxonomy term reference field to the user entity

In my case, I didn’t have multiple roles for the teams. I only had one, called “Team member”. Because every team has exactly the same rights as the others, maintaining only one role suited me best.
For really special cases, I could always just create a new role with the special permissions.

So, how do we link users to their teams the easiest? Exactly, by just adding a taxonomy term reference field to the user entity!
Let’s call this field “Team” and reference our previously created taxonomy vocabulary “Teams” with it.

Now, when adding a new user, we can select it’s team belonging and IMCE will be able to grab the needed information from there.
Yes, IMCE will be able to do that but it’s not doing it yet.
Getting the teams ftp folder for the current user is still something we have to code, so let’s proceed to the next step.

Writing a custom function to provide the accessible directories for an user

Now we need to provide IMCE the information that we’ve set up before.
We’ve created users belonging to teams, which hold the FTP root folder name for the teams.
What’s left to do, is to write a function (ideally in a custom module, in my example the module is called “awesome_teams”), that combines all information and returns it to IMCE.
Following function would do that for us:

function awesome_teams_imce($user) { $user_folders = array('cms/teams/all'); $user_wrapper = entity_metadata_wrapper('user', $user); $user_teams = $user_wrapper->field_team->value(); foreach ($user_teams as $user_team) { $user_team_wrapper = entity_metadata_wrapper('taxonomy_term', $user_team); array_push($user_folders, 'cms/teams/' . $user_team_wrapper->field_ftp_folder->value()); } return $user_folders; }

1

2

3

4

5

6

7

8

9

10

11

12

13

function awesome_teams_imce($user) {

  $user_folders = array('cms/teams/all');

  $user_wrapper = entity_metadata_wrapper('user', $user);

  $user_teams = $user_wrapper->field_team->value();

  foreach ($user_teams as $user_team) {

    $user_team_wrapper = entity_metadata_wrapper('taxonomy_term', $user_team);

    array_push($user_folders, 'cms/teams/' . $user_team_wrapper->field_ftp_folder->value());

  }

  return $user_folders;

}

The function expects an user object as argument and will return an array of strings containing all the folder names an user is allowed to access.
Our folder structure would look like this:

  • sites/default/files/cms
  • sites/default/files/cms/teams
  • sites/default/files/cms/teams/all
  • sites/default/files/cms/teams/team-alpha
  • sites/default/files/cms/teams/team-beta
  • sites/default/files/cms/teams/team-gamma

Note: The folder “cms/teams/all” is a special folder and every user is allowed to access it.
It will be used to save files which are used globally over multiple or even all teams.

What our code does, is actually looping over all assigned teams for the given user (yes, an user can be in multiple teams!), and adding the teams ftp folder names to the array of accessible folders.

There is no “hook_imce” hook, the “_imce” in the function name does nothing till now. You can also name your function differently. The link from IMCE to our function is something we have to set up in an IMCE profile.
Let’s proceed to the last step then, shall we?

Creating the IMCE profile “Team member”

Now, as the last step, let’s create an IMCE profile called “Team member”. You’re free to define any settings as you like, there’s only one thing that will be special about this profile: The accessible directories path.

Instead of writing something constant as “cms/teams/team-alpha”, we’ll write “php: return awesome_teams_imce($user);” here.
So, the setting should look like this:

imce-profile-settings

Now save the profile and you are done!

As soon as one team member now accesses the IMCE page (either via /imce or by the configured file/image fields), he will only see his team’s directories and the special directory “all” which is meant for exchange.

This wasn’t that difficult, was it?

I hope I was able to give you an insight on how to solve more complicated file permission issues with IMCE.
Don’t forget to give feedback, ask questions and follow our blog if you want to read more about our Drupal experiences at Liip!

May 25 2016
May 25

My role as a principal at LevelTen means that I spend a lot of time overseeing Accounting, Operations, and Marketing. So for my visit to DrupalCon 2016, I wanted to spend as much time as I could talking with other C-level people to see what struggles we have in common and what solutions we've come up with.

Throughout the sessions, summits, and socializing, there were a few key themes that kept coming up over and over from people who run Drupal shops. With that in mind, this post is less of a DrupalCon 2016 takeaway than a preliminary analysis of the economics of Drupal as it evolves in Drupal 8 and beyond.

Offshoring: The U.S. Perspective

As with any business, attention to the bottom line is always a topic of hot discussion among agency principals. One recurring theme seems to be the idea of offshoring of development work (and increasingly other work).

Let’s face it, Drupal has its origins across the pond, so the concept of offshoring has always been in its roots, so to speak. As Drupal grew, healthy collaboration from anywhere in the world became a standard within the community. Geographic boundaries were never a problem when it came to the sharing of information, modules, and other technical hurdles.

What did NOT come as straightforward was the outsourcing of the actual development work (or project management work) to places outside of the country a company was conducting business. Historically, outsourcing seemed to be frowned upon within U.S. agency circles, but now, it seems to be the standard practice for larger agencies, even if only to test the waters. (For the record, I am not a protectionist, but I can appreciate the long term economic implications suggested by those who don’t like this trend.)

Either way, it is a new economic reality for any U.S. agency wishing to compete: some competitors will be leveraging workforces outside the U.S. We can talk about maintaining a competitive advantage all day, but the economics of capitalism will drive companies to seek economic advantages abroad if they exist.

Business Summit: One Size Does Not Fit All

Susan Rust did an excellent job of leading the Business Summit, where many takeaways for agency principals were discussed. There were way too many great conversations to pack into this writing, so I suggest that, if at all possible, you should really attend one of these summits yourself -- maybe at DrupalCon Baltimore?

One issue Susan raised, which I also think needs to be addressed, is the separation of agencies by size in these summits. Considering all the varying sizes of companies working with Drupal, one size does NOT fit all when it comes to operational challenges (or solutions). It is both inspiring and comforting for all to listen to the successes and challenges of all size shops; however, the idea that a 15-person company like LevelTen will employ the same solutions as a 100-person shop and a 2-person shop would be naive. I reiterate Susan’s call to modify the format in some way to accommodate all business summit participants, but sub-segment by agency size.

Drupal Economics: Drupal is Going Upstream

For those developer types, “upstream” has nothing to do with Git. In business parlance, "upstream" has to do with looking at larger industry sectors that, most times, serve other industries downstream. When we say that Drupal is going upstream, we mean that Drupal is evolving to be a good solution for large enterprise-level businesses, as opposed to small or mid-size businesses.

I saw a lot of people during the course of the week get caught up in the question of whether Drupal "can" be for everyone. Of course it can. The real question is "Who is Drupal best suited for at this time?," and an honest assessment is needed to answer it. It seems clear that Drupal is going upstream, becoming a preferred web platform for large enterprises. If you think Drupal is still best suited for small or medium businesses, I would love to hear why.

Now that we have established that Drupal is in fact going “upstream,” I would like to share what that means for the economics of Drupal:

1. Project sizes are getting larger, even as websites are commoditized.

Websites are fast becoming a commodity (if they are not already there, here in 2016). Look no further than ads for free websites with a minimal purchase, or inexpensive SAAS platforms for the masses. With this commoditization comes downward pressure on prices (price per unit of output), even as the industry matures. The successful companies look to larger projects to sustain the increased revenue requirements needed to support growth initiatives in an industry where the price per unit of output is decreasing.

2. Drupal shops are looking for economic advantages (see my point about outsourcing, above).

With increased revenue comes increased expenses and decreased profits as a percentage. Business owners often combat this with lower cost structures to prop up profits, which is generally regarded as a short term fix.

Lowering costs is not a sustainable model for growth unless, that is your competitive advantage (side note: contrary to Michael Porter’s acclaimed Competitive Advantage Theory (which I generally subscribe to), certain industries that exhibit rapid change, and lots of new alternatives or substitutes, will find that being the cost leader is the least desired strategy). Instead, the majority of Drupal shops are looking for other ways to increase their margins, whether that is through outsourcing, moving to a recurring-revenue retainer model, or other ways of restructuring the company.

3. Consolidation in the industry is coming.

Lastly, in an environment this competitive, Drupal companies are increasingly looking to consolidation through mergers and acquisitions of competitors to maintain growth. In this scenario, only a few survive the onslaught -- unless you have a true differentiation in the marketplace, and even then, it will be tempting to sell out to a competitor at some point.

This is not a doomsday prediction for the economics of Drupal, but rather, a reminder of the economic forces of goods and services that have increasing demand, and how companies attempt to capitalize on this need during the growth phase.

As Drupal becomes more powerful and more popular, these tensions are going to arise for more and more people, from solo freelancers to small shops to big players like our friends at FFW. At LevelTen, we plan to keep doing everything we can to keep bringing Drupal solutions to the people that need them.

May 24 2016
May 24

The normal Drupal instructions for applying patches are well used and reliable. However, I find them to be a little verbose, so I came up with a slightly quicker workflow.

TL;DR

The short explanation of what I do is to copy the patch's URL and run this command:

curl [patch URL] | patch -p1

Which would then become something like this:

curl https://www.drupal.org/files/issues/metatag-n2636348-12.patch | patch -p1

Disclaimers

  1. This workflow assumes the current version of the module/theme/core being patched is up-to-date, possibly a -dev version, and that the patch was also relatively current. It is common for files to substantially change from revision to revision, so a patch written against the latest -dev version of a module may not work with an older release.
  2. I'm not touching the "always use Drush Make" or "Composer is how the cool kids do it nowadays" workflows, this is purely about spending less time mucking around with patch files to test what could be a single line change to one of the simplest, or most complex, pieces of code you've ever seen.

Longer explanation

Step 1: Find the patch to be applied.

Step 2: Copy the patch's URL into the clipboard.

Step 3: In Terminal (or the Command Prompt on Windows), go to the appropriate directory for that project, e.g. sites/all/modules/contrib/metatag.

Step 4: Type the following into the terminal window: curl

Step 5: If it gave any warnings, update the issue with the comment "This patch needs to be rerolled." and change the status to "Needs work".

Step 6: Presuming the change applied ok, use "git status" to see what changed.

Step 7: If any files with a file extension ".install" show as either being changed or added, run the database updates.

Step 8: Clear all of the site's caches: drush cc all

Reason to do this

  • There's no need to keep a copy of a patch file, it can always be downloaded again later from drupal.org if needed again.
  • Because there are no patch files locally there's no worrying about where the patch file is stored on the computer versus which directory the command prompt is in, or how to make the path to the patch work correctly.
  • "git apply" does not apply the patch at all if it would not apply cleanly, and it often doesn't explain why the patch would not apply, even with the "-v" argument. If the patch didn't apply cleanly then it has to be manually recreated from scratch, which can be problematic and lead to mistakes. Using the "patch" command instead will apply what can be successfully applied, and anything that couldn't be applied correctly will be saved out as a separate ".rej" file, leaving much smaller pieces to be recreated.
  • There will be fewer files floating around the computer; the only patch files on my computer are the ones I actually created.

Over to you

What development processes have you tweaked to your own liking? Let me know in the comments.

Additional Resources
Mediacurrent's Contrib Committee April 2016 Update |Mediacurrent Blog
How to Add Content in an Update Hook |Mediacurrent Blog
Acquia's Dev Desktop: A Drupal Service for Beginners |Mediacurrent Blog

May 24 2016
May 24

As I've said before in my custom views filter handlers tutorial, views is amazing. Today I was writing a custom style plugin. I got the plugin to show up in the list of available formats, but whenever I saved the form, it wouldn't stick.

My Typical Method of Debugging in Drupal

Typically I would throw dpm's to debug, so I started walking through the callstack trying to find where things were going wrong. Then I ran into a line in views that called vpr(). It looked like a print_r debug statement, so I knew this was either being logged or there was a setting somewhere.

A Better Way to Debug Views Plugins

Sure enough it is part of the "Enable views performance statistics" setting to have these messages logged with watchdog. To turn it on go to /admin/structure/views/settings/advanced. Even better, when you turn Devel on, you can have them dpm'ed instead. Now I get exactly the information I need to figure out what I was doing wrong, without having to throw my own dpm's in views or ctools.

Other Views Settings for Debugging

Also, if you are just looking to debug your views query the "Show the SQL query" and "Show performance statistics" options on /admin/structure/views/settings are invaluable.

This post is part of my challenge to never stop learning.

Pages