Our First Site Built with Drupal 8 - How we did it.

Our First Site Built with Drupal 8 - How we did it.

  Posted on November 23, 2015 by Bob Kruse

I'm happy to say that we relaunched our parent agency's site on Drupal 8 within one day of Drupal 8's release, however it would have been the same day if we didn't encounter some last minute "drush up" fails causing us to rebuild some parts of the site (all the the page manager variants that magically disappeared in the updates). Regardless, we got it up and here are the highlights of our experience and also a few mini tutorials.

Building a real site in Drupal 8

We started in the D8 Beta stage with a fresh install, then scratched our heads because our usual building block D7 modules weren't ready yet, like page manager, panels, panelizer, webform, to name a few. I feel like we were a bit spoiled in D7 because we leveraged contrib modules so much that going back to template files felt a bit foreign. So this forced us to rethink and get back to the basics of building a Drupal site.

 


 

Theming

Working with Twig

There are a ton of great tutorials out there to get you started with building a new twig theme, so I won't go there. Once you get past those nuances, the actual theming process is very similar to D7. Just edit your template files and add the twig variables.

The coolest part about Twig is enabling the Twig debugging, which shows you in the code where theme file suggestions begin and end. This made it really stupid-easy to find out what theme files we needed to edit.

Twig Debugging

 

The hardest part about working with Twig is getting the variables you want. You can use {{ dump }} which always caused me to run out of memory or {{ kint() }} which worked but didn't always show me what I was looking for. Ex. When I was seeking out the url of an unrendered image field, if took hours of searching to find the right answer. Thank god for stackexchange because many answers are there, but I think we're in need of a resource to explain how those answers were derived.

For example, to display an image field URL in a twig template file, it's {{ node.field_your_image.0.entity.uri.value }}. This wasn't something we could find in the array dumps.

To sub-theme or not to sub-theme

We never really needed subthemes. When we first started building Drupal sites back in 2008, we always built our own themes. If you're starting with pre-built html and css mockups, then just inserting Drupal's theme variables is quite easy.

I think it's best to start out this way because then you get a feel for what drupal outputs naturally, whereas if you always used a base-theme, you don't know if the output you're looking at was a product of native drupal or some magic of the sub-theme. Some people may not care about this, but you will care when you have to debug something and you don't know where to look first – was it drupal, the sub-theme, or a module?

So our approach with Twig was the same, no sub-theme. The cleanliness of Drupal's output in D8 is wonderful and very easy to work with.

Adding in some Bootstrap

We're huge fans of the bootstrap framework and in D7 we had the best setup – bootstrap base theme with the panels bootstrap layout builder. This allowed us to rapidly build bootstrap sites extremely easily.

In Drupal 8, the bootstrap base theme wasn't really necessary for our site as we could just simply add in the bootstrap coding through our theme files. In the past, the area where we really needed the bootstrap theme's magic was for theming form elements since bootstrap has a particular group of form classes and structure that takes some finagling to get drupal to output. Luckily in our case, we only have one form and it was easy enough to form_alter to get the structure needed.

 


 

Site Building

In Drupal 8, site building feels very familiar to Drupal 7, so getting accustomed to the new system wasn't difficult at all. However the feeling of impotence set in when we realized that our usual method of building a site had to change since our goto toolset wasn't available.

The scary world of contrib modules

Everytime we enabled a module, it was a scary, cross-your-fingers moment. So many known reliable modules from Drupal 7, could easily blow up a site in D8. Backup and Migrate, Admin Menu, and Webform caused fatal errors for us making the site unusable. We quickly learned that deleting the module and then deleting everything in /sites/default/files/php was a way to recover.

Page Manager & Panels

We use Page Manager, Panels, and Panelizer a lot. And for the custom layouts we needed for the new site, we had to make them work. Page Manage actually kinda works and Panels kinda works. Panelizer, as of this writing, does not.

We used a custom (Page Manager) page for each page in the site and then created custom panel layouts for each – since the panels layout builder doesn't work yet. There isn't documentation for how to actually add custom layouts so we figured that out with some trial and error. Here's a mini-tutorial on that:

How to create a custom Panels layout in Drupal 8

1. Add a yourtheme.layouts.yml to your theme. Here is an example with for our blog layout:

blog:
  label: Blog Layout
  category: Blog
  path: layouts/blog
  icon: blog.png
  #css: blog.css
  template: blog
  regions:
    top:
      label: top
    left:
      label: left
    right:
      label: right

2. Create actual files for the custom panel layout in your theme. In this case it's:

  • sites/themes/yourtheme/layouts/blog/blog.html.twig
  • sites/themes/yourtheme/layouts/blog/blog.png
  • sites/themes/yourtheme/layouts/blog/blog.css

3. In blog.html.twig you simply add your custom markup and variables for the regions you defined in the yourtheme.layouts.yml file. So in this case, our file looked like

<div class="container">
  <div class="row">
    <div class="col-md-12">
    {{ content.top }}
    </div>
  </div>
  <div class="row">
    <div class="col-md-9">
		{{ content.left }}
    </div>
    <div class="col-md-3">
    	<aside class="sidebar">
		{{ content.right }}
      </aside>
    </div>
  </div>
</div>

And that's basically it. Clear your cache and now you should be able to select it when you add a Panel to your Page.

Views rocks

It's great having views right out of the box. It works just like Drupal 7, so no surprises there. I was right at home. Now that all the taxonomy pages are driven by views, that made it really easy to theme them without the need for an extra module like TVI or Taxonomy display.

No views theming suggestions

One feature missing in D8 Views, that was extremely helpful in D7 views, was the Theming Information link in each view that showed you all of the theme file suggestions you could use to theme each part of the view output. The syntax of the files names are always so long and confusing, and then you have single and double dashes with underscores and more dashes, it can be a nightmare for someone with a little dyslexia (like me). So we had a separate D7 install with the same views just so we could get the theme filename suggestions. Eventually, not having the theme suggestions, forced me to learn their syntax, so I guess that made me a better themer in the end.

Views Theming Information missing in D8

Blocks rocks

I found that a majority of my content now lives in blocks. In D7 there was this big anti-block movement, but in D8 it's kind of the only available tool. When building a Panel layout, you can't create custom content panes, they aren't there yet, so the only option is to add blocks.

What's nice about D8 blocks is that they have block-types, can have fields added, and can be added more than once on the blocks layout page. The UI is a little confusing because when you delete a custom block from the blocks layout page, it just deletes its placement, not the actual block. But once you get used to it, it's all very functional.

Forms

For many years Webform was our goto form module. In D8, it's not ready. Entity form was our next option (eform in D8) and it does allow you to build form with native fields, however it relies on Rules to send emails… and Rules isn't ready yet. So the only option left, which I didn't even consider was the built-in Contact module. For years, it's been a pooped-on module no one uses. But in this case, it was the only option that actually worked. And paired with Contact Storage, which saves the form submissions, it's a workable solution.

While Contact module does work, I consider it a temporary solution until webform is ready. It's not very customizable, like you can't change the email formatting or the button label without digging into code.

For client projects, we'll need something easy for them to use to build and edit forms with and Webform fits the bill. People have been complaining for year about Webform not using Drupals built-in fields, but from a UI stand point I don't want to have to explain to clients was Booleans are or what a List (Integer) is versus a List (float). Webform makes it easy and end-users like easy.

For spam protection, Honeypot is available! And you know how we love honeypot.

 


 

What I'm looking forward to

The site building experience for Druapl 8 was ultimately a positive one. Once all the contrib modules catch up it will be useable for our client projects.

SEO

For SEO, we don't have a metatag module that works yet, so we had to add meta descriptions by code. That wasn't too fun. Here's another mini tutorial:

How to add a meta description tag in Drupal 8

Open up your yourtheme.theme file and add the following:

/**
 * Implements hook_page_attachments().
 */
function yourtheme_page_attachments_alter(array &$page) {
	$current_path = \Drupal::service('path.current')->getPath();
	switch ($current_path) {
		
		// Home page
  	case '/home':
			$viewport = array(
					'#type' => 'html_tag',
					'#tag' => 'meta',
					'#attributes' => array(
						'name' => 'description',
						'content' => "Home page description",
					),
				);
				$page['#attached']['html_head'][] = [$viewport, 'viewport'];
			break;
		
		case '/node/1':
			$viewport = array(
					'#type' => 'html_tag',
					'#tag' => 'meta',
					'#attributes' => array(
						'name' =>'description',
						'content' => 'some other page description',
					),
				);
				$page['#attached']['html_head'][] = [$viewport, 'viewport'];
			break;	
								
		} //end switch
  }

You need to create a case for each url.

The Admin menu

I'll admit, I don't like the built in toolbar. It takes too many clicks to get around and I'm always moving it to the left, then top, expanding options on the left, but you can't expand options from the top – it's very frustrating. I want the Admin Menu module. It might not be mobile friendly, but when building a site on a desktop, I'll take all the speed I can get and Admin Menu lets me move quickly.

Global Redirect and Redirect

When you're redesigning a site, the urls are going to change, so the redirect module would be really handy to handle that… it's not ready yet. Instead we have a huge htaccess file of redirects and a stupid 404 page with a mullet guy. For Drupal 8, Global Redirect and Redirect are merging into Redirect, so don't install Global Redirect, also it will crash your site.  

 


 

Final thoughts

Overall we used a lot less modules than we would have used in Drupal 6 or 7. The lack of available modules forced us to think outside the box and sharpen our chops when it comes to theming and site building. If you want to check out our parent agency site, click here. It's certainly not perfect, but it's our guinea pig Drupal 8 site and will be a continual work in progress. 


About the Author

Bob Kruse is the founder of Drupal Aid and a Drupal fanatic since 2008. He is also the creator of Cart Craze, an ecommerce website design gallery and Sick Journal, an online tool for keeping track of your family's health, sicknesses, and medications.