Author

Jul 24 2016
Jul 24

Mike interviews Gregg Marshall, Enzo Garcia, and Daniel Schiavone live from Drupal GovCon 2016! Gregg discusses his new book, Enzo talks about his upcoming community keynote and the upcoming DrupalCamp Costa Rica, and Daniel previews Baltimore DrupalCamp and discusses preparations for Baltimore DrupalCon 2017.

DrupalEasy News

  • The Fall, 2016 session of Drupal Career Online begins September 26; applications are now open.
  • Online and in-person workshops; introductions to both module and theme development for Drupal 8. See the complete schedule.

Sponsors

Follow us on Twitter

Intro Music

Subscribe

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

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

Jul 22 2016
Jul 22

In our weekly roundup of higher education notes and trends, you can usually count on three themes being discussed by the academic community: student demographics, budget constraints, and technology. In this post, we'll expand more on these themes by sharing some of our own insights, and we'll cover a few unique and emerging technology trends across higher education and technology.

Virtual Reality on the Horizon in Higher Education

As a web agency specializing in building high-end websites for colleges and universities, anything technology related that has the potential to impact the sector is sure to get our attention. As a VP at our agency, imagine my enthusiasm when I read Inside Higher Ed’s article on virtual reality in the classroom!

The technology is still in its infancy. As such, it’s oftentimes expensive to produce and procure, so it will likely be years before we see it make any kind of tangible impact in schools. That said, the potential it may have in the future on learning outcomes is significant. Imagine complimenting a history lesson with a virtual reality tour, or studying rock formation in a geology class by seeing it in augmented reality. Expensive field trips? No need! Plug into virtual reality and tour the world right from your seat! Another hypothesized value will be the ability for a truly global classroom where virtual classes can meet “face to face” and work together on problem-solving. 

Technology has come a long way; I remember how excited the classroom would get when the teacher rolling in a bulky tubed-TV meant we’d get to watch a grainy, severely outdated educational video. Kids today - they have no idea how lucky they are.

Machine Learning -- Adapting Content To Complex Higher Education Websites

In a previous blog post, we reviewed an interesting new trend in higher education where learning management systems were starting to predict student outcomes by their usage patterns. That particular article noted the stats that showed that the more a student logged into the system during the first week or two of classes, the higher the probability they would succeed in the class. 

The concept of a “machine learning” has been prevalently used in the commercial sector for years now, with trendsetters like Amazon and Facebook serving up product and advertising suggestions based on your purchase history, “likes” and what websites you’ve visited. But the application for higher education is just as promising.

As a specialized web agency that does most of our work for higher education institutions, we’ve been introducing machine learning or “personalization” concepts to our clients for some time now (if you want to read more about personalization in higher education, check out this blog post we published last year). Higher education websites are what we call “content complex,” meaning they have a large number of distinctly different visitor types (what the web industry calls “personas”) frequenting them. Prospective students, parents of prospective students, enrolled students, parents of enrolled students, faculty and alumni is the best case scenario; often times our clients will have very different types of prospective students who require further segmentation (imagine international students vs. local). How does one landing page identify and speak to six unique types of visitors? Personalization technology, that’s how. 

When used, web personalization technologies can log specific user criteria and attributes such as age, location, purchasing behaviors, social media and more. With user attributes logged and indexed, businesses can deploy unique, adaptive content (even web pages) that are custom tailored to individual users. A sophisticated personalization strategy will have a unique web experience for each type of persona where everything from the content, images, colors and messaging has been tailored for them. As a person engages with the website, the technology “learns” more about what they are looking for and can serve up relevant content to them (just like Amazon suggests products to you based on your search and purchase history). 

Of course, this level of personalization requires a complex and thorough content strategy that many institutions simply do not have (yet). We often recommend simpler ways of personalization such as explicitly asking the user when they arrive who they are as a starting point. This basic framework can be evolved as the content strategy of the website becomes more refined. ImageX believes that personalization will be the foundation of user experience on the web moving forward, much like responsiveness for a mobile experience is today. Getting started on this trend now will make future adaptations that much more efficient.

Native Mobile Apps

It seems like every organization has or wants to have a native app; in some cases for good reason, while others, not so much. If an organization has a customer base that needs to interact with a large and often complex data set or tasks on a frequent basis, a native app is likely a good idea. Mobile banking on an app is a great example; the complexity of a banking website and the volume of content make the mobile experience cumbersome for specific interactions, such as paying bills or transferring money (what people generally refer to as “doing their banking”). A banking app immerses the user in that specific set of tasks, with a light set of complementary content and features. The business case for higher education is, in our opinion, just as strong as it is for mobile banking.

The obvious use case for higher education is current students managing their courses. Class schedules, assignment submissions, reminders for upcoming deadlines or events, test score notifications, paying tuition; you get the point. It wasn’t that long ago I was in University and the student portal my school had wasn’t even mobile responsive; if you couldn’t get to a desktop computer, you were in trouble. Another potential use case we parents here at ImageX often discuss is a parent app for those of us with children in post-secondary. Imagine if we could stay up to speed on children’s class schedule, assignments and grades? Oh, the possibilities…

Like to stay on top of higher education notes and trends? Subscribe to our newsletter below!

Jul 22 2016
Jul 22

In our weekly roundup of higher education notes and trends, you can usually count on three themes being discussed by the academic community: student demographics, budget constraints, and technology. In this post, we'll expand more on these themes by sharing some of our own insights, and we'll cover a few unique and emerging technology trends across higher education and technology.

Virtual Reality on the Horizon in Higher Education

As a web agency specializing in building high-end websites for colleges and universities, anything technology related that has the potential to impact the sector is sure to get our attention. As a VP at our agency, imagine my enthusiasm when I read Inside Higher Ed’s article on virtual reality in the classroom!

The technology is still in its infancy. As such, it’s oftentimes expensive to produce and procure, so it will likely be years before we see it make any kind of tangible impact in schools. That said, the potential it may have in the future on learning outcomes is significant. Imagine complimenting a history lesson with a virtual reality tour, or studying rock formation in a geology class by seeing it in augmented reality. Expensive field trips? No need! Plug into virtual reality and tour the world right from your seat! Another hypothesized value will be the ability for a truly global classroom where virtual classes can meet “face to face” and work together on problem-solving. 

Technology has come a long way; I remember how excited the classroom would get when the teacher rolling in a bulky tubed-TV meant we’d get to watch a grainy, severely outdated educational video. Kids today - they have no idea how lucky they are.

Machine Learning -- Adapting Content To Complex Higher Education Websites

In a previous blog post, we reviewed an interesting new trend in higher education where learning management systems were starting to predict student outcomes by their usage patterns. That particular article noted the stats that showed that the more a student logged into the system during the first week or two of classes, the higher the probability they would succeed in the class. 

The concept of a “machine learning” has been prevalently used in the commercial sector for years now, with trendsetters like Amazon and Facebook serving up product and advertising suggestions based on your purchase history, “likes” and what websites you’ve visited. But the application for higher education is just as promising.

As a specialized web agency that does most of our work for higher education institutions, we’ve been introducing machine learning or “personalization” concepts to our clients for some time now (if you want to read more about personalization in higher education, check out this blog post we published last year). Higher education websites are what we call “content complex,” meaning they have a large number of distinctly different visitor types (what the web industry calls “personas”) frequenting them. Prospective students, parents of prospective students, enrolled students, parents of enrolled students, faculty and alumni is the best case scenario; often times our clients will have very different types of prospective students who require further segmentation (imagine international students vs. local). How does one landing page identify and speak to six unique types of visitors? Personalization technology, that’s how. 

When used, web personalization technologies can log specific user criteria and attributes such as age, location, purchasing behaviors, social media and more. With user attributes logged and indexed, businesses can deploy unique, adaptive content (even web pages) that are custom tailored to individual users. A sophisticated personalization strategy will have a unique web experience for each type of persona where everything from the content, images, colors and messaging has been tailored for them. As a person engages with the website, the technology “learns” more about what they are looking for and can serve up relevant content to them (just like Amazon suggests products to you based on your search and purchase history). 

Of course, this level of personalization requires a complex and thorough content strategy that many institutions simply do not have (yet). We often recommend simpler ways of personalization such as explicitly asking the user when they arrive who they are as a starting point. This basic framework can be evolved as the content strategy of the website becomes more refined. ImageX believes that personalization will be the foundation of user experience on the web moving forward, much like responsiveness for a mobile experience is today. Getting started on this trend now will make future adaptations that much more efficient.

Native Mobile Apps

It seems like every organization has or wants to have a native app; in some cases for good reason, while others, not so much. If an organization has a customer base that needs to interact with a large and often complex data set or tasks on a frequent basis, a native app is likely a good idea. Mobile banking on an app is a great example; the complexity of a banking website and the volume of content make the mobile experience cumbersome for specific interactions, such as paying bills or transferring money (what people generally refer to as “doing their banking”). A banking app immerses the user in that specific set of tasks, with a light set of complementary content and features. The business case for higher education is, in our opinion, just as strong as it is for mobile banking.

The obvious use case for higher education is current students managing their courses. Class schedules, assignment submissions, reminders for upcoming deadlines or events, test score notifications, paying tuition; you get the point. It wasn’t that long ago I was in University and the student portal my school had wasn’t even mobile responsive; if you couldn’t get to a desktop computer, you were in trouble. Another potential use case we parents here at ImageX often discuss is a parent app for those of us with children in post-secondary. Imagine if we could stay up to speed on children’s class schedule, assignments and grades? Oh, the possibilities…

Like to stay on top of higher education notes and trends? Subscribe to our newsletter below!

Jul 22 2016
Jul 22

Of the many things that contribute to the success of a project, communication is the most important. While every project will differ in its requirements, team members, and plan, at the most basic level their goals should always be the same: to add value for the client. Open communication -- that is, the free exchange of ideas, collaboration, and ensuring clarity and direction is the lynchpin that holds a project together in the pursuit of that goal.

At ImageX, we believe in using the right tool for the job. And while “tool” usually means the specific software our staff uses to execute tasks, it also extends to the individuals themselves and how we bridge together teammates and project details. Among the many benefits of being one of the top-ranked Drupal agencies in the world is that we attract some of the top-ranked talent in the world -- and just like we don’t confine ourselves to a specific geographic area when we’re choosing which clients to partner with, neither do we for the teams we build to serve them. That team is based in our office in Vancouver, but it also includes those of us who help expand the depth and breadth of our agency -- remote employees, or as we affectionately call them, our “remotees.” 

For those of us who do work remotely, myself included, the benefits are vast:

  • We’re liberated from our desks;
  • Our morning commute is usually from our breakfast table to our den or workspace;
  • Or for that matter, our office is wherever we make it -- a café, library, or even on our travels; and,
  • We have the flexibility to set our own schedules and be more available for life’s demands (as long as we’re available for meetings, of course -- more on that below).

And for ImageX, the world becomes our talent pool and this allows us to hire the best people available for every position -- whether they’re in Vancouver, Toronto, Sweden, Ohio, Seattle, Taiwan, Florida, or the Ukraine (ImageX has remotees in all of these locations).

Working remotely also has quantifiable benefits to a business’ bottom line:

  • Two-thirds of managers reported that employees are more productive when working remotely;
  • 54 percent of remote workers reported completing as much or more work in less time because of fewer distractions;
  • 82 percent of remote workers reported lower stress levels;
  • Attrition rates fall by as much as 50 percent;
  • 68 percent of younger workers said that the option to work remotely would “greatly increase” their interest in a specific employer; and,
  • Businesses can significantly lower their overall operating costs.

And not to mention the environmental impact of fewer people commuting. When health insurance company, Aetna measured the benefits of their remote working policies, they found that their employees drove 65 million fewer miles, saved over two million gallons of gas, and reduced carbon dioxide emissions by over 23,000 tonnes per year.

A remotee (me on the laptop screen) joining our weekly #toughcoders push-up challenge by webcam, via Google Hangouts.

But working with distributed teams isn’t without its challenges. Communication problems can surface easily, whether because of logistics due to time zones or something simply being lost in translation online, and it’s easy to feel isolated at a home office and disconnected from your team. Like any project, overcoming these challenges and adding value to your team comes from having a strong plan in place to mitigate them. Building your team with the right mix of individuals, having a structured communication plan in place, and using the right tools for each job can help you realize the benefits of working with a distributed team.

Building Your Remote Team

Managing distributed teams introduces some additional considerations to make when you’re recruiting for new staff. Outside of the core competencies of each position, we’ve found emphasizing these four qualities to be a good predictor of success:

  • Is the candidate self-motivated? Working autonomously and independently requires a very high degree of self-motivation, rather than the constant encouragement and motivation that can be expected in a traditional office environment.
  • Does the candidate have strong communication skills? With limited face-to-face contact, above-average communication skills become even more important. Can the candidate communicate clearly and concisely, regardless of the medium, and accommodate for the subtlety and nuance that can often get lost?
  • Is the candidate results-driven? In the absence of more subjective evaluations, it’s important that your team members set clear objectives and that they’re measured against them.
  • Is the candidate open, honest, and transparent? This one is often the most important because you’re relying on your team to pro-actively raise any problems or concerns that could otherwise slip by unnoticed if people confine themselves to communication silos. The more forthcoming and straight-forward, the better.

Building teams of self-sufficient individuals who are empowered to work autonomously will encourage open communication and collaboration between members, rather than top-down (micro)management.

A SMART Communication Plan

With a distributed team, it’s essential that all members unite around a clearly defined and shared goal or purpose. A strong project and/or client manager can act as the advocate for this goal or purpose when any gaps occur and be the face of the team to the client. 

When defining the team’s goal or purpose, consider the SMART framework:

  • Specific
  • Measurable
  • Attainable
  • Relevant
  • Time-bound

Whether it’s included in a formal team or project charter, or more informally in how the project manager oversees the team day-to-day. 

Creating and fostering a results-driven culture is essential. Rather than tracking the team’s working hours (though we still track project hours for billing, efficiency, and accountability to the client), it’s more important that they’re able to produce results that drive the team towards their goals on a sustained basis. And it’s incumbent upon the project manager to ensure continued clarity on what those goals are.

Bringing your team together for regular meetings, either in-person or digitally, is the best way to make certain of this. Daily stand-ups for the project team where each member shares what they worked on yesterday, what their goals are today, and if there is anything blocking their progress shouldn’t take more than 10-15 minutes each morning, but will save exponentially more time in focus.

Weekly team-wide stand-ups allow department leads and upper management to share higher-level progress and help bring any remote staff out of their project silos and into the “office”. We don’t use these meetings to discuss the specifics of any projects -- rather, they bring the team together so that we can hear each other’s voices and see each other’s faces (even if they’re just on a screen), and it reinforces the bigger picture that each individual project is working towards.

The Right Tool for the Job

Once you have the right team members in place and a plan to facilitate communication, you need the tools in place to keep them connected. Using the right software can make communication seamless and effortless, and gives teams the advantage of having every project discussion documented, archived, and searchable -- far from the risk of impromptu drive-bys in the office. 

Every project needs a central repository that captures the tasks, responsibilities, and dependencies involved. While physical backlogs with Post-It Notes are great for the office, they don’t help distributed teams. Trello is an easy-to-use Kanban-style board that lets you drag-and-drop cards between lists to show progress in real-time. Or for a more comprehensive and collaborative solution, we like Basecamp and Jira.

For conversations between team members and clients, in-person meetings allow the participants to communicate verbally as well as non-verbally. There is no substitute for this, but web-based tools like Google Hangouts, Skype, and Slack are the next best thing. Their video functions help approximate in-person meetings and allow the participants to see each other’s faces to better detect nuance. And as a bonus, they have the added functionalities such as screen sharing that further simulate a meeting room setting.

Skype and Slack are particularly helpful for team members in different time zones who may be limited in the meetings they can attend. Because they archive the transcripts of any typed conversation, it’s easy for anyone to catch themselves up at the beginning of their day without the risk of anything being missed in a game of broken telephone. It also allows for easy searching anytime someone needs something confirmed.

Finally, document repositories and collaboration tools like Google Drive and Dropbox can centralize any templates, documentation, design artifacts, and project assets while providing versioning control as well as the ability for multiple team members to collaborate on the same file at the same time.

Final Thoughts

  • It can be difficult for a team to build a positive culture when its members are distributed -- it’s not as simple as grabbing a coffee or going out for lunch. But a strong team culture extends beyond being social. It’s also about “seeing a vision, aligning to a mission, creating a sense of community and belonging and having loyalty to a project that gets people excited about work.”
  • Get to know each other personally. Catch-up with before and after calls, take breaks and make time to chat, and build relationships that help bridges across timezones and cultural divides;
  • Take advantage of your communication tools and create spaces for team members to share off-topic, interesting, or funny content. We have Slack channels for #office, #kudos, #random and even #nhl; and,
  • Iterate. Like any project, test an idea and adapt based on what works and what doesn’t. Every team will have its own dynamic, and it’s essential that any plan adjusts to accommodate it. You won’t get everything right at first, but you can continually improve over time.

Does your organization have distributed teams? If so, what benefits have you realized, what challenges have you encountered, and what have you learned from the process? Get in touch below and let’s talk.

Jul 22 2016
Jul 22

Today marked the final day of this year's Drupal GovCon. It's been three days of insightful talks, swapping knowledge, and catching up with industry peers.

One of this week's most hands-on talks was this morning's overview of the structural differences between custom modules in Drupal 7 and Drupal 8. Unlike Drupal 7, Drupal 8 utilizes Symphony, Autoloading, and Composer. Additionally, the use of YAML files for .info configuration takes some getting used to. While the minimum structure of a Drupal 8 module is at first glance more complex than in Drupal 7, it minimizes effort as the module grows in complexity, utilizing Drupal 8's object-oriented structure to its advantage.

Another fantastic talk today took an in-depth look at implementing living style guides within Drupal. With the ever-changing nature of the web, a living style guide pulls in real code from a website to gather all of the site's components and styles in one place. This is a valuable tool not only for designers and developers, but also for content editors to see their options. In this talk, Sarah Thrasher showed how her team implemented the popular style guide library KSS not only to pull in the site's CSS, but also to leverage the same Twig templates that Drupal used for the theme to minimize duplication of code.

Last but certainly not least, I attended a talk on using usability.gov, a resource provided by the Department of Health and Human Services (HHS) to promote better usability across both government and private-sector sites. This site provides a number of valuable tips and templates not only on development, but also on everything from design to content strategy to project management.

All in all, this has been a fantastic event. I look forward to implementing the new knowledge and ideas this week has provided, and to GovCon 2017! If you missed them, check out the recaps of day 1 and day 2.

Jul 22 2016
Jul 22

This is the second post in a series about coding standards. In our first post, we talked about code standards and why they are so important. In this post, we’ll talk about how to implement Drupal coding standards in your projects.

Other posts in this series:

  1. Code Standards: What Are They?
  2. Code Standards: How Do We Implement Them?
  3. Code Standards: Formatting
  4. Code Standards: Documentation
  5. Code Standards: The t() function
  6. Code Standards: Object Oriented Coding & Drupal 8

Read the coding standards and keep them handy.

It’s a good idea to read over the Drupal coding standards so you have an idea of what’s expected. Even if you’re familiar with them, we can always use a refresher. They’re also a living document, so there’s a good chance something may have been changed or added since the last time you gave them a go-over. Use this post as a reason to read them again! Make sure you have them bookmarked for reference, as well. https://www.drupal.org/coding-standards

Set up your editor for success

The easiest way to keep your code clean and up to par is by having your editor do the work! There are a lot of editors out there, and even the ones that don’t have many bells and whistles can be set up to help you keep standards in mind when you’re coding.

Sublime Text

This post from Chris is a couple years old, and geared towards front-end developers, but has lots of great Sublime Text setup tips and plugins for every developer.

There’s some great info on drupal.org as well: https://www.drupal.org/node/1346890. Here you can find the basic configuration for adhering to Drupal coding standards, a script to set it up on OSX and Linux, and great plugins to help with development. Now you don’t need to worry about line length, spaces, tabs, line endings, and more. It’ll all be handled for you!

PhpStorm

If you’re using PhpStorm, their website has extensive instructions for getting set up with Drupal configuration here.

If you’re using another editor, you can see if it’s listed here: https://www.drupal.org/node/147789

If not, I’d suggest googling it, and if you don’t find instructions, create them and add them to the list!

Review your own code - Use coder

The easiest way to make sure you’re conforming to coding standards is to use a program like codesniffer. You can install coder, which is a Drupal module that allows you to check your code from the command line using custom rules and PHP Codesniffer. Here’s an example of what you might see:

Example Coder output

Let’s walk through this screenshot.

  1. I’ve navigated to a module directory - here, I’m checking the countries module.
  2. The alias I have set up for codesniffer, using custom Drupal rules, is drupalcs.
  3. I want to test the file at tests/countries.test.
  4. Sometimes this command can take a little while. If it seems like it’s hanging, especially if you’ve checked a directory, it may be too much, so try a single file at a time.
  5. The first thing you’ll see is which file you checked, and the full path. Here, it’s /Applications/MAMP/htdocs/countries/tests/countries.test
  6. Next, you’ll see how many errors and warnings, and how many lines they affect - there can be multiple errors per line, and coder will catch them all.
  7. Next, each error or warning will be listed line by line.

I find it’s easiest to go in order, because sometimes one error causes others - coder can only understand so much, so if you have, for example, an array that has one line indented improperly, it may also think the subsequent lines are indented improperly, even if they’re correct.

Christopher did a great post on PHP Codesnifffer last year, check it out here.

Generally, you want to run coder every time you make a change, and before you commit your code or submit a patch. This way, you’re always writing clean code, and anyone reviewing your code is reviewing it for content, and they don’t have to worry about style. Of course, everyone is human and we all make mistakes. Sometimes you’ll push up a tiny change without running coder, and not realize there was a style issue. That’s why team code reviews are so important!

Team code reviews - make the time

The most successful teams build in time to review one another’s code. There’s no substitute for code reviews by another person, and making sure that you view them as an essential part of your process - the same goes for reviews on drupal.org. When planning time and resources for a project, make sure that there is time set aside for code reviews. When you’re working on contrib projects, make sure you take a look at issues marked "Need Review," and test them. If you want a way to dive into a project or just Drupal and contrib work in general, reviewing patches is a great way to get acclimated. You get exposed to other people’s code, and if you find something that needs to be corrected, that will stick with you and you’ll remember it.

Two things to remember when reviewing other people’s code, or when receiving reviews of your own:

  1. Treat others as you would like to be treated. Be kind, courteous, respectful, and constructive. Be aware of your tone. It’s easy to come off more harshly than you intended, especially when working quickly. Take just a second to re-read your comments, especially if you’re communicating with someone you’re not acquainted with.
  2. Take everything in stride, and don’t take it personally. Those reviewing your code want it to be good, and corrections aren’t a personal attack. This can be especially hard when you start out, and even after years, you can still get a comment that comes off in a way that hurts your feelings. Don’t dwell on it! Thank them, make the corrections, submit them, and chances are, they’ll thank you, too.

Now you know what code standards are, why they’re important, and how you can get started implementing them in your code. Set up your editor, install coder, and get ready for our next code standards post on formatting! We’ll talk about the nitty gritty of how you should format your Drupal code.

[1] Hero photo attribution: charlene mcbride

Jul 22 2016
Jul 22

The more I work with Drupal 8, the more I realize how much has changed for developers in the Drupal community. While the transition to a modern, object-oriented system is what's best for the longevity of the platform, it certainly doesn't come without challenges. As someone who doesn't come from an OOP background, I've found the transition difficult at times. In many cases, I know exactly what I want to do, just not how to do it the "Drupal 8 way". On top of this, tutorials and blog posts on D8 are all over the map in terms of accuracy. Many posts written during D8's development cycle are no longer applicable because of API changes, etc.

Below is a list of snippets that might be helpful to site builders or developers more familiar with D7 hooks and procedural. It might also be useful to OOP folks who are new to Drupal in general. My goal below is to add to and update these snippets over time.

Routes & Links

Determine the Current Drupal Route

Need to know what the current Drupal route is or need to run some logic against the current route? You can get the current route like so:

$route = \Drupal::routeMatch()->getRouteName();

To some, the \Drupal::routeMatch() syntax might look foreign (it did to me). Here's a rundown of what's happening here:

First, \Drupal. This is calling the global Drupal class, which, in Drupal 8, is a bridge between procedural and OO methods of writing Drupal code. The following comes from the documentation:

This class acts as a unified global accessor to arbitrary services within the system in order to ease the transition from procedural code to injected OO code.

Right. Moving on to ::routeMatch(). Here we're using the routeMatch() method which "Retrieves the currently active route match object." Simple enough. But what is "::" all about? This StackOverflow answer helped me to understand what that's all about.

From there, the getRouteName() method returns the current route name as a string. Here are some example routes: entity.node.canonical, view.frontpage and node.type_add.

Is this the Front Page Route?

Need to check if the current route is the front page route? There's a service and method for that:

// Is the current route/path the front page?
if ($is_front = \Drupal::service('path.matcher')->isFrontPage()) {}

Here we're calling the path.matcher service (defined in /core/core.services.yml) and using the isFrontPage() method. For more on services, check out the "Services and Dependency Injection Container" documentation on api.drupal.org which helped me understand how all of these bits work together and the why of their structure.

Get the Requested Path

Need to know what the current page's requested path was, as opposed to the route? You can do this:

$current_uri = \Drupal::request()->getRequestUri();

Redirect to a Specific Route

Need to redirect to a specific page? In Drupal 7, you would likely handle this with drupal_goto() in your page callback function. In Drupal 8, you can use RedirectResponse() for that. Here is the relevant changelog.

Here are some examples, borrowed heavily from said changelog. First, in procedural PHP:

use Symfony\Component\HttpFoundation\RedirectResponse;

function my_redirect() {
  return new RedirectResponse(\Drupal::url('user.page'));
}

Here is how you would use a Drupal 8 controller to accomplish the same thing:

use Drupal\Core\Controller\ControllerBase;

class MyControllerClass extends ControllerBase {

  public function foo() {
    //...
    return $this->redirect('user.page');
  }
}

Links on the Fly

Drupal 7 and prior relied heavily on the l() function. (In fact, I would wager this was my most used function over the years. In Drupal 8, if you need to create links on the fly, utilize the Link class

$link = \Drupal\Core\Link::fromTextAndUrl($text, $url);

Working with Entities

Query Database for Entities

If you need to query the database for some nodes (or any other entity) you should use the entityQuery service. The syntax should be pretty familiar to most D7 developers who have used EntityFieldQuery:

// Query for some entities with the entity query service.
$query = \Drupal::entityQuery('node')
  ->condition('status', 1)
  ->condition('type', 'article')
  ->range(0, 10)
  ->sort('created', 'DESC');

$nids = $query->execute();

Loading Entities

If you need to load the actual entities, you can do so a number of ways:

While the following will technically work in Drupal 8:

$node = entity_load_multiple('node', $nids);

This method has been deprecated in Drupal 8 and will be removed before Drupal 9, in favor of methods overriding Entity::loadMultiple(). To future-proof your code, you would do something like the following:

$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($nids);

Here's how you would do similar for a single node:

$node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);

Here are a few other entity snippets that might be useful:

// Link to an entity using the entity's link method.
$author_link = $user->toLink();

// Do the same thing, but customize the link text.
$author_link = $user->toLink('Some Custom Text');

// Given a node object, here's how to determine its type:
$type = $node->getType();

// To get the full user entity of the node's author:
$author = $node->getOwner();

// To get the raw ID of the author of a node:
$author_id = $node->getOwnerId();

Image Styles

Need to whip up an image using a particular image style on the fly? This will work for that:

// Create an instance of an image using a specific image style, given a path to a file.
$style = \Drupal\image\Entity\ImageStyle::load('yourStyle_image');
$img_path = $user->field_profile_some_image->entity->getFileUri();
$img_style_url = $style->buildUrl($img_path);

That's it for now. I intend to keep this post updated as we learn more and more about the new world of Drupal 8. If you have a snippet worth sharing, drop us a line via Twitter and we’ll add it to this post (with credit of course).

Jul 22 2016
Jul 22

Like it or not, sometimes you have to output HTML in javascript.

Recently, I ran across a line of code something like this while reviewing a pull-request for a client:

var inputMarkup = '<span><label data-val="' + inputText + '"
for="checkbox-' + index + '" data-tid="' + tid + '">' +
  inputText + '</label><input type="checkbox" id="checkbox-' + index + '"
  data-tid="' + tid + '" data-val="' + inputText + '"
  /></span>';

Aside from the fact that this code was hard to read (and therefore would be more difficult to maintain), the same code was used with no significant modification in three separate locations in the pull-request.

In PHP, most developers familiar with Drupal would immediately reach for one of the well-known parts of Drupal's theme system, render arrays, theme(), or a *.tpl.php file. In javascript, however, I seldom see much use of Drupal 7's extensive javascript API (also made available in a nicely browseable--though not quite up-to-date--form by nod_).

In this case, the relatively difficult-to-read code, combined with the fact that it was repeated several times across more than one file were clear signs that it should be placed into a theme function.

The Drupal.theme() function in the javascript API works much like theme() in PHP. When using theming functions in PHP, we never call them directly, instead using the theme() function.

In javascript, it's similar; when output is required from a given theme function, we call Drupal.theme() with the name of the theme function required, and any variable(s) it requires.

For example, drupal.org shows the following usage:

Drupal.theme('myThemeFunction', 50, 100, 500);

The example uses Drupal.theme() to call the theme function, myThemeFunction(), and pass it the arguments it requires (50, 100, and 500 in this instance). A theme function can accept whatever number of arguments is necessary, but if your theme function requires more than one parameter, it's good practice to define the function to take a single javascript object containing the parameters required by the function.

So in the case of my code-review, I suggested we use a theme function like this:

/**
 * Provides a checkbox and label wrapped in a span.
 *
 * @param {object} settings
 *   Configuration object for function.
 * @param {int} settings.index
 *   A numeric index, used for creating an `id` attribute and corresponding
 *   `for` attribute.
 * @param {string} settings.inputText
 *   The text to display as the label text and in various attributes.
 * @param {int} settings.tid
 *   A Drupal term id.
 *
 * @return {string}
 *   A string of HTML with a checkbox and label enclosed by a span.
 */
Drupal.theme.checkboxMarkup = function(settings) {
  "use strict";

  var checkboxId = 'checkbox-' + settings.index;
  var inputText = Drupal.checkPlain(settings.inputText);
  var checkboxMarkup = '';

  // Assemble the markup--string manipulation is fast, but if this needs
  // to become more complex, we can switch to creating dom elements.
  checkboxMarkup += '<span>';
  checkboxMarkup += '<label data-val="' + inputText + '" for="' + checkboxId + '" data-tid="' + settings.tid + '">';
  checkboxMarkup += inputText;
  checkboxMarkup += '</label>';
  checkboxMarkup += '<input type="checkbox" value="' + inputText + '" id="' + checkboxId + '" data-tid="' + settings.tid + '" data-val="' + inputText + '">';
  checkboxMarkup += '</span>';

  return checkboxMarkup;
};

This allowed the calling code to be much simpler:

// Creates themed checkbox.
checkboxMarkup = Drupal.theme('checkboxMarkup', {
  index: i,
  inputText: $('.inputText').val(),
  tid: $('.tid')
});

$container.append(checkboxMarkup);

The HTML generation is now also more loosely coupled, and more portable, meaning that we can easily use Drupal.theme.checkboxMarkup() elsewhere in this project--or in any other Drupal project.

Jul 22 2016
Jul 22

This webinar has passed. Keep an eye on our blog for future webinars.

You know how to get things done with git: pull, add, commit, push; but have you mastered it like a Jedi does the force? Nothing is a more lasting record of our work then our git commits. In a galaxy where companies ask you for your Github account in lieu of, or in addition to a resume, we have one more reason to make sure that our commit history is as readable as our code itself.

In this one hour session, we will cover:

  • Rewriting commits
  • Reordering commits
  • Combining commits
  • The perfect commit message
  • Finding bugs using git
  • Avoiding common pitfalls

Join us for this session and you will leave a jedi-level git master!

These Are Not the Commits You're Looking For

Jul 22 2016
Jul 22

Below is a site launch checklist, with details on individual areas of interest to follow in the appendix. While some are Drupal specific, the majority would apply to most any site.

Launch Checklist

  • Is the web server instance size large enough?
  • Is there a load balancer in front of your web head(s)?
  • Is Jenkins configured to automatically deploy your code, run cron, etc?
  • Is Redis configured and enabled?
  • Is a CDN configured?
  • Is the CDN serving HIT's?
  • Is Varnish serving HIT's?
  • Is New Relic configured?
  • Is the VirtualHost configured to redirect from www to the base url (or vice-versa)?
  • Is HTTPS enabled?
  • Is Apache configured for HTTP/2?
  • Is Google Analytics (or your analytics tool of choice) configured?
  • Is robots.txt configured for production (ie. did you remove any changes that were made for development)?
  • Is Drupal's internal page cache enabled?
  • Is the Security Review module installed and providing a clean report?
  • Do Drupal's settings.php & (if Drupal 8) services.yml files have the correct read-only permissions?
  • Are all of the checks on Drupal's status report page reporting green?
  • Are all development related modules disabled?
  • Are errors configured to be suppressed?

Appendix

Infrastructure

Though we use a number of different hosting providers in practice, our standard is Linode. Specific hardware recommendations follow:

Web Server

Use at least a 4GB cloud instance. If you or the client are price sensitive and are considering opting for a smaller instance size to save money, I would argue that the billable time spent troubleshooting an underperforming server is easily much more expensive then paying for more power.

Load Balancer

A load balancer is essential when configuring a site with multiple web servers, but using a load balancer is preferable even in situations with only one web server. Having DNS point to a load balancer, instead of to the web server directly, will give you instantaneous control over where your traffic is routed. For example, if you need to replace your web server hardware, you can redirect traffic instantaneously as opposed to waiting for DNS to propagate. Additionally, a load balancer can add simplicity when configuring a site that uses HTTPS, as you can configure the appropriate certificates at the load balancer level as opposed to on all of the relevant web servers.

Automation

At a minimum, the following jobs should be configured in Jenkins:

  • Automated deployments triggered from Github.
  • Cron to be run at least once every 24 hours.
  • A Drush cache clear job that can be run on-demand from the Jenkins UI.

Performance

New Relic

Chromatic configures all web servers meant for production with New Relic. If the client does not already have a New Relic account, create one and obtain the license key. When configuring production boxes using Ansible, utilize the New Relic role in the playbook and provide the correct API key.

Redis

Redis should be installed and configured for all production Drupal sites. Using Redis will improve database performance.

CDN

Putting a CDN in front of your site, provides many perfomance and security benefits. With the many low-cost and free options available, there is rarely a reason to not institute a CDN on every production site. We have had great success using CloudFlare.

Note: CloudFlare requires you to change your name servers and use them for DNS configuration. These changes should be made at least 24 hours in advance of launch.

If this is a Drupal 7 site, be sure to add the following line to your production settings.php file:

/**
 * Remove "cookie" from Vary header to allow HTML caching.
 */
$conf['omit_vary_cookie'] = TRUE;

Varnish

Many high traffic sites will benefit from an extra layer of caching between the web server and the CDN. In these instances one or more Varnish reverse proxy servers is recommended.

HTTPS

SSL can be configured easily with Let's Encrypt. These certificates need to be renewed quarterly but this renewal process can be automated.

HTTP/2

If you have configured HTTPS, you should go one step further and enable HTTP/2 to reap its additional performance benefits. While HTTP/2 does not technically require encryption, no browser currently supports it over HTTP, so for all intents and purposes HTTP/2 requires HTTPS.

Enabling HTTP/2 is a straight-forward process:

  • Enable the Apache HTTP/2 mod:
sudo a2enmod http2

  • Add the following line to the SSL vhost in question:
Protocols h2 http/1.1

  • Restart Apache
sudo service apache2 restart

This content has been generated from the Chromatic Site Launch Guide repository. Fork it on Github!

Jul 22 2016
Jul 22

DrupalCon New Orleans is nearly here and Chromatic will be attending in full force! Here's the rundown of what you need to know:

Learn About Render Arrays from Gus Childs

Gus will be presenting his session on Drupal 8 render arrays on Tuesday at 1pm in the Blackmesh Room (267-268): Aha! Understanding and Using Render Arrays in Drupal 8. If you're ever been confused by render arrays or just want to learn the best practices for how you're supposed to use them, be sure not to miss this session. Gus happens to be an awesome presenter to boot!

Schedule or Attend a BoF in the Chromatic Room

We're once again sponsoring a Birds of a Feather room. BoFs are a great way for folks to get together and discuss interesting topics in a more informal setting. There's already some great BoFs scheduled for the Chromatic room, including one on Drupal VM and Local Development from the well-known geerlingguy. We have a couple BoFs of our own too:

If you have a great idea for a BoF, schedule one for the Chromatic room!

Connect with Us at one of the Summits

In addition to attending the conference proper, we're once again sending our leadership to the Business Summit, as well as sending a couple of folks to the Media & Publishing Summit.

Grab Some Swag

Every year, DrupalCon attendees rave about how awesome and comfortable our t-shirts are. That's because we don't believe in making swag that we ourselves wouldn't love to wear. This year is no different. For NOLA, we've made a limited run of some special vintage baseball tees, printed on 3/4 sleeve American Apparel 50/50 cotton. These shirts are our best yet and we want to give you one for FREE!

See you in New Orleans!

Jul 22 2016
Jul 22

We're happy to announce two new releases for the YouTube Field module:

Improvements include:

Once again, it was a community effort. The module has now given credit attribution to 28 different people. A number of them have been the community member's first attributed commit! Not to mention, endless others have contributed in the issue queue. Thanks to their help, the module has now reached over 30,000 installs. That's enough to land in the top 200!

Why the "beta" label on the 8.x release?

The 7.x-1.x module includes Colorbox support, but that support has not yet been ported to the 8.x-1.x branch. We'd love help with that! We're planning on removing the "beta" label once that support is committed. The rest of the module is a direct port of 7.x-1.x and it already reports a healthy number of installs.

How else can I help?

Hop in the issue queue and have a look at the outstanding issues for either branch. As previously mentioned, any and all contributions are greatly appreciated!

Jul 22 2016
Jul 22

Civil Comments is a platform that brings real-world social cues to comments sections via crowd-sourced moderation and powerful community management tools. Civil Comments is the first commenting platform specifically designed to improve the way people treat each other online.

Unlike others who have thrown up their hands and accepted that the comments sections of the Internet would either be dominated by bullies and trolls, or become a moderation burden for a site's editors, the team at Civil is attempting to solve the problem with community moderation. It is an exciting new take on a widespread problem, and Chromatic is thrilled to bring Civil Comments integration to Drupal with a new contrib module.

It should be noted (and is on the project page!) that there is not currently a free version of Civil Comments. For the time being, it is only available with a subscription as Civil continues work on the platform, but from what I understand a free version is on the horizon.

A special thanks to Christopher Torgalson and Alanna Burke, whose contributions helped get this project off the ground!

Jul 22 2016
Jul 22

Aren't you a cutie?

Here at Chromatic HQ, the team is encouraged to give back to the open-source community. (And on company time!) One way to do this is by reviewing and contributing Drupal patches. For me, this can be both rewarding and frustrating. When things go well, I feel good about contributing and I might even get a commit credit! But there are times when patches don't apply, I have no clue what's wrong and I need to start fresh. First, I curse mightily at the time wasted, then I create a new db, and then re-install a fresh copy of Drupal, and then configure it etc. etc. Using drush site-install makes this process relatively easy, but what if it could be easier? (Hint: It is!)

Hooray for promiscuity!

I recently had a fling with Drush's core-quick-drupal command. I had known about it for years, but I hadn't realized what it could really do for me. This has now changed, and together we're having an open affair!

For the uninitiated, drush core-quick-drupal takes advantage of PHP's built-in web server (PHP >= 5.4) and uses a sqlite database to get a fresh, stand-alone copy of Drupal up and running, all in about a minute. It has two aliases: drush qd and, my personal preference, drush cutie.

Out-of-the-box overview

  • In about a minute it installs a full instance of Drupal.
  • Runs a web server at http://127.0.0.1:8888 (no apache config).
  • Uses a self-contained sqlite file as the db (no mysql db to create and configure).

It's so much fun, you may want to follow along. From the command line, just cd to a folder of your choosing and run drush cutie --yes. (You'll need to have drush installed.)

Behind the scenes, a folder is created called quick-drupal with a timestamp appended to the end. (One of my older cutie folders is quick-drupal-20160214193640... a timestamp from a Valentine's evening with Drush that my wife won't soon forget!) Inside the new quick-drupal folder are subfolders with the latest D8 files and the sqlite db file. (There are lots of options to customize the Drupal version and environment, but the default nowadays is Drupal 8.)

Running it looks something like this

drush cutie --yes
Project drupal (8.0.3) downloaded to 
...
Installation complete.  User name: admin  User password: EawsYkGg4Y
Congratulations, you installed Drupal!
Listening on http://127.0.0.1:8888

(The output above has been edited to highlight the tastier bits!)

And with that I have the latest version of D8 running at http://127.0.0.1:8888. As you can see from the shell output above, the superuser is admin with a password of EawsYkGg4Y.

Okay, okay, very cool, but what can I do with it?

Here's a breakdown:

  1. Review patches with minimal fuss, thereby giving back to the Drupal community.
  2. Investigate new modules without sullying your main dev environment.
  3. Test that new Feature you created to see if it really works.
  4. NOT RECOMMENDED! When that friend asks you how long it will take to build him a website, respond with "about a minute" and fire it up.

You thought I was done?

Let's run through the steps to review a patch. This is where drush core-quick-drupal really shines because it's best to have a clean install of Drupal to work with; this minimizes the number of externalities that can interfere with testing. Having a single-command, throwaway copy of vanilla Drupal is the way to go.

You could call this a blog version of a live demo; I have chosen a patch out in the wild to review. I found this one for the core taxonomy module, that had a status of "Needs Review" on D.O.

The patch file itself is here: https://www.drupal.org/files/issues/taxonomy-term-twig-cs.patch

Here are the steps I took on the command line:

# Install a temporary copy of D8 into a folder I named "test2644718"
drush cutie test2644718 --yes

With the above command I got my environment running. The patch itself simply fixes the formatting in taxonomy-term.html.twig, which is a default template file for taxonomy terms, provided by the core taxonomy module.

I first tested to see the original template in action. Satisfied with the way it was working, I took steps to apply the patch.

# Move into the root folder of the new site
cd test2644718/drupal/
# Use wget to grab the patch from D.O.
wget https://www.drupal.org/files/issues/taxonomy-term-twig-cs.patch
# Apply the patch
patch -p1 < taxonomy-term-twig-cs.patch
patching file core/modules/taxonomy/templates/taxonomy-term.html.twig

The patch was applied successfully and a minor change in taxonomy-term.html.twig was made. I quickly tested to ensure nothing had blown up and was satisfied that the patch works as expected.

Back in D.O., I added my two cents and marked the issue as Reviewed & tested by the community. And that's that.

Update

Though the patch originally sat awaiting review for 2 months, I'm happy to claim that my review got things moving again! After I posted RTBC, a flurry of activity took place with the scope increasing and new patches being created. I reviewed those too! A day later the patches were committed to 8.1.x. Nice.

Jul 22 2016
Jul 22

There are many different ways to handle offsite database backups for your Drupal sites. From host provider automations to contrib modules like Backup and Migrate and everywhere in between. This week, I was looking to automate this process on a Drupal 8 site. Since Backup and Migrate is being rewritten from the ground up for Drupal 8, I decided to whip up a custom shell script using Drush.

I knew I wanted my backups to not only be automated, but to be uploaded somewhere offsite. Since we already had access to an S3 account, I decided to use that as my offsite location. After doing a bit of Googling, I discovered s3cmd, a rather nifty command line tool for interacting with Amazon S3. From their README.md:

S3cmd (s3cmd) is a free command line tool and client for uploading, retrieving and managing data in Amazon S3 and other cloud storage service providers that use the S3 protocol, such as Google Cloud Storage or DreamHost DreamObjects. It is best suited for power users who are familiar with command line programs. It is also ideal for batch scripts and automated backup to S3, triggered from cron, etc.

It works like a charm and basically does all of the heavy lifting needed to interact with S3 files. After installing and setting it up on my Drupal 8 project's server, I was able to easily upload a file like so: s3cmd put someDatabase.sql.gz s3://myBucket/someDatabase.sql.gz.

With that bit sorted, it was really just a matter of tying it together with Drush's sql-dump command. Here's the script I ended up with:

  
    # Switch to the docroot.
    cd /var/www/yourProject/docroot/

    # Backup the database.
    drush sql-dump --gzip --result-file=/home/yourJenkinsUser/db-backups/yourProject-`date +%F-%T`.sql.gz

    # Switch to the backups directory.
    cd /home/yourJenkinsUser/db-backups/

    # Store the recently created db's filename as a variable.
    database=$(ls -t | head -n1)

    # Upload to Amazon S3, using s3cmd (https://github.com/s3tools/s3cmd).
    s3cmd put $database s3://yourBucketName/$database

    # Delete databases older than 10 days.
    find /home/yourJenkinsUser/db-backups/ -mtime +10 -type f -delete
  

With the script working, I created a simple Jenkins job to run it nightly, (with Slack notifications of course) and voilà: automated offsite database backups with Jenkins and Drush!

Jul 22 2016
Jul 22

Dropcast: Episode 22 - The Jim Birch Society

Recorded July 6th 2016

This episode our number one fan, Jim Birch, comes on to talk about his Drupal life and sadly learns how unprofessional his favorite podcast is. With that we recognize how long it takes me to actually get an episode out of the can and into your ears. Bob highlights some blog posts, which derails into a discussion about the Google AMP service, which rolls perfectly in with Ryan’s Pro Project Pick. We discuss the latest Drupal News and of course Ryan brings it home with the Final Bell.


Episode 22 Audio Download Link

Updates:

Mediacurrent Blog Mentions:

Interview with Jim Birch (Mario):

Pro Project Pick:

Drupal News:

Jul 22 2016
Jul 22

Look for Talent, Not Experience

We got started with the idea to train inexperienced employees out of necessity, as well as from personal values. I had a few different careers before I got into web development. I was a pharmaceutical chemist, and I was also a math teacher. But I never worked at a place where anyone recognized my talent.

I had other jobs, too. In college, I was a telemarketer and did data entry. I was a bright person, but nobody seemed to notice. I always thought that it was a shame that talent goes to waste due to a lack of opportunity for young, unproven workers.

Back then, I wished someone would have given me an opportunity to do something at my level. Instead, I made it happen for myself, and co-founded this company in 2008. We didn't have any money, and back then there were even fewer qualified potential hires in our field. I'm super picky about the quality of the work my company does, and wasn’t willing to hire second rate workers.

We hired a few people and then the economy collapsed. Much of our work went away. We decided that we weren't going to cut anybody. By that point, we’d hired four or five people, and they didn't really have any experience. I was doing most of the billable work, plus teaching people. When the work dwindled, we decided to pay them from our credit cards. About half of those people are still with us, and they're doing great. I'm really glad that we kept them.

The main reason that we started hiring people who didn't really have much or any experience was that we couldn't afford anyone who did. We're not a virtual company; we've always had an office, so we're limited to our local area, and there really were very few good developers. Instead what we did was just bring candidates into the office, make sure everyone communicated, and for our part, we would bring a willingness to teach.

Believe that your people are intelligent, and that you can teach them something, and that they can learn. They might not learn as quickly as you would like sometimes, but if you believe that they will learn, they will.

*SOURCE: http://www.modernsurvey.com/fall2014

Download the full Grow Your Own white paper for free.

Jul 22 2016
Jul 22

An OSTraining member asked how to setup a bitnami lamp that supports PHP 5.4.

The Bitnami Wamp stacks are available in 3 versions here:

  • 5.5.37
  • 5.6.23
  • 7.0.8

Each of these provides an environment that is preconfigure with a different version of PHP.

5.5.37 comes with PHP 5.5, which you should also use for 5.4 setups. The reason 5.4 is no longer available is because the changes between 5.5 and 5.4 are minimal. You can read more about the changes on the official change log here.

To install the Wamp stack, follow our installation guide.

If you already have a Bitnami Lamp setup, you can install it again. Just be sure to use a different directory location to your original installation. All Bitnami files are contained within these containers, so you can simply install the stack as many times as you like. 

When installing your second stack, you will have to use a different ports for apache, ssl and mysql:

 apache port

apache port

Once the installation is complete, you should see this screen:

installed

installed

In this older version of the Bitnami stack, the enviroment doesn't include Drupal. So we will have to install Drupal now.

Download or copy your drupal site to Bitnami\wampstack-5.5.37-1\apache2\htdocs\drupal

Navigate to http://127.0.0.1:8080/drupal/ 

If you are doing a fresh install, you will see this screen:

drupal install

drupal install

 You can access PHPMyAdmin from http://localhost:8080/phpmyadmin/


About the author

Daniel is a web designer from UK, who's a friendly and helpful part of the support team here at OSTraining.

View the discussion thread.

Jul 22 2016
Jul 22

Friday 5: 5 Structured Data Items that Work for Every Website

We hope the work week is treating you well and that you're gearing up for an even better weekend!

Thanks for joining us for Episode 13 of The Mediacurrent Friday 5. This week, Director of Digital Strategy Dawn Aly joins host Mark Casias to cover 5 Structured Data Items That Work for Every Website. She discusses 5 schema markup types that will work for your website AND a bonus of 5 kinds of content that you should definitely consider marking up.

Watch the video below to learn more about Organization Schema, Website Schema, BreadcrumbList Schema, SiteNavigationElement Schema, VideoObject Schema and more!

[embedded content]

Have a topic that you want to learn more about? Feel free to email us your suggestions to [email protected] and stay tuned for Episode 14 in two weeks. Have a great weekend!

Additional Resources
Friday 5: 5 Tips for Improving Your Site's SEO | Blog Post
Mediacurrent's Crash Course in SEO and Drupal | Webinar
SEO Checklist | eBook

Jul 21 2016
Jul 21

Day two of Drupal GovCon brought with it more tales of Drupal success, lessons learned, and exciting new ideas.

The morning began with a case study on NIH.gov's move to Drupal. As a large federal agency, the NIH team was unused to open source software, but needed a highly flexible system. With Drupal, they created a custom solution using content types, entities, and taxonomy, all while maintaining a strict separation of content from presentation to allow for multi-channel publishing. They were also able to set up specific user roles and workflows for the numerous government stakeholders who use the system every day, and meet all FedRAMP and all FISMA requirements.

Next followed an in-depth discussion of how to improve accessibility in dynamic interface elements such as accordions, tabs, or slideshows. Section 508 and WCAG 2.0 provide extensive documentation on how to ensure that websites are accessible to the broadest audience, accounting for a wide range of limitations and abilities. While these standards are legally required for government sites, they are best practice for all sites across the web, both as the right thing to do and to help a site's SEO. In addition to common measures such as making sure that a site is keyboard navigable and all images have alt text, this talk specifically dug into the role (pun intended) ARIA attributes play when modifying content visibility using JavaScript.

In the afternoon, I went to talks on new features in Drupal 8 such as Twig and configuration export, as well as a detailed discussion of Paragraphs, a Drupal contrib module that we've used on several projects here at Third & Grove. The paragraph module allows the site architect to create fielded entities for custom chunks of content - for example, a photo gallery, an accordion, or anything else that can be built out of fields - and let the user insert them in any order they want within a content node. This lets content editors create far more interesting and dynamic pages than they would be able to in an plain WYSIWYG field, and future-proofs content by keeping it sorted in the database rather than a single field of HTML.

If you missed it, check out yesterday's Drupal GovCon Day 1 Recap, and stay tuned for tomorrow!
Jul 21 2016
jam
Jul 21
A conversation from DrupalCon Asia DrupalCon Mumbai 2016 with members of Acquia's Pune, India office: Prassad Shirgaonkar, Prassad Gogate, Prafful Nagwani, and Jeffrey A. "jam" McGuire in which we touch on Drupal and community in India, the history of the DrupalCon Prenote, Drupal's multilingual strengths, the Drupal Campus Ambassador Program in India, and more!
Jul 21 2016
Jul 21

Today I am very excited! A while ago I asked my friend David Ličen to help me improve appearance and UX for my personal blog. He carefully observed my desires and added some of his own ideas. When we agreed on the initial mock he proceeded with the theme implementation.

He finished his part a while ago. I needed to tweak few other things on the back-end too, which took me way too long to do. Today I finally decided to finish this and deployed the changes to the live website.

How do you like it?

Jul 21 2016
Jul 21

Republished from buytaert.net

Boston.gov's new homepage

Yesterday, the City of Boston launched its new website, Boston.gov, on Drupal. Not only is Boston a city well-known around the world, it has also become my home over the past 9 years. That makes it extra exciting to see the city of Boston use Drupal.

As a company headquartered in Boston, I'm also extremely proud to have Acquia involved with Boston.gov. The site is hosted on Acquia Cloud, and Acquia led a lot of the architecture, development, and coordination. I remember pitching the project in the basement of Boston's City Hall, so seeing the site launched less than a year later is quite exciting.

The project was a big undertaking, as the old website was 10 years old and running on Tridion. The city's digital team, Acquia, IDEO, Genuine Interactive, and others all worked together to reimagine how a government can serve its citizens better digitally. It was an ambitious project as the whole website was redesigned from scratch in 11 months; from creating a new identity, to interviewing citizens, to building, testing and launching the new site.

Along the way, the project relied heavily on feedback from a wide variety of residents. The openness and transparency of the whole process was refreshing. Even today, the city made its roadmap public at http://roadmap.boston.gov and is actively encouraging citizens to submit suggestions. This open process is one of the many reasons why I think Drupal is such a good fit for Boston.gov.

Tell Us What You Think form

More than 20,000 web pages and one million words were rewritten in a more human tone to make the site easier to understand and navigate. For example, rather than organize information primarily by department (as is often the case with government websites), the new site is designed around how residents think about an issue, such as moving, starting a business or owning a car. Content is authored, maintained, and updated by more than 20 content authors across 120 city departments and initiatives.

Screenshot of Towed Cars page

The new Boston.gov is absolutely beautiful, welcoming and usable. And, like any great technology endeavor, it will never stop improving. The City of Boston has only just begun its journey with Boston.gov—I’m excited see how it grows and evolves in the years to come. Go Boston!

Panel on stage at Boston.gov launch

Dries on stage at Boston.gov launch

Dries and Boston mayor, Marty Walsh

Last night, there was a launch party to celebrate the launch of Boston.gov. It was an honor to give some remarks about this project alongside Boston mayor, Marty Walsh (pictured above), as well as Lauren Lockwood (Chief Digital Officer of the City of Boston) and Jascha Franklin-Hodge (Chief Information Officer of the City of Boston).

Jul 21 2016
Jul 21
The before and after of Boston.gov

Yesterday the City of Boston launched its new website, Boston.gov, on Drupal. Not only is Boston a city well-known around the world, it has also become my home over the past 9 years. That makes it extra exciting to see the city of Boston use Drupal.

As a company headquartered in Boston, I'm also extremely proud to have Acquia involved with Boston.gov. The site is hosted on Acquia Cloud, and Acquia led a lot of the architecture, development and coordination. I remember pitching the project in the basement of Boston's City Hall, so seeing the site launched less than a year later is quite exciting.

The project was a big undertaking as the old website was 10 years old and running on Tridion. The city's digital team, Acquia, IDEO, Genuine Interactive, and others all worked together to reimagine how a government can serve its citizens better digitally. It was an ambitious project as the whole website was redesigned from scratch in 11 months; from creating a new identity, to interviewing citizens, to building, testing and launching the new site.

Along the way, the project relied heavily on feedback from a wide variety of residents. The openness and transparency of the whole process was refreshing. Even today, the city made its roadmap public at http://roadmap.boston.gov and is actively encouraging citizens to submit suggestions. This open process is one of the many reasons why I think Drupal is such a good fit for Boston.gov.

Boston gov tell us what you think

More than 20,000 web pages and one million words were rewritten in a more human tone to make the site easier to understand and navigate. For example, rather than organize information primarily by department (as is often the case with government websites), the new site is designed around how residents think about an issue, such as moving, starting a business or owning a car. Content is authored, maintained, and updated by more than 20 content authors across 120 city departments and initiatives.

Boston gov tools and apps

The new Boston.gov is absolutely beautiful, welcoming and usable. And, like any great technology endeavor, it will never stop improving. The City of Boston has only just begun its journey with Boston.gov - I’m excited see how it grows and evolves in the years to come. Go Boston!

Boston gov launch event Boston gov launch event Boston gov launch event Last night there was a launch party to celebrate the launch of Boston.gov. It was an honor to give some remarks about this project alongside Boston Mayor Marty Walsh (pictured above), as well as Lauren Lockwood (Chief Digital Officer of the City of Boston) and Jascha Franklin-Hodge (Chief Information Officer of the City of Boston).
Jul 21 2016
Jul 21

There are many talented designers with the ability to create a fabulous, responsive, web design worthy of the term “screen candy.” But looks aren’t everything and website design is not just art. When a website fails to engage the visitor, it’s often due to the designer’s failure to plan strategically.

A vital step in any website design project is to find out how the website will be used and understand the business behind it. What good is a blog targeted to senior citizens if the small fonts and low contrast make it a challenge to read? How successful is the ecommerce site when the visitor doesn’t complete their purchase because of a poorly structured checkout process? How can an educational website inform the user if the content library is unorganized and the user can’t find what they’re searching for? Before getting started on creating that beautiful website, here are some valuable questions to ask:

What’s the Goal?

In design school, this is the first question we learned to ask. Knowing the goal of the design is the key to unlocking the information needed in order to provide the best solution for your client: a website that attracts, informs, and engages the new and returning visitor. You need a clearly defined ‘Goal’ statement. The statement should be ‘actionable’ and ‘measurable. This will  guide you through the design process as you ask the question: “does this design accomplish the goal?”

An example of a website goal that provides online learning for children might be: “To become an authoritative learning resource for children ages K–8th grade, while providing fresh, quality content on the website.” We want to accomplish this by, “regularly adding new information through new classes and blog posts from professionals, establishing trust by highlighting case studies and targeted free offerings, and marketing the site through other websites and social media.”

Talk to your client. They know their business better than anyone and should have a clear idea of the main goal of their website. If they don’t know, work with them until you establish this essential element needed to create an interface that serves a meaningful function. Whether it be to inform the visitor, entertain them, provide a service, or sell a product, the main focus of the website design should work to achieve this primary organizational goal.

Who is the Audience?

It is said with good reason to “Know Thy User.” A well-known design (and business) best practice is defining the target audience. The audience of the website will not only influence the design elements, but also the voice of the editorial content and the way it’s organized. Answering this question is not always easy, and there is not always just one answer. Often, this step is aided with various tools such as conducting surveys, developing user personas, researching analytics, exploring the competition, and obtaining various insights from social media and email service providers.

What’s the Brand Image?

A design should accomplish a meaningful function, while also support the overall brand message the client wants to convey. Defining the brand message for a website is not just about the always important logo and color palette, but also includes special considerations for the use of icons, imagery, typography, and the ‘voice’ of the editorial content. The way the website behaves – how the user interacts with the various elements  – is another important tool often used to help clients set themselves apart from their competition.

If the client doesn’t have a ‘brand’ image or has no established digital identity, probe further with another question and let their answers paint the picture: “What do you want your website design to ‘say’ about your company and/or service?” Answers could range from “We’re fun and hip” to “Zen, peaceful, and calm”. Whatever the response, it will most likely help guide the layout and overall graphic approach to convey the message behind the brand.

Are There Accessibility Concerns for Brand Elements?

Considerations for accessibility should always be made when determining the best implementation for brand elements in the digital space. Special care is sometimes needed to navigate the political waters of brand color negotiation, so addressing potential accessibility concerns before beginning the design process will save time down the road.

Are the colors accessible? Not all branding agencies provide style guides including color palettes with enough contrast to pass basic accessibility standards in the digital format. Be sure to test the contrast of the foreground and background values for each potential color combination, and pay special attention to the font colors before including them in the design. If the color combinations don’t pass, there are tools available that will help with making adjustments to improve the contrast.

What are the brand fonts? The font size for all device sizes and the font style are considerations that should also be made. Are they available in web format and are they easy to read at a small size? Web fonts load faster, enlarge clearer, and are easier to translate. Certain font styles are found to be easier to read by those with Dyslexia when the ascenders and descenders are extreme, the counter is defined, and ALL CAPS are used at a bare minimum.

Thoughtful consideration of the brand elements prior to beginning the design will help to ensure all audiences including the color blind, vision impaired, and those with reading disabilities will be able to engage and interact with the website as the design intends.

What and Where is the Content?

Understanding the content that will be included in the website will help guide the architecture, the layout structure, and the ways it’s designed. Good organization leads to a carefully crafted navigation and an enjoyable user experience, helping the website not only look good but also serve it’s purpose.

  • Will the content include an extensive amount of copy?
  • How will the text files be provided?  
  • Who is the primary contact for the content?
  • How large is the image library?
  • Are the image sizes and resolution suitable for retina devices?
  • If the image library is small: are there plans for a photo shoot in the near future, or is stock photography an option?
  • Will videos be added? If so, what is the source of the video files?

If the website is a redesign, review each main section with your client to discover what is no longer relevant and possible changes they would like to see moving forward. If it’s a new website design, at the very minimum you’ll need a Content Outline with the names and categories of each section in order to determine the page templates and main navigational structure best suited for the design and user experience.

Additional Resources
Easy Ways to Make Your Website More Accessible | Blog Post
Designing With Personas | Blog Post
Why Web Analytics Are Important for Your Business | Video

Jul 21 2016
Jul 21

I'm super excited to be invited to be a keynote speaker for this year's DrupalCamp WI (July 29/30). If you're in the area you should attend. The camp is free. The schedule is shaping up and includes some great presentations. Spending time with other Drupal developers is by and large the most effective way to learn Drupal. So sign-up, and come say hi to Blake and me.

Why is Drupal hard?

The title of my presentation is "Why is Drupal Hard?" It is my belief that if we want to continue to make it easier for people to learn Drupal we first need to understand why it is perceived as difficult in the first place. In my presentation I'm going to talk about what makes Drupal hard to learn, why it's not necessarily accurate to label difficult as "bad", and what we as individuals and as a community can do about it.

As part of the process of preparing for this talk I've been working on forming a framework within which we can discuss the process of learning Drupal. And I've got a couple of related questions that I would love to get other people's opinions on.

But before I can ask the question I need to set the stage. Close your eyes, take a deep breath, and imagine yourself in the shoes of someone setting out to be a "Drupal developer."

Falling off the Drupal learning cliff

Illustration showing the scope of required knowledge across the 4 phases of learning Drupal. Small at phase 1, widens quickly at phase 2, slowly narrows again in phase 3 and through phase 4.

When it comes to learning Drupal, I have a theory that there's an inverse relationship between the scope of knowledge that you need to understand during each phase of the learning process and the density of available resources that can teach it to you. Accepting this, and understanding how to get through the dip, is an important part of learning Drupal. This is a commonly referenced idea when it comes to learning technical things in general, and I'm trying to see how it applies to Drupal.

Phase 1

Graph showing Drupal learning curve, showing exponential growth at phase 1

When you set out to start, there's a plethora of highly-polished resources teaching you things that seem tricky but are totally doable with their hand holding. Drupalize.Me is a classic example: polished tutorials that guide you step-by-step through accomplishing a pre-determined goal. During this stage you might learn how to use fields and views to construct pages. Or how to implement the hook pattern in your modules. You don't have a whole lot of questions yet because you're still formulating an understanding of the basics, and the scope of things you need to know is relatively limited. For now. As you work through hand-holding tutorials, your confidence increases rapidly.

Phase 2

Graph of Drupal learning curve showing exponential decay of confidence relative to time at phase 2, the cliff

Now that you're done with "Hello World!", it's time to try and solve some of your own problems. As you proceed you'll eventually realize that it's a lot harder when the hand-holding ends. It feels like you can't actually do anything on your own just yet. You can find tutorials but they don't answer your exact question. The earlier tutorials will have pointed you down different paths that you want to explore further but the resources are less polished, and harder to find. You don't know what you don't know. Which also means you don't know what to Google for.

It's a much shorter period than the initial phase, and you might not even know you're in it. Your confidence is still bolstered based on your earlier successes, but frustration is mounting as you're unable to complete what you thought would be simple goals. This is the formulation of the cliff, and, like it or not, you're about to jump right off.

Phase 3

Graph of Drupal learning curve showing relatively flat and low confidence over time at phase 3

Eventually you'll get overwhelmed and step off the cliff, smash yourself on the rocks at the bottom, and wander aimlessly. Every new direction seems correct but you're frequently going in circles and you're starving for the resources to help. Seth Godin refers to this as "the dip", and Erik Trautman calls it the "Desert of Despair". Whatever label you give it, you've just fallen off the Drupal learning cliff. For many people this is a huge confidence loss. Although you're still gaining competence, it's hard to feel like you're making progress when you're flailing so much.

In this phase you know how to implement a hook but not which hook is the right one. You know how to use fields but not the implications of the choice of field type. Most of your questions will start with why, or which. Tutorials like those on Drupalize.Me can go a long ways toward teaching you how to operate in a pristine lab environment, but only years of experience can teach you how to do it in the real world. As much as we might like to, it's unrealistic to expect that we can create a guide that answers every possible permutation of every question. Instead, you need to learn to find the answers to the questions on your own by piecing together many resources.

The scope of knowledge required to get through this phase is huge. And yet the availability of resources that can help you do it is limited. Because, as mentioned before, you're now into solving your own unique problems and no longer just copying someone else's example.

Phase 4

Graph of Drupal learning curve showing upswing of confidence, linear growth, at phase 4

If you persevere long enough you'll eventually find a path through the darkness. You have enough knowledge to formulate good questions, and the ability to do so increases your ability to get them answered. You gain confidence because you appear to be able to solve real problems. Your task now is to learn best practices, and the tangential things that take you from, "I can build a website", to "I can launch a production ready project." You still need to get through this phase before you'll be confident in your skills as a Drupal developer, but at this point it's mostly just putting in time and getting experience.

During this phase, resources that were previously inaccessible to you are now made readily available. Your ability to understand the content and concepts of technical presentations at conferences, industry blog posts, and even to participate in a conversation with your peers is bolstered by the knowledge you gained while wandering around the desert for a few months. You're once again gaining confidence in your own skills, and your confidence is validated by your ability to continue to attain loftier goals.

And then some morning you'll wake up, and nothing will have changed, but through continually increasing confidence and competence you'll say to yourself, "Self, I'm a Drupal developer. I'm ready for a job."

What resources can help you get through phase 3?

So here's my questions:

  • What resources do you think are currently available, and useful, for aspiring Drupal developers who are currently stuck in phase 3, wandering around the desert without a map asking themselves, "Panels or Context?"?
  • What resources do you think would help if they existed?
  • If you're on the other side, how did you personally get through this dip?

Responses from Lullabot

I asked this same question internally at Lullabot a few days ago, and here are some of the answers I received (paraphrased). Hopefully this helps jog your own memory of what it was like for yourself. Or even better, if you're stuck in the desert now, here's some anecdotal evidence that it's all going to be okay. You're going to make it out alive.

For me, it was trial and error. I would choose a solution that could solve the particular problem at hand most efficiently, and then I would overuse it to the extreme. The deeper lessons came months later when changes had to be made and I realized the mistakes I had made... Learning usually came also from working with others more experienced. Getting the confidence to just read others' code and step through it is also a big plus.

building something useful++. That's the absolute best way. Can't believe I forgot to mention it. Preferably something that interests you or fulfills your own need. You still fall off the cliff, but you at least see the fall coming, and your ability to bounce back is better.

At this stage I find that the best resources are people, not books or tutorials. A mentor. Someone that can patiently listen to your whines and frustrations and suggest the proper questions to ask, and who can give you the projects and assignments that help you grow and stretch.

Everything I know about Drupal I know through years of painful trial and effort and shameless begging for help in IRC.

I spent a lot of time desperately reading Stack Overflow, or trying to figure a bug out from looking at an issue where the patch was never merged, or reading through a drupal.org forum where somebody tries to solve something but then just ends with "nevermind, solved this" without saying why.

I'd agree that people is what gets you through that. I learned IRC and how to write patches and get help from individuals and that is when the doors opened.

Another approach that really boosted me to the next level, especially early on in my career as a developer, was to work with someone that you can just bounce ideas off of. I'll never forget all the hacking sessions Jerad and I had back in the day. Coding at times can be boring, or the excitement of doing something awesome is self-contained. Being able to share ideas, concepts, and example code with someone that appreciates the effort or awesomeness of something you've done and at the same time challenges you to take it to the next level is priceless.

Printing out the parts of Drupal code I wanted to learn: node, taxonomy and reading comments and code like a gazillion times.

Try and code something useful so I could ask others for help. That's how I wrote the path aliasing module for core.

I often find that as you get into more complicated, undocumented territory, being able to read code is super valuable. You can often get lost in disparate blog posts, tutorials and forums that can lead you all sorts of ways. The code is the ultimate source of truth. Sometimes it takes firing up a debugger, stepping through the parts that matter to see how things are connected and why.

Jul 21 2016
Jul 21

Extending in Twig is a method by which one template can inherit content from another template, while still being able to override parts of that content. This relationship is easy to imagine if you are familiar with Drupal’s default system of template inheritance.

A theme can have multiple page templates, many node templates, even more field templates, and a plethora of block and Views template. And it is common for those templates to largely be identical, save for a snippet of markup or some logic. The advantage in extending templates is reducing this duplication, thereby simplifying architecture and easing maintenance.

Let’s say, for example, you want to change the template for a specific block, adding a wrapper div around the main content area. This might be done by copying the standard block template and giving it a name specific to your block.

Classy’s block.html.twig template
{%
  set classes = [
    'block',
    'block-' ~ configuration.provider|clean_class,
    'block-' ~ plugin_id|clean_class,
  ]
%}
<div{{ attributes.addClass(classes) }}>
  {{ title_prefix }}
  {% if label %}
    <h2{{ title_attributes }}>{{ label }}</h2>
  {% endif %}
  {{ title_suffix }}
  {% block content %}
    {{ content }}
  {% endblock %}
</div>

Copied to block--my-special-block.html.twig
{%
  set classes = [
    'block',
    'block-' ~ configuration.provider|clean_class,
    'block-' ~ plugin_id|clean_class,
  ]
%}
<div{{ attributes.addClass(classes) }}>
  {{ title_prefix }}
  {% if label %}
    <h2{{ title_attributes }}>{{ label }}</h2>
  {% endif %}
  {{ title_suffix }}
  {% block content %}
    <div class=”content-wrapper”>{{ content }}</div>
  {% endblock %}
</div>

This accomplishes your goal. You have a template specific to this particular block, and a wrapper div just where you need it. Following the same method, and with a complex site, you can end up with lots of different block templates (or node templates, or field templates, or … you get the idea.)

But, now you have a different problem. The majority of the template is duplicated. All the CSS classes, the outer wrapper, the markup for the block title, etc. If any of that needs to be changed, like changing all block titles from H2s to H3s, you have to update every single one of those templates.

Even if this happens infrequently enough not to be considered time consuming, it is still prone to errors. You might make a mistake in one template, miss one that needs changing, or even change one that should not be changed.

This is where {% extends %} comes in

Extending templates allows you to reference the original template, and only override the parts that are unique to the child template.

In the block example, we can create a block--my-special-block.html.twig template with this content:

{% extends "block.html.twig" %}
{% block content %}
  <div class=”content-wrapper”>{{ parent() }}</div>
{% endblock %}

That’s it. That is the whole template. Twig uses the original block.html.twig template as the main template, and only uses what we override in the more specific block--my-special-block.html.twig template.

The parent() function simply returns all of the content within the {% block %} tags in the original template. This saves us from having to duplicate that content; keeping the template simple, and future proofing it. If any of that content changes in the original template, we don’t have to update the block--my-special-block.html.twig template.

In this example, the content in the original template is fairly simple, only printing the content variable, but imagine if there was a large amount of multiline html and Twig code wrapped in those block tags.

Twig blocks, not Drupal blocks!

This overriding is done by using Twig blocks. (Terminology is fun!) The Twig block is what you see identified by the {% block %} and {% endblock %} tags. The word "content" is the identifier for the block. You can have multiple blocks in a single template.

In the block--my-special-block.html.twig template file, we can do anything we want inside the block tags. Twig will replace the original templates “block” with the one in block--my-special-block.html.twig.

What else?

Well, you have access to pretty much everything in the main template, except the printed markup. So, for example, you can modify the variables it uses.

{% extends "block.html.twig" %}
{% set attributes = attributes.addClass(‘super-special’) %}

This template will add a CSS class called "super-special" to the attributes printed in the outer wrapper of the original block template. The alternative would be to copy the content of the entire block.html.twig template just to add this class to the ‘classes’ array at the top of the file.

You can also just set a variable that will be used by the original template.

{% extends "block.html.twig" %}
{% set foo = 'yellow' %}

Imagine a series of variant field or content type templates that set variables used by the original template for classes, determining structure, etc.

You can even add Twig logic.

{% extends "block.html.twig" %}
{% block content %}
  {% if foo %}
    <div class=”content-wrapper”>{{ parent() }}</div>
  {% else %}
    {{ parent() }}
  {% endif %}
{% endblock %}

Pretty much anything you still might want to do with Twig, inside or outside of the block tags, you can still do.

Things to note

Before you jump right in, and bang your head against a wall trying to figure out why something isn’t working, there a few things to know.

  • The {% extends %} line needs to be at the top of the file.
  • When overriding markup, you can only change what is within block tags in the original template. So add {% block %} tags around anything you might want to modify.
  • You cannot print additional things outside of the overriding block tags. You will have an extends line. You can set variables, add comments, add logic, and override blocks. You cannot put other pieces of markup in the template. Only markup that is inside a block.
  • If Drupal does not extend the correct template, based on what you expect from template inheritance, you may have to explicitly state the template you want.
    Example: {% extends "@classy/block/block.html.twig" %}

Additional Resources

Jul 20 2016
Jul 20

Week 8 is over and we are just one month away from Google Summer of Code final evaluation. I mentioned in my last weekly summary that I would work on documentation about implementing a Social Auth integration. I started doing so, but in our last meeting Mateu, one of my mentors, suggested to start working on an implementer for Social Post.

Series on Social Auth implementer.

This week, I created the first two posts in the series for creating a Social Auth implementer. This real-life example is based on the Social Auth Google code. In these posts, I described how to define the implementer's dependencies in the info.yml and composer.json files and I described the Settings manager class.

This series will be updated in coming weeks. You can take at look at it now at http://blog.gvsanz.net/tag/social-api. I will also create a repository with comprehensibly documented code, so you can choose which approach suits you better to understand the code.

Social Post implementer.

As I mentioned above, one of the mentors asked me to begin working on a implementer for Social Post. Thus, we decided to work on one for Twitter. I might admit, it has been quite challenging so far; nonetheless, I have been able to move forward thanks to my mentors' support.

As of current, Social Post Twitter would allow site builders to give (drupal) permissions to specific roles. This permissions will allow users with the right role to grant (twitter) permissions to the site in order to tweet on their behalf.

To autotweet, the site should store an oauth_token and an oauth_token_secret, which are provided by twitter when the user grants permissions. These values should be stored in the database, therefore, I was working on creating a Twitter user entity.

This module is still in development. These are screenshots of how it looks so far.

Social Post Twitter settings formSocial Post Twitter settings formTwitter User entity collectionTwitter User entity collection

There is not any content for this entity as I have not worked on the Twitter authentication yet.

Next week

For next week, I will continue working on the Social Post implementer named Social Post Twitter. I would like to say I will finish it by then, but I will probably not be able to accomplish this. This implementer requires a little more work than any of the ones I worked before. Nevertheless, I will try to have an immature version for next week.

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

Stay tuned for the next weekly summary!

Jul 20 2016
Jul 20

This week, I'm fortunate enough to be attending Drupal GovGon, which brings together Drupal developers, users, and more in Washington, DC. It's a great chance not only to learn the latest techniques, but also to see how Drupal is being used for everything from government projects to non-profits to entertainment.

Today's keynote was an insightful conversation between Sibyl Edwards and Allyson Kapin on building diversity into both our companies and our projects. In the early stages of designing a new platform, for instance, a team may wish to consider how to mitigate its potential to be used for hate speech, or whether their sign-up forms are forcing people to choose between categories with which not everyone identifies.

Later in the morning, I attended a more technical talk by Will Vedder on decoupled Drupal, also known as "headless Drupal." Thanks to Drupal 8's built-in RESTful API integration, it's now easier than ever to combine the powerful back-end features of Drupal with the flexibility and speed of front-end javascript frameworks such as Angular or Backbone. While Drupal's traditional approach remains the best solution for many websites, this integration promises exciting new possibilities for dynamic web applications.

After lunch, Mike Potter, the lead maintainer of the popular "Features" module, spoke about the differences in Features between Drupal 7 and Drupal 8. With the latter's core support for importing and exporting configuration, Features becomes less critical; however, it remains an invaluable tool for organizing related pieces of configuration and detecting dependencies. Finally, Nick Grace led a session on the power of Google Analytics for setting and tracking business goals on Drupal sites, from tracking page views and conversions to conducting full A/B testing.

All in all, it's been an educational and enjoyable day. Stay tuned tomorrow for day 2!

Jul 20 2016
Jul 20

I have been porting Search Configuration module from Drupal 7 to 8 as part of this year’ s Google Summer of Code (GSoC). This summer program is an opportunity for university students to work on projects connected with open source organisation. I have been really lucky to be a part of this initiative. I could explore deep of more technologies, version control systems as part of my project in Drupal. This gives young students a platform where they are assigned mentors who are experts and experienced in various software.

Last week, I could learn some of the Drupal concepts as part of this module port. So, let me begin with the Drupal 7 property. The t function translates a string to the current language or to a given language. This makes the strings used in Drupal translatable. This generally takes up the format:

t($string, array $args = array(), array $options = array());

Here, $string is the string containing the English text to get translated.

$args: An associative array of replacements to make after translation.

$options: An optional associative array of additional options, with the following elements: lang code and context.

This t function has got some alteration in the Drupal 8. It has been replaced by the $this->t() by making use of \Drupal\Core\StringTranslation\StringTranslationTrait. 

 The translatable markup returns a string as a result of this process.

Another important aspect which I dealt was the roles. This is an important feature  for any module as it  deals with the security constraints of the module. Roles are often manipulated to grant certain permissions. What we have to do is that, initially, load the particular role to be manipulated and then provide the permission which is to be granted.

$role = Role::load('access page.');
$role->grantPermission('access comments');
$role->save();

These role functions help us to load the roles and manipulate the permissions assigned to it quite easily. Thus, turns out to be really helpful in dealing with permissions.

I have been also dealing with writing the simple test for my module. In one of my previous blog posts, I have introduced the PHP unit testing.  The simple test tests the web oriented functionality of the module. It needs a good understanding of the behaviour of the module to write an effective test. Tests are often really important to identify the flaws of a functionality and to correct it accordingly. I will be writing the simple tests for my module in the coming days. I will be sharing you the concept of this mode of testing in my next blog post.

Stay tuned for further developments on this blog post.

Jul 20 2016
Jul 20

Drupal 8.2.0, the next planned minor release of Drupal 8, is scheduled for Wednesday, October 5, 2016. Minor releases include new features, usability improvements, and backwards-compatible API improvements. Here's what this means for core patches.

Drupal 8.2.0-beta1 will be released the week of August 3

  • In preparation for the minor release, Drupal 8.2.x will enter a beta phase the week of August 3.
  • Developers and site owners can begin testing the beta.
  • The 8.3.x branch of core will be created, and future feature and API additions will be targeted against that branch instead of 8.2.x.
  • All outstanding issues filed against 8.2.x will be automatically migrated to 8.3.x once it is opened.
  • During the beta phase, core issues will be committed according to the following policy:
    1. Most issues that are allowed for patch releases will be committed to all supported minor branches (8.1.x, 8.2.x, and 8.3.x) for the duration of the beta. Drupal 8.0.x is not supported anymore and changes are not made to that branch.
    2. Issues specific to added 8.2.x functionality, or disruptive changes that have a positive impact outweighing their disruption, will be committed to both 8.2.x and 8.3.x. (Such issues can be moved back to the 8.2.x branch after the automatic migration.)
    3. Most issues that are only allowed in minor releases will be committed to 8.3.x only.

Drupal 8.2.0-rc1 will be released September 7

  • The release candidate phase for the minor release begins on September 7, and starting on that date, the 8.2.x branch will be subject to release candidate restrictions, with only critical fixes and certain other limited changes allowed.
  • September 7 is also the final scheduled patch release window for 8.1.x, and it will not receive further development or support after that date aside from its final security release window on September 21.
  • All outstanding issues filed against 8.1.x will be automatically migrated to 8.2.x after the final 8.1.x patch release. Bug reports after September 7 should be targeted against the 8.2.x branch.
  • Minor versions may include changes to user interfaces, translatable strings, themes, internal APIs like render arrays and controllers, etc. (See the Drupal 8 backwards compatibility and internal API policy for details.) Developers and site owners should test the release candidate to prepare for these changes.
  • 8.3.x will remain open for new development during the 8.2.x release candidate phase.

See the Drupal core release cycle overview, Allowed changes during the Drupal 8 release cycle, and Drupal 8 backwards compatibility and internal API policy for more information.

As a reminder, we have until the start of the beta to add great new features to Drupal 8.2.x. Stabilizing experimental modules (such as Migrate and BigPipe), new features for workflows, and usability and bugfixes are all priorities for 8.2.0. Help with these feature requests and initiatives now for a great Drupal 8.2.0!

Jul 20 2016
Jul 20

We recently launched a new case tracker for foster ed youth designed to improve their educational outcomes in partnership with The National Center for Youth Law (NCYL). The web application replaces their existing platform, Goal Book, which lacked the flexibility they needed to meet their requirements. A web application differs from a website in that a website primarily provides content where a web application primarily provides tools.

The project presented us with an opportunity to do extensive custom development with our favorite new platform, Drupal 8. D8’s many developer experience improvements, including standardized object-oriented development methods, allowed us to meet NCYL’s requirements efficiently and with a level of quality that would have been more difficult on Drupal 7. In addition, we were able to accelerate the release of RedHen CRM on Drupal 8, which lives at the heart of the application managing all of the contacts, organizations, and relationships.

To enhance the utility of the application, we made an early decision to customize every URL a user would interact with. As most of the functionality would revolve around nodes, we wanted to make sure we avoided URLs like /node/256/edit that don’t give the user any indication of which part of the application they’re using.

Implementation

If you wanted to customize URLs in Drupal 7, you could use the Pathauto module. You can still do that in Drupal 8, but D8’s routing system can be coaxed into doing something similar. It works on admin pages, too, which was perfect for NCYL’s needs.

Overriding Existing Node Paths

As an example, let’s say you have a node type specifically for storing information about schools: a School Node. The standard admin path for adding a School Node would be something like this:

/node/add/school

But, add a custom module with route configuration and you can have this:

/school/add

For simplicity, we’ll call our module school.module. The directory structure looks like this:

modules/
  school/
    school.module
    school.routing.yml

The route configuration sits inside school.routing.yml and looks like this:

school.add:
  path: '/school/add'
  defaults:
    _controller: '\Drupal\node\Controller\NodeController::add'
    _title: 'Add School'
    node_type: 'school'
  requirements:
    _node_add_access: 'node:school'

Line by line:

school.add:

This is the name of the route. Route names should be unique and usually start with the name of your module.

path: '/school/add'

The path the route points to. This is the part that comes after your site’s base URL.

_controller: '\Drupal\node\Controller\NodeController::add'

This tells the route to use the NodeController, provided by the Node module. No need for a custom controller here.

_title: 'Add School'

This sets the page title of the node add form.

_node_add_access: 'node:school'

This is an access handler that ensures the user has permission to add a node of type “school.”

Providing a custom path to edit School Nodes is even easier:

school.edit:
  path: '/school/{node}/edit'
  defaults:
    _entity_form: 'node.edit'
  requirements:
    node: \d+
    _entity_access: 'node.update'

We no longer need to tell the route which controller to use or what type of node we’re using. Drupal 8’s Entity API figures it out using the node ID passed in the URL.

Line by line again:

path: '/school/{node}/edit'

The path now contains a placeholder, {node}, which represents the node ID in the URL.

_entity_form: 'node.edit'

The form we want to use to edit the node.

node: \d+

Some validation to ensure the URL contains the right data type for a node ID. By specifying the regular expression pattern \d+, we are telling Drupal to only use this route when {node} is one or more digits. The route will match a URL like /school/32/edit, but will not match /school/lincoln-high/edit.

_entity_access: 'node.update'

An access handler, ensuring the user has permission to update this node. No need to specify the node type, as we did when adding a node.

Finally, a route for viewing the node:

school.view:
  path: '/school/{node}'
  defaults:
    _controller: '\Drupal\node\Controller\NodeViewController::view'
  requirements:
    node: \d+
    _entity_access: 'node.view'

Very similar to the node edit route, just with a different path and controller.

For a more thorough explanation of routes and route options not covered here, check out the official docs.

Custom Controllers

What if you want to provide a custom controller for adding a node and still take advantage of Drupal’s permissions system? Routes can do that, too.

Let’s introduce a Teacher Node and an accompanying module.

modules/
  school/
  teacher/
    src/
      Controller/
        TeacherController.php
    teacher.module
    teacher.routing.yml

teacher.routing.yml looks like this:

teacher.add:
  path: '/teacher/add'
  defaults:
    _controller: '\Drupal\teacher\Controller\TeacherController::addTeacher'
    _title: 'Add Teacher'
    node_type: 'teacher'
  requirements:
    _node_add_access: 'node:teacher'

Very similar to the route we used to add School Nodes, but with a custom controller.

TeacherController.php looks like this:

<?php
namespace Drupal\teacher\Controller;

use Drupal\node\NodeTypeInterface;

class TeacherController extends ControllerBase {

  public function addTeacher(NodeTypeInterface $node_type) {

  }

}

The addTeacher function is where you would add your custom code for adding Teacher Nodes.

That’s how you can use core Drupal 8 functionality to make your Drupal admin pages a little more user friendly.

Get In Touch

Questions? Comments? We want to know! Drop us a line and let’s start talking.

Learn More Get In Touch
Jul 20 2016
Jul 20

When I started making sites with Drupal 8 I missed a special body class that I sometime need for theming as well as other times, and that's the language body class. When making multilingual sites this comes in handy sometimes. For Drupal 7 this was made possible by the Internationalization (i18n) module, but since that module has been moved into core in Drupal (source) that special body-class-adding-thingamajig seems to have vanished.

After facing the need of language id when making this site I started to search for a solution, but came up with very few answers. When I solved it I thought I could make a short entry to spread the knowledge.

My needs

Basically, I had two needs for the language class to be added to my theme. 

  1. I wanted to hide some of the meny items depending on which language the content was presented in. (I later solved this in another way in my theme, but that was the initial need for a body class representing the current language.)
  2. I have two different RSS-feeds, one for posts in English and one for posts in Swedish. To make it work 100%, the path to the feed needed the language id as well. This was the latter need for me, and also the need that made it to the final site.

The theme

The themes I've used for Drupal 8 haven't had the language flag/path, but some themes may have implemented it, so if you have the path in the body class then you probably don't need to read this.

The example I'm going to show you is from the the Bootstrap Clean Blog, which I use for this site, and I will show you the code for adding the language id to it.

The files

In the theme folder of Bootstrap Clean Blog you need to locate two files:

  • bootstrap_clean_blog.theme, which is in the root of the theme folder called bootstrap_clean_blog and
  • html.html.twig which is located in the templates folder.

In bootstrap_clean_blog.theme (or any other .theme-file you might have in the theme you're using/developing) add the following code snippet to it:

function bootstrap_clean_blog_preprocess_html(&$variables) {
  $language = \Drupal::languageManager()->getCurrentLanguage()->getId();
  $variables['language'] = $language;
}

If you're using a different theme than Bootstrap Clean Blog, the name of the theme-file is something like XYZ.theme, where XYZ is the name (lowercase with underscores) of the theme. For example, if you're using the Pixture Reloaded theme, the theme-file is called pixture_reloaded.theme.

The code above calls for the language by getCurrentLanguage() and assigns the value to the variable $language. After that the value of $language is assigned to the global variable array $variables['language'].
You could shorten this down to

function bootstrap_clean_blog_preprocess_html(&$variables) {
  $variables['language'] = \Drupal::languageManager()->getCurrentLanguage()->getId();
}

but I wrote it on two separate rows to make it more clear. The shorter code snippet is quite allright, though, and you can use that in your .theme-file.

Next up: The TWIG-file

Allright, so far we've collected the language and stored it in a global variable. Now it's time to make it visible on the webpage, to print it. This is done via TWIG, a fast and secure template engine that Drupal 8 started using. To print the $variables['language'] you write the following "twig code" in your template where you want it to be printed.

{{ language }}

So, in my example, if we want to print it in the body class, I open up the template html.html.twig in the templates folder of the theme and search for the line where the body is set. It looks like this:

<body{{ attributes.addClass(body_classes) }}>

It prints the following HTML when rendered in a browser:

<body class="user-logged-in path-frontpage">

Though, we can't just add {{ language }} to the body tag since it won't be a part of the {{ attributes.addClass(body_classes) }}. Those are set a couple of lines up, but it's easy to fix it. They look like this:

{%
  set body_classes = [
    logged_in ? 'user-logged-in',
    not root_path ? 'path-frontpage' : 'path-' ~ root_path|clean_class,
    node_type ? 'node--type-' ~ node_type|clean_class,
  ]
%}

In i similar way we add:

language ? 'lang-' ~ language|clean_class,

so the final result looks like this:

{%
  set body_classes = [
    logged_in ? 'user-logged-in',
    not root_path ? 'path-frontpage' : 'path-' ~ root_path|clean_class,
    node_type ? 'node--type-' ~ node_type|clean_class,
    language ? 'lang-' ~ language|clean_class, 
  ]
%}

Now comes the thing that's very important. After saving your theme-files, you must clear cache for the changes to appear. Click Configuration > Performance > Clear all cache. Then reload the page and check the source code of it et voilà - it works and the source code looks like this:

<body class="user-logged-in path-frontpage lang-en">

That's that. You can now use the class lang-en to distinguish your English pages and on your pages in another language it might look something like this:

<body class="user-logged-in path-node node--type-article lang-sv">

You can also use {{ language }} anywhere else, for example is you have the same need as I, to make a link language-dependant: 

<a href="http://www.adamevertsson.se/{{ language }}/feed">RSS</a>

which gives you the following complete HTML

<a href="http://www.adamevertsson.se/sv/feed">RSS</a>

or

<a href="http://www.adamevertsson.se/en/feed">RSS</a>

if the visitor is on the English part of the site.

Hope this helped you in some way. Happy drupaling!

Jul 20 2016
Jul 20

During the 8th week of Google Summer of Code 2016, we have started with adding support for posting comments via email. After getting the feedback from my mentors, there was some space to improve proposed solution. The suggestions were accepted and briefly explained below.

Comments in a submodule

As comments are supported through new handler plugin (MailhandlerComment), we decided to move it into a submodule - mailhandler_d8_comment. Following this approach, we can avoid too many dependencies on the main module. The submodule features: Inmail config entity that represents the handler, the plugin class and the related test coverage.

Configurable referenced entity type

With configurable referenced entity type of processed comments, we can support not only node entities but all the other “commentable” entities. In my opinion, this is a nice feature for site administrators in case they want to allow posting comments (for their articles or custom entities) as easy enough as sending an email.

Strict validation

Validation is the important topic in software development in general. In Drupal 8, there is an API made specifically for entity validation - Entity Validation API. It is recommended to use it before saving an entity. However, entity validation does not work as expected in a case of creating comments via API. The referenced entity ID and its bundle were not validated which required us to find a different approach. To accomplish this, we had to implement custom validation checks. They consist of:

  • Entity type validation - entity type is “commentable”

  • Referenced entity ID validation - referenced entity with provided ID actually exists

  • Bundle validation - identified entity bundle supports comments


Last week, besides the improvements made on the comment feature, I was working on the demo module improvements. The pull request has been submitted on Github and available for review. This module serves as an example module to show features of Mailhandler. It creates a sample “Mailhandler” content type (with a body field) and a new user with permissions to add content for “Mailhandler” content type and post comments. The GPG key field of this user was populated  with a sample key (both public and private GPG keys were added to the module) as well. Since last week, the example messages - sample comment and PGP clear-signed, MIME and MIME HTML emails are part of the demo module too. By enabling mailhandler_d8_demo, exploring Mailhandler features becomes very straightforward.

[embedded content]

Drupal 8 module demo: Mailhandler from Milos Bovan on Vimeo.

Also, the demo module adds a sample article attached to the front page. The idea is to have a descriptive article about Mailhandler features. Its content will be extended during the “documentation week”. Next week, I will be working on improving overall user experience and user interface of Mailhandler.

 

 

Jul 19 2016
Jul 19

DrupalCon is brought to you by the Drupal Association with support from an amazing team of volunteers.
Built on COD v.7, the open source conference and event management solution. Creative design by ADCI Solutions.
 
DrupalCon Dublin is copyright 2016. Drupal is a registered trademark of Dries Buytaert.

Jul 19 2016
Jul 19

In the last post of this series, we started declaring our module information (social_auth_google.info.yml) and its dependencies through a composer.json file. In this post, we will move on and start working on the routing, settings form, and Settings Manager.

Routes

Now that we have let Drupal about our module and its dependencies, it is time to define our routes. In the case of our Social Auth Google module, we'll need the following social_auth_google.routing.yml file

First, we define the route for our settings form. Then, we create a route for our method that redirects to Google Accounts for authentication. Last, we add another route which will be used as a callback for Google after the user successfully log in into his account and grant permissions.

For Google Login, the site builder needs to create a project in https://console.developers.google.com/ and provides some data defined in this routing file. More information can be found in this documentation page.

Settings Form

We need to declare our settings form, so site builders can add their Google project information. For this module, they should specify their Client ID and Client Secret. This is an example of how the form file looks like.

This settings form definition may change in coming weeks in order to provide more settings options. However, it won't be so different. You can refer to this issue to get updates

Settings manager

Now that we have defined the settings form which stores the data the site builder provides, we should be able to access that data. 

To achieve this, we should create settings file in src/Settings. In the case of Google, we need to get the Client ID and Client Secret, so we should retrieve that information from the Drupal Configuration Manager:

With this, we are able to get the Client ID (client_id) and Client Secret (client_secret) from social_auth_google.settings

But how is this class able to know it needs to get those keys from social_auth_google.settings? You have to specify it in a Network Plugin definition!

We will be looking more in detail about Network Plugins in the following post.

Jul 19 2016
Jul 19

In the last few months we have been working on the Social API project which tries to harmonize Social Networking functionality in Drupal. This project is divided in four main components which are:

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

In this series, I will be showing a real-life example to implement an integration for Social Auth. This series will be based on the Social Auth Google module.

Getting your hands dirty: .info.yml and composer.json files

To start, we have to let Drupal know that our module depends on the Social Auth module. Furthermore, as this module authenticates with Google,  we need to define the dependency (Google API PHP Client), using a composer.json file

In this example we use the Google PHP client; however, if you plan to work on an implementer for Twitter, you should look for the appropriate SDK. Make sure to implement official libraries if possible.

Now using Composer Manager, you can let Drupal download the library dependency you defined in the composer.json file. There is a description of this process in step 3 and 4 of this documentation page.

Jul 19 2016
Jul 19

Web applications today have many things in common, but at the core, there is only one thing that drives these applications - a thirst for data.

The topic of GraphQL is a big one - especially when deciding the future of Drupal web services - as was brought up by Dries Buytaert himself in his blog post, “Advancing Drupal’s web services. ”Dries states, “I believe that GraphQL and JSON API in core would be a big win for those building decoupled applications with Drupal...”

After attending Sebastian Siemssen’s session on “GraphQL meets Drupal” at DrupalCon NOLA, it was immediately apparent to me that whilst traditional REST is the more popular approach for fetching data, it may not be the best in solving many of the problems of handling hierarchical data. In comes GraphQL, a database querying language built by Facebook, to solve the limitations of REST - which may include overfetching, under fetching, multiple round-trips, and versioning issues.

A non-hypothetical real-world example

To demonstrate how GraphQL is advantageous over a traditional REST approach, Sebastian uses a Star Wars API as an example in which several pieces of information are desired - the name of the person, movie appearances (by name of the movie), and the home planet. In a traditional REST approach, a response object may return unnecessary data not required or used in an application (see http://swapi.co/api/people/1/ as an example), which results in overfetching. Since Drupal has a very heavy bootstrap and is continuously requesting resources, performance can quickly be impacted.

If we wanted to fetch more specific information based on a value returned from the object (let’s say, the “homeworld” of the person), another round-trip to the server will be required to access the endpoint for the “homeworld” name (see http://swapi.co/api/planets/1/). Multiple round-trips to the server are required when fetching complex, relational data structures.

In addition, maintaining several front-end applications (iOS, Android, JS) that use data served from the same API each might require different views and API versions, which makes versioning equally as important as preventing overfetching and multiple round-trips.

Ideally, we would want the specific information we desire in a single request in the same shape requested in and to do so, we need to think of data in terms of graphs.

How to fix this?

Try GraphQL! The GraphQL module helps us solves these problems. It generates a self-documented schema to expose the Drupal data graph (so it can be read by the GraphQL library) through the TypedData API. If you want to fetch the value of a field (and only that field, nothing else) on a specific node, GraphQL will fetch the node through the Entity API, extract the requested fields from the entity, and output the result in a formatted JSON. This prevents a bloated response of all the other fields and information associated with an entity that is not needed.

Pro-tip: There is a tool called GraphiQL (pronounced “graph-i-cal”) developed by Facebook to provide a functional IDE for your schemas.

To go more in depth, a more detailed explanation of how GraphQL works with Drupal can be accessed in the recording of Sebastian Siemssen’s session.

In Summary

This session was very much enjoyable, as it addresses important data access issues that come up more and more frequently in modern web applications. In the limited time he had, Sebastian Siemssen did a tremendous job in introducing GraphQL and demoed some complex Drupal queries using the GraphiQL interface. It was a valuable session and one that should not be missed if you are looking to optimize your applications.

More Resources on GraphQL

Additional Resources
Brain Food for Your Post-DrupalCon Slump | Blog Post
8 Insights and Useful Snippets for the D8 Rest Module | Blog Post
Introducing Decoupled Blocks Module: Decoupling In Drupal 8 Based on a Proven Model | Blog Post

Jul 19 2016
Jul 19

By now, you may have heard that we’re putting on a show: the ROW Roadshow, to be exact!

ROW stands for Results Oriented Websites, and it means just what it says. We think that all of our clients – and everyone in the United States! – should have a meaningful web presence, with a website that produces real results and helps them grow their company.

The ROW Roadshow is our way of taking that message to the people. We’ll be visiting 20 cities over the course of 3 months, and we’d love for you to be a part of it.

row roadshow cities

We’ll be hosting and a seminar in every city we visit. The seminar will cover the fundamentals of modern digital marketing, a demonstration of the Drupal CMS and its best marketing tools, and live website valuations.

THE ROW ROADSHOW SEMINARS

  1. Fundamentals of modern digital marketing: inbound marketing strategies and content marketing strategies
  2. Demonstration of Open Enterprise Pro, our Drupal distribution, and how Drupal modules can help marketers work more efficiently and effectively
  3. Live valuations of example websites submitted by seminar attendees.

We Need Your Help!

The website valuations are one of the most important parts of the ROW Roadshow. There’s no better way to demonstrate how digital marketing practices play out in real life. So take 30 seconds right now and submit your site for a free valuation.

Thanks so much! We can’t wait to see you on the road this fall!

If you’d like to learn more about the ROW Roadshow, please check out the website and our Sponsorship Kit.

If you’d like to help by becoming a sponsor, please let us know!

Jul 19 2016
Jul 19

On our first day as interns at Cheeky Monkey, we (Jared and Jordan) were given the task of exploring the somewhat uncharted waters of using Behat, an open source BDD (Behavior-driven development) testing framework, with Drupal 7.

Why BDD Testing?

We all know that testing is important, but why do we bother with “BDD” testing?

Behavior-driven development testing is exactly what it sounds like, testing the behavior of the site. This makes the tests very different than say a unit test.

Unit tests are often reliant on a small piece of code, such as an individual function, so if you change that function, you often have to change the test. With BDD tests, however, you write plain English “Scenarios” inside of specific “Features” or “Stories” to test how you expect the website to react in response to certain user actions. Having these tests available in your back pocket helps you catch bugs in unpredicted areas of your site when you’re implementing new features.

Now that we have the “why?” out of the way, it is time to get cracking on some serious detective work. We also need a sandbox to play around in with these foreign concepts. We set up a very basic Drupal 7 site on Pantheon and cloned it down on our local machines.

 

The Process:

Being relatively new to the world of development, and with Behat being fairly new to the world of Cheeky Monkey, we didn’t have many clues right off the bat. For the first few days of the project, we were on a quest to gather resources and knowledge. First stop? The wise sage, Google. We discovered that there was not a definitive Behat/Drupal tutorial out there, but there are plenty of little breadcrumbs to go off of. The most helpful resources for us were the Drupal Extension to Behat and Mink and the Behat Docs.

The first few days that we spent trying to piece everything together were filled with a constant flux of blind frustration, complete confusion and wonderful epiphanies. Over the course of around two weeks, we were able to put together a small set of features, or tests. Our intention was that they cover some basic Drupal 7 site functionality and can hopefully be implemented on most Drupal 7 projects going forward.

Installation

The following steps are what we ironed out to get Behat up and running on Drupal 7 sites locally.

  1. In your local project directory, create a folder called ‘behat’ inside of your sites folder: PROJECT/sites/Behat

  2. In your new Behat folder, create a composer.json file that looks like this:

Screen Shot 2016-07-06 at 10.53.39 AM.png

  1. From your command line, in PROJECT/sites/behat you will want to run $ composer install to get all of those dependencies installed. In order for this step to work, you will need composer installed on your machine.

  2. You will also need to create a behat.yml file that looks something like this, to configure your testing environment:

Screen Shot 2016-07-06 at 3.54.45 PM.png

6. We now need to initialize Behat. To do this, run: $ bin/Behat --init. This creates the features folder where you will write your tests, and your own FeatureContext.php file, where you can define custom steps. To learn more about this, visit the Behat and Drupal Extension documentation that we listed above.

Writing Tests

Now to actually writing the tests! This is the easy part. The tests are written using a language called Gherkin, in files with the extension ‘.feature’.

GitHub user mikecrittenden has a list of predefined Drupal behat steps that are available if you like to look at them in a browser.

The quick and easy way to view these steps, in our opinion, is to run $ bin/behat -dl in your terminal from the PROJECT/sites/behat folder.

Here is an example of a small and simple test to get a sense of how the tests are structured:

Screen Shot 2016-07-07 at 10.43.50 AM.png

In the above test, the “Feature” declaration is not processed by Behat as it is there for humans to understand what this .feature file is testing. The @api tag before the “Scenario” calls the Drupal API Driver.

  • Given’ is generally used to define some parameters of the environment of your website.
  • When’ is usually the actions taken by the user.
  • Then’ is usually saved for the expected behaviors of the site.

Executing Tests

Once the tests are written, you probably want to run them, right?

Luckily, once everything is correctly installed, running Behat tests is a breeze.

You just implemented a new feature onto your website and now you need to run your tests to make sure it didn’t accidently break a behavior.

In your command line, navigate to the PROJECT/sites/Behat folder and run the simple command $ bin/Behat. This tells Behat to find all of the *.feature files and test them against your website. Once it is done running you should be able to see all of your passing tests, and more importantly, any failing scenarios specifying the exact step that failed.

Now let’s say you have your core set of features and you have just written a new one. You don’t need to run all of the tests just to see if the new one works. In your command line, you start as you did before, just adding the path from your project’s Behat folder to that specific .feature file. For example, you made a new test and named it my_example.feature. You would simply run $ bin/Behat features/my_example.feature in your command line.

In Conclusion

While this is still a work in progress for us interns, we have learned a lot about Behat and hope that our new found knowledge will be of some help for the fine developers at Cheeky Monkey Media and for anybody else who wishes to cut back on unpredicted bugs!

Pages

About Drupal Sun

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

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

See the blog post at Evolving Web

Evolving Web