Jan 22 2019
Jan 22

[embedded content]

Over the years I’ve written a fair bit about Drupal and its modules, but all the videos and tutorials focused on a single module or topic.

So I decided to try something different and record a video where I build a whole website in a single go. I recorded the video in one night and only stopped recording to get a drink.

In this video, which is over 3 hours long, I’ll teach you how to build a basic directory website. We’ll start right at the beginning by setting up a local Drupal site for this we’ll use DDEV-Local. Then we create content types, create a sub-theme, create a few custom views, a search page, media management functionality and so much more.

I’ve broken out the video into sections below with timecodes and extra resources. For the content below to make any sense you should follow along by watching the video.

Enrollments are now open for the Drupal 8 Site Building Bootcamp: 7-week program, 2 live lectures per-week. Enroll NOW!

1. Set up Local Drupal Site

Time: 00:01:33 – 00:09:49

Download Drupal

We first need to download the Drupal codebase, run the following Composer command:

composer create-project drupal-composer/drupal-project:8.x-dev SITE_NAME --stability dev --no-interaction

Replace SITE_NAME with the name of the folder.

Tip: If you want to speed up Composer then install the prestissimo plugin. This is a Composer plugin and has nothing to do with Drupal.

Configure DDEV-Local

We’ll use DDEV-Local to run our local Drupal 8 site. It requires Docker to run, and you can get the install instructions from their documentation site.

Once you’ve installed DDEV-Local go to your Drupal site within the terminal and run:

ddev config

You’ll be prompted with a few options, and it’ll configure the environment.

MacOS Users: If you’re using macOS make sure you set webcache_enabled to true in the ddev config.yml.

Go to your Drupal codebase and open .ddev/config.yml and change:

# From:
webcache_enabled: false
# To:
webcache_enabled: true

Time: 00:06:58

Links:

2. Create Content types and Taxonomy Vocabularies

Time: 00:09:50 – 00:29:08

Just like on any Drupal site we need to build the data model: content types and taxonomy vocabularies.

Content Types

Listing:

  • Body
  • Email
  • Listing categories
  • Logo
  • Website

Blog:

  • Body
  • Comments
  • Featured image
  • Tags
  • Blog categories

Taxonomy Vocabularies

  • Listing categories
  • Blog categories

Links:

3. Modify Content types

Time: 00:29:08 – 00:41:20

Once the content types have been created we’ll need to modify them. For this, we’ll use Display Suite.

To install Display Suite, run the following command:

composer require drupal/ds

If you’re keen to learn more about Display Suite check out our following tutorial series:

  1. How to Customize Content Pages
  2. How to Use Display Suite Fields
  3. How to Use Switch View Mode Sub-module
  4. Webinar: Customize Content Pages using Display Suite in Drupal 8

4. Create Bootstrap Sub-theme

Time: 00:41:22 – 01:01:40

We’ll use the Bootstrap theme on the site, and we’ll create a basic CDN sub-theme.

If you need step-by-step instructions on creating a Bootstrap theme, then read our “Getting Started with Bootstrap in Drupal 8“.

Install the theme using this command:

composer require drupal/bootstrap

Please note: The Bootstrap theme (as of this writing), only supports Bootstrap 3, not 4. If you need a Bootstrap 4 theme look at Barrio or Radix.

We have a tutorial on Barrio called “Getting Started with Bootstrap 4 using Barrio in Drupal 8“.

Bootstrap Layouts

The Bootstrap Layouts module ships a bunch of prebuilt layouts for Drupal 8. We’ll use these layouts in Display Suite.

composer require drupal/bootstrap_layouts

If you want to learn more about Bootstrap Layouts, then check out our tutorial “How to Implement Layouts using Bootstrap Layouts in Drupal 8“.

Links:

5. Block and Menu System

Time: 01:01:42 – 01:15:03

Once we’ve created our sub-theme, we’ll create four new footer regions.

Add the following into your theme’s .info.yml:

regions:
  footer_one: 'Footer one'
  footer_two: 'Footer two'
  footer_three: 'Footer three'
  footer_four: 'Footer four'

Add the following into page.html.twig (make sure you override the Twig file):

<div class="footer footer-grid {{ container }}">
    <div class="row">
        <div class="col-sm-3">
            {{ page.footer_one }}
        </div>
        <div class="col-sm-3">
            {{ page.footer_two }}
        </div>
        <div class="col-sm-3">
            {{ page.footer_three }}
        </div>
        <div class="col-sm-3">
            {{ page.footer_four }}
        </div>
    </div>
</div>

6. Views

Time: 01:15:03 – 01:38:10

We need to create a few custom Views for our website. The first one, which lists blog content is fairly simple.

The second, which is “My listing” is complicated because you have to deal with contextual filters.

Read our tutorial “Add Custom Tab to User Profile Page with Views in Drupal 8” for a step-by-step tutorial on implementing this type of View.

7. Build Search page using Search API

Time: 01:38:10 – 02:10:32

We’ll use the Search API and Facets module to build our custom listing search page.

Download the required modules using the following command:

composer require drupal/search_api drupal/facets

Watch our webinar “How to Build Custom Search Pages in Drupal 8” which covers the core Search module and Search API.

Links:

8. Media Management

Time: 02:10:55 – 02:30:54

We now need to add media handling functionality to the directory site.

Run the following Composer command to download the required modules:

composer require drupal/entity_embed drupal/ctools drupal/entity_browser drupal/inline_entity_form

For a detailed tutorial on configuring all this stuff and more go to “Managing Media Assets using Core Media in Drupal 8“. And there’s a video: “Live Training: Managing Media Assets using Core Media in Drupal 8“.

9. Roles and Permissions

Time: 02:30:56 – 02:51:10

Now we need to create a role called “Contributor” and configure its permissions.

To allow users to publish/unpublish listings, you’ll need to use Override Node Options.

Install it using the command below:

composer require drupal/override_node_options

The “Contributor” role needs the following permissions:

  • Use the Contributor HTML text format
  • Image: Create new media
  • Image: Delete own media
  • Image: Edit own media
  • Listing: Create new content
  • Listing: Delete own content
  • Listing: Edit own content
  • View own unpublished content
  • Override Listing published option

Create Registration Page

To create a registration page, we’ll use Multiple Registration.

Run this command to install it:

composer require drupal/multiple_registration

Read our “Create Individual Registration Forms using Multiple Registration in Drupal 8” for a detailed tutorial on the module.

Links:

10. Paragraphs

Time: 02:51:10 – 03:06:45

We’ll use the Paragraphs module to allow an editor to add a Bootstrap Jumbotron to a page.

Install the module by running:

composer require drupal/paragraphs

If you want to learn more about Paragraphs, then check out our free course, “Build Edge-to-edge Sites using Paragraphs in Drupal 8“.

Links:

11. Webform

Time: 03:06:47 – END

We’ll use the Webform module to build functionality which sends an email to the owner of the listing.

You can install Webform by running:

composer require drupal/webform

Below is the token which is used:

[webform_submission:submitted-to:author:mail]

Links:

Summary

I don’t expect many people to make it to the end of the video but if you did, congratulations! I hope you learnt something new by seeing how a Drupal site is built.

We can often learn a lot just by watching a developer build something.

Ivan Zugec

About Ivan Zugec

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 10 years and has successfully completed several large Drupal projects in Australia.

Oct 16 2018
Oct 16

[embedded content]

Video sections

Bootstrap is a powerful front-end framework which helps you build sites and web applications faster by offering prebuilt CSS and JavaScript components.

Some of the CSS components it offers are a grid system, buttons, navigation, jumbotron and so much more. On the JavaScript side, it comes with a few useful items such as a modal, collapsible divs, carousel to name a few. Read the Bootstrap documentation to find out more.

Bootstrap in Drupal

If you search for “drupal bootstrap” in Google, the first result will likely be the Bootstrap theme. This theme is the most popular on drupal.org with over 150,000 reported installs. But as of this writing, the theme only supports Bootstrap 3, not version 4 which is the latest.

So if you want to use Bootstrap 4 you’ll need to use another theme until the Bootstrap theme supports version 4.

In this tutorial, you’ll learn how to configure and use the Drupal 8 version of the Barrio theme which uses Bootstrap 4.

Getting Started

Before we can begin, go download the Barrio theme.

Using Composer:

composer require drupal/bootstrap_barrio

Create Sub-theme

The recommended way of using a theme in Drupal is to first create a sub-theme. You’ll never want to use Barrio directly. If you need to customize how things look, i.e., change CSS and override templates, then do it in the sub-theme and not Barrio itself, this way you can keep Barrio up-to-date.

If you want to learn more about sub-themes in general. Check out the Creating a Drupal 8 sub-theme, or sub-theme of sub-theme documentation page.

Let’s now look at creating a sub-theme which pulls Bootstrap via a CDN, this is the quickest and easiest way to get started.

Create CDN Sub-theme

1. Go to the bootstrap_barrio directory and copy the subtheme directory into /themes.

2. Change the subtheme directory name to anything you want, I’ll change it to barrio_custom (everywhere you see barrio_custom, use your actual sub-theme name).

Now we need to go through the sub-theme and replace bootstrap_barrio_subtheme to barrio_custom.

3. Rename the following files:

  • _bootstrap_barrio_subtheme.theme -> barrio_custom.theme
  • bootstrap_barrio_subtheme.info.yml -> barrio_custom.info.yml
  • bootstrap_barrio_subtheme.libraries.yml -> barrio_custom.libraries.yml
  • config/install/bootstrap_barrio_subtheme.settings.yml -> config/install/barrio_custom.settings.yml
  • config/schema/bootstrap_barrio_subtheme.schema.yml -> config/schema/barrio_custom.schema.yml

4. Open  barrio_custom.info.yml change the name of the sub-theme and rename the libraries section from bootstrap_barrio_subtheme to barrio_custom.

From this:

To this:

5. Open barrio_custom.theme (formerly_bootstrap_barrio_subtheme.theme) and change the function name:

// From:
bootstrap_barrio_subtheme_form_system_theme_settings_alter(&$form, FormStateInterface $form_state)
// To:
barrio_custom_form_system_theme_settings_alter(&$form, FormStateInterface $form_state)

6. Open config/schema/barrio_custom.schema.yml (formerly config/schema/bootstrap_barrio_subtheme.schema.yml) and change the following:

# from:
bootstrap_barrio_subtheme.settings:
# to:
barrio_custom.settings:

7. Open color/color.inc file and change the following:

// From:
'preview_library' => 'bootstrap_barrio_subtheme/color.preview',
// To:
'preview_library' => 'barrio_custom/color.preview',

8. Last but not least, open js/global.js and change the following:

// Change this:
Drupal.behaviors.bootstrap_barrio_subtheme = {
// To this:
Drupal.behaviors.barrio_custom = {

Now that you’ve created a sub-theme go to the Appearance page in your Drupal site and install your sub-theme by clicking on “Install and set as default”.

The front-end of your Drupal site should look something like the image below:

The actual Bootstrap 4 library is being loaded via a CDN which is the default behavior in the Barrio sub-theme and that’s why everything works without downloading the library locally. Of course, this can be changed and we’ll look at how to do that next.

Download Local Version of Bootstrap

In the sub-theme we created above, we’re pulling in Bootstrap through the CDN. Let’s configure it now to use a local version of Bootstrap.

1. Go to the Download page and click on Download in the “Compiled CSS and JS” section.

2. Extract the zipped file into /libraries directory in your Drupal site and rename the folder to bootstrap. 

The path to the css and js folder should be /libraries/bootstrap/css and /libraries/bootstrap/js.

3. Open up *.libraries.yml in your sub-theme, mine is called barrio_custom.libraries.yml and change the bootstrap section like so:

From this:

bootstrap:
  js:
    /libraries/popper/popper.min.js: {}
    /libraries/bootstrap/dist/js/bootstrap.min.js: {}
  css:
    component:
      /libraries/bootstrap/dist/css/bootstrap.min.css: {}

To this:

bootstrap:
  js:
    /libraries/bootstrap/js/bootstrap.bundle.min.js: {}
  css:
    component:
      /libraries/bootstrap/css/bootstrap.min.css: {}

Bootstrap 4 has two dependencies Popper and jQuery. Drupal comes with jQuery already and to save a bit of effort will use the bootstrap.bundle.min.js which comes with Popper whereas, bootstrap.min.js doesn’t.

4. Open the *.info.yml file in your sub-theme and change barrio_custom/bootstrap_cdn under libraries to barrio_custom/bootstrap.

From this:

libraries:
  - barrio_custom/bootstrap_cdn
  - barrio_custom/global-styling

To this:

libraries:
  - barrio_custom/bootstrap
  - barrio_custom/global-styling

5. Rebuild the site cache by running drush cr or drupal cache:rebuild or by going to /admin/config/development/performance and clicking on “Clear all caches”.

If the JavaScript or CSS file isn’t loading or the site looks broken. Make sure the paths in the *.libraries.yml file is correct and that the Bootstrap library is correctly in the /libraries directory.

Theme Settings

The Barrio theme allows you to configure a lot through the Settings page, which you can access by clicking on the Settings link after you’ve activated the theme. I won’t go through absolutely everything, however, I’ll mention some important settings.

To access the settings page, click on Appearance in the toolbar and Settings next to the installed theme.

Layout Settings

From the Layout tab, you can configure aspects of the layout such as the type of container, i.e., fluid or non-fluid and how wide the sidebar columns should be.

If you select “Fluid container”, then your website will be full-width with gutters on each side.

The “Sidebar first layout” and “Sidebar second layout” let you configure the width of each sidebar.

Components Settings

From the Components tab, you can configure the buttons and the navbar.

The most important section in this tab is the navbar. It lets you configure it without having to modify any CSS or SASS files.

Affix Settings

In this section, you can configure components like the navbar or sidebar to be affixed to the top when scrolling.

If you check “Affix navbar”, it’ll stick the navbar to the top as you scroll down the page.

Here’s an example:

Scroll Spy

In this area, you can configure the Scrollspy functionality in your Drupal Bootstrap site.

Fonts Settings

From the Fonts tab, you can configure what fonts will be used and icon set.

Colors

And finally, from the Colors tab, you can configure the color of the messages and how tables are displayed.

Color Scheme

One thing I do like about Barrio which is different to the Bootstrap theme is the ability to change the color scheme directly in the theme.

Now, this isn’t groundbreaking and Drupal’s had this ability for a long time, but being able to easily change colors without modifying CSS or compiling SASS is a nice touch.

However, there is a limitation on which colors can be changed. You can’t change Bootstrap colors: primary, secondary, success, danger, warning or info from the color scheme section.

So that is a quick overview of the settings page. My guess is you’ll spend most of your time configuring the navigation bar and grid layout. But do spend some time familiarizing yourself with the options available.

Bootstrap Library

Another way to load Bootstrap is by using the Bootstrap Library module. One of its benefits is the ability to change which version of the CDN library you want to use without modifying the *.libraries.yml file in your sub-theme.

1. Start things off by first downloading the module and then installing it.

composer require drupal/bootstrap_library

2. Go to the Settings page of your sub-theme and scroll to the bottom and from “Load library” choose how you want the library to be loaded.

  • CDN: This will load Bootstrap through a CDN.
  • Local non minimized (development): This will use the non minified version stored in the /libraries directory
  • Local minimized (production): This will use the minified version stored in the /libraries directory.

As long as you’ve downloaded Bootstrap and added it into the /libraries directory as explained early, the “Local non minimized” and “Local minimized” should work.

Bootstrap Library Settings

The Bootstrap Library module comes with a configuration page, just go to Configuration and click on Bootstrap Library.

If you choose None from “Load library” on the theme settings page, then whichever way Bootstrap is configured to load from this page is what will be implemented.

From this “Load Boostrap from CDN” section, you can choose if a CDN is used and which version. If you prefer to load Bootstrap locally, then select “Load locally”.

Then from “Minimized, Non-minimized, or Composer version” select which local version you want to use.

Form “Theme visibility” select which themes will have Bootstrap loaded.

Make sure you select your theme from the multi-select or the library will not load and your site will be broken.

From the “Activate on specific URLs” section, you can include or exclude the library on specific paths.

From the “Files settings” you can choose if you want CSS and/or JavaScript files loaded.

If you decide to use Bootstrap Library to load the library then make sure your sub-theme isn’t loading the library itself because you’ll end up loading the library twice.

Remove any library declarations from the *.info.yml file in your sub-theme. This will stop your sub-theme from loading the library.

Rebuild the site cache and you’re good to go.

Summary

The current state of Bootstrap in Drupal 8 is this. If you need to use Bootstrap 3, then use the Bootstrap theme. If, however, you want to use Bootstrap 4 then look at Barrio, Bootstrap4BootBase or Radix.

If you know of any good Bootstrap 4 base themes then please leave a comment.

Ivan Zugec

About Ivan Zugec

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 10 years and has successfully completed several large Drupal projects in Australia.

Oct 02 2018
Oct 02

[embedded content]

Watch other videos on our YouTube channel. Click here to subscribe.

I was recently looking at all the default views that come with Drupal 8. For people who don’t know, the Views module is part of Drupal 8 core. In Drupal 7 and below it’s the most installed module so during Drupal 8’s development it was decided to move Views into core.

During my exploration into all of the default Views, I noticed that in the People (User) view there was a filter called “Combine fields filter”.

Want to learn about Views? Read Build a Blog in Drupal 8: Using Views or watch it as part of our FREE Drupal 8 Site Building course.

Now just a quick side note, if you’re new to Drupal and Views I’d highly recommend you spend time walking through all of the default views and see how they were configured. You can learn a lot just by seeing how things are set up.

The “Combine fields filter” does a pretty cool thing. It allows you to search across multiple fields or put another way, it allows you to combine fields and then filter by their combined value.

How to use “Combine Fields Filter”

Using this filter is relatively straightforward. Just click on Add in the Filter criteria field-set. Search for the filter by name or select Global from the Category drop-down.

When configuring the filter, you can select which fields you want to search from the “Choose fields to combine for filtering” drop-down.

If you want to see what the actual query looks like, turn on “Show the SQL query” from the Settings page (admin/structure/views/settings).

Then in the preview area, you should see the query that gets generated.

The above example is from the “People (User)” view.

Summary

If you want to add basic filtering across fields to your views, then this is the way to go. It’s useful for those custom admin pages which we create to help editors manage content. If you’re looking for something more advanced such as keyword searching, then look at using Search API.

Ivan Zugec

About Ivan Zugec

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 10 years and has successfully completed several large Drupal projects in Australia.

Sep 05 2018
Sep 05

[embedded content]

Drupal has got new media management functionality in 8.6. In the above video, I’ll demonstrate what new media functionality we have in Drupal 8.6.

Thanks to the Media in Drupal 8 Initiative, media handling in Drupal has improved with every new release. In 8.4 we got the experimental core Media module. Then in 8.5, the module moved from experimental to stable and now it’s the recommended way for storing media assets. Now in Drupal 8.6 we get a few extra goodies such as oEmbed support, a Remote video media type and a media library.

Grab our FREE course on using core Media in Drupal 8.
(While you’re at it check out our list of free courses)

New Remote Video Media Type

When you install the Media module you get four media types by default: Audio, File, Image and Video. Now you get Remote video which can be used to embed YouTube and Vimeo videos.

Currently only YouTube and Vimeo are supported. If you need to support other video platforms look at using Video Embed Field.

Learn how to configure Video Embed Field with core Media module.

oEmbed Support

To handle the new Remote video media type, Drupal 8.6 also got oEmbed support (Drupal change record).

Media Library

The new Media library module is by far the most exciting new functionality. You’ll need to install the experimental module called Media library. Don’t forget this is experimental for now; use at your own risk.

The first change you’ll notice is that the Media page looks different. You get to switch between a Grid and Table view.

The module also comes with a new widget for the Media field called “Media library”. This will allow you to browse media assets from the edit screen.

To use this widget make sure “Media library” is selected as the widget on the “Manage form display” page.

Here it is in action and watch how you can bulk upload images.

Can this module replace Entity browser? At this point I’d say no. Entity browser gives you more flexibility in how you build these types of browse pages. But I hope in the future Media library will be the standard way of creating these browse pages.

Want to learn how to use Entity browser? Check out “How to Browse Media Assets using Entity Browser“.

Summary

Slowly and steadily media handling in Drupal core is improving and becoming more powerful. It’s good to see this continued momentum. But if you need to create bespoke media functionality I still think the combination of Entity embed/Entity browser is the winner for now.

Check out our epic “Managing Media Assets using Core Media in Drupal 8” tutorial where you’ll learn how to use Entity embed, Entity browser, DropzoneJS and more.

Ivan Zugec

About Ivan Zugec

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 10 years and has successfully completed several large Drupal projects in Australia.

Aug 23 2018
Aug 23

[embedded content]

Drupal Console and Drush are two command line (CLI) tools built for Drupal. For a long time Drush was the only CLI tool and it was very useful for managing Drupal sites. Common tasks you’d do with Drush are rebuild caching, installing sites, import/export configuration and so much more.

Then Drupal Console came onto the scene and offered other goodies such as the ability to generate boilerplate code, which Drush 9 can now do as well. People often ask “Can you run Drush and Drupal Console together” and the answer is yes, I personally use both. If you install Drupal using drupal-composer/drupal-project then you get both Drush and Drupal

In the video above, you’ll learn how to use Drush and Drupal Console.

Drupal Console

Drupal Console is a CLI tool for Drupal built using the Symfony Console library. One of its many strengths is the ability to generate boilerplate code. With a few simple commands you can create a module or a custom entity type.

How to Install Drupal Console

Drupal Console can be installed into your Drupal site using Composer, follow the instructions over on the Drupal Console documentation page.

Use the links below to jump to a section of the video:

  • Drupal Console intro: 02:31
  • How to install Drupal Console: 04:29
  • Using Drupal Console launcher: 06:27
  • Overview of Drupal Console commands: 07:41
  • How to use debug commands: 08:33
  • Using debug:router command: 10:11
  • Using debug:container command: 11:49
  • Using debug:cron command: 15:08
  • Using debug:user command: 15:08
  • How to use generate commands: 17:15
  • Using generate:module command: 18:07
  • View module code generated by Drupal Console: 20:42
  • Using generate:entity:content command: 20:59
  • View code generated by generate:entity:content command: 24:43
  • Install module generated by Drupal Console: 27:21
  • How to download modules using Drupal Console: 31:10
  • Viewer question: What’s composer?: 34:45

Drush

Drush is the original CLI tool for Drupal. You can use it to interact with a Drupal site and generate boilerplate code.

How to Install Drush

Drush is just a PHP library and can be installed using Composer. For details read the Drush install documentation page.

Use the links below to jump to a section of the video:

  • Drush intro: 37:22
  • How to install Drush: 40:56
  • Using Drush: 42:11
  • Overview of Drush Commands: 43:00
  • Using Drush generate command: 44:11
  • Using generate module-content-entity command: 45:12
  • View module code generated by Drush: 46:23
  • Install module generated by Drush: 47:13
  • Overview of common Drush commands: 52:00
Ivan Zugec

About Ivan Zugec

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 10 years and has successfully completed several large Drupal projects in Australia.

Jul 17 2018
Jul 17

[embedded content]

In the video above, you’ll learn how to build powerful media management functionality using Drupal 8.5. I start the webinar with a review of what’s new in Drupal 8 and then jump right into a live demo.

If you prefer text, then read our tutorial on “Managing Media Assets using Core Media in Drupal 8“.

Modules

In the video we use the following modules:

Below is a time coded list of all the sections in the video. Just click on the time code and it’ll jump to that part of the video.

Video Sections

  • Agenda: (00:41)
  • What’s new in Drupal 8: (01:35)
  • Required Modules: (09:53)
  • Demo time: (11:02)
  • Install Media module: (11:49)
  • How to Upload and view assets: (12:34)
  • Overview of Media types: (14:42)
  • Create remote video media type: (15:34)
  • Field mapping in media types: (17:45)
  • Create remote video asset: (18:52)
  • Customize remote video formatters: (19:48)

Media Field

  • Attach media field to Article content type: (20:24)
  • Using Inline Entity Form on media field: (22:53)
  • Install Inline Entity Form: (23:27)
  • Configure IEF on media field widget: (24:46)

Entity Embed

  • Install Entity Embed: (27:44)
  • Create embed button: (28:37)
  • Configure text format for embed button: (29:40)
  • Testing embed button: (32:27)

Entity Browser

  • Install Entity Browser: (35:50)
  • Create entity browser: (38:21)
  • Integrating entity browser and entity embed: (39:45)
  • Create view for entity browser: (41:02)
  • Add IEF to entity browser: (47:35)

Entity Browser and DropzoneJS

  • Add dropzonejs to entity browser: (51:59)
  • Customize fields on media types using form modes: (54:26)

Drupal 8.6

Ivan Zugec

About Ivan Zugec

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 10 years and has successfully completed several large Drupal projects in Australia.

Jun 05 2018
Jun 05

Webform allows you to create powerful forms in Drupal without the need for any custom code. You can use it for a basic contact us form with a few fields such as name, phone and email, or it can also be used to create complex multi page forms with conditional fields.

If you want to allow your editors to create their own forms without the need of a developer then install and teach them how to use the module. If you want to learn more about webform we have a two part series which will help you get started; Getting Started with Webform in Drupal 8 and Moving Forward with Webform in Drupal 8.

Collecting submissions using Webform is easy, but what if you want to integrate the module with a 3rd party SaaS provider? What if you want to push all contact form submissions into your CRM system, or add a row into a Google Sheets spreadsheet.

Of course, this can be done by a developer through the right APIs but you can also do it without writing any code using a service called Zapier.

In this tutorial, you’ll learn how to send Webform submissions into Zapier which will then add it as a row into a Google Sheets spreadsheet.

What is Zapier?

Zapier is an automation platform which lets you create workflows based on an action. For example, you could create a workflow when a user subscribes to a MailChimp list it’ll add the contact in a CRM (if supported by Zapier) or a Google Sheets spreadsheet.

It has integration with over 1000 SaaS applications and I do recommend that you have a play around with the service if you’ve never used it. They do offer a decent free plan which is more than enough to get you started.

Personally, if I’m looking at using a new SaaS application the first thing I check is if it has Zapier integration that way you can move data around and you have more flexibility.

How Does Webform Send Submissions to Zapier

Submissions are sent to Zapier using a POST request. This can be configured by adding a “Remote post” handler to a form. When a submission gets added, Webform will send it via a POST request using the URL in the “Remote post” handler.

Getting Started

For this tutorial, I’m going to assume you know how to use Webform. So all we’re going to do is download the module and install Webform and Webform UI. We’ll use the default Contact form that comes with the module.

Using Composer:

Composer require drupal/webform

Step 1: Create Zap on Zapier and Get POST URL

If you haven’t already, go ahead and create an account on Zapier. It is a paid service but has a free plan.

The first thing we’ll need to do is create the Zap where we’ll define a trigger and action.

1. Click on “Make a Zap!” in the top right.

2. In the “Choose a Trigger App” page, click on Webhooks in the “Built-in Apps” section down the page.

3. Choose “Catch Hook” and click “Save + Continue”.

4. Click Continue on the “Pick off a Child Key” page.

5. Copy the POST url because we’ll need it for Webform.

Step 2 : Set up Remote Post Handler

Using the POST url from Zapier which we got in the last section, we’ll need to create a “Remote post” handler in Webform.

1. Go to Structure, Webforms and click on Settings on a Webform. For this tutorial, I’ll use the default Contact form that comes with Webform.

2. Click on the “Emails / Handlers” tab, then click on “Add handler”.

3. Click on “Add handler” on the “Remote post” row.

4. In the Completed section paste in the URL we got from Zapier and click on Save.

Note: You can add a URL if the submission is updated or deleted. That’s a nice bit of added flexibility. I should also note that this is all the configuration required on Webform’s part, cool isn’t it!

Step 3: Send Test POST to Zapier and Finish Configuring Trigger

Let’s now jump back into the Zap we started building in step one.

1. Once you’ve configured the “Remote post” handler click on “Ok, I did this”.

2. Now go back to your Drupal site and submit the actual form so it sends a POST to Zapier. This is a required step.

3. Once you’ve sent a test POST, you should be on the “Pick A Sample To Set Up Your Zap” section. You can view what was in the post by clicking on the down arrow.

When you’re ready click on Continue.

Step 4: Configure Action in Zap

At this point, we’ve configured the trigger in our Zap and sent a test submission. We know that the POST request from Webform worked because Zapier received it.

Now we need to configure the action; where the submission will be stored.

1. Click on Google Sheets on the “Choose an Action App”.

2. Choose “Create Spreadsheet Row” and click on “Save + Continue”.

3. Connect Zapier to your Google account, then click on “Save + Continue”.

4. From the Spreadsheet field select the actual spreadsheet you want the submissions saved into.

5. Select the Worksheet within the spreadsheet.

If you see the message below it means your spreadsheet doesn’t have any headers.

Go and add a header for each column you want to save in your Google Sheets spreadsheet.

6. Now go and map the fields with the values below the “Catch Hook”.

Then click on Continue.

7. Click on “Send Test to Google Sheets” to test everything out.

Check your Google Sheets you should see a new row in it.

Then click on Finish.

8. Don’t forget to name and Zap and switch it on.

Step 5: Test Webform Submission

Go to your Webform and create an actual submission. Once submitted you should see the submission as a row in the spreadsheet.

Debug Zapier

If you need to debug what’s coming into Zapier or you want to see all the submission data which has been pushed into Zapier, then go to the “Task History” page.

From this page you can view if the task was successful or if there was a error. You can sometimes get an error if the API is down and not working.

You can also see what data has come in and out by clicking on the Task.

This gives you some nice visibility into what Zapier is handling.

Summary

The combination of Webform and Zapier is powerful. Almost everyone can be trained to use Zapier and create Zaps which will open a whole new world of possibilities. You’ll finally be able to connect your CRM with Drupal and without the need for custom code.

Ivan Zugec

About Ivan Zugec

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 10 years and has successfully completed several large Drupal projects in Australia.

May 15 2018
May 15

Media Management for Drupal 8.5+

There’s a lot of momentum to fix media management in Drupal 8 thanks to the Media Entity module. By using a combination of Media EntityEntity Embed, Entity Browser and some media providers such as Media entity image you could add decent media handling in Drupal 8.

Then in Drupal 8.4, the Media Entity functionality was moved into a core module called Media. However, the core module was hidden by default. Now in Drupal 8.5 it’s no longer hidden and you can install it yourself.

In this tutorial, you’ll learn how to install and configure the Media module in Drupal 8 core. This tutorial is an updated version of the How to Manage Media Assets in Drupal 8 tutorial where we cover Media Entity.

Configuring Entity Embed and Entity Browser for the core Media module is essentially the same as with Media Entity. So if you have experience using Media Entity, then you’ll be fine using the core Media module.

Sections:

  1. Storing Media Assets
  2. Displaying Media Assets
  3. Embedding Assets into the Editor
  4. How to Browse Media Assets

What’s the Difference Between Media Entity and Media

The biggest difference between the two modules is that the API has changed. Any media provider module for Media Entity such as Media entity Instagram or Media entity Twitter need to be updated to use the new API. A lot of these modules now have a 8.x-2.0 version which only works with core Media. So if you’re going to use a media provider module read the project page.

If you want to see a technical explanation of the changes go to the “Moved a refined version of the contributed Media entity module to core as Media module” change record on drupal.org.

Getting Started

Before we begin, go ahead and install the Media module. It comes with Drupal core but it’s off by default.

Part 1: Storing Media Assets

The Media module implements a fieldable entity type called Media. This means you can add custom fields to them like content types and adjust their look-and-feel through the “Manage display” page. If you know how to manage content types then you’ll be right at home managing media types.

Let’s first look at how media assets are stored in Drupal 8. Saving assets into a Drupal site is similar to creating content.

1. Click on Content in the toolbar.

2. Click on the Media tab, then click “Add media”.

3. Choose which type of media you want to upload, in this example I’ll choose Image.

4. Enter in a name for the asset in the Name field and select an image using the Image, then click on Save.

5. Once you save the form, you’ll be redirected to the public media page.

View all Media Assets

You can view all upload assets from the Media page we were just on, go to the Content page and click on the Media tab.

You can search assets by their name using the “Media name” field or filter by media type using the Type drop-down.

Creating and managing media assets are pretty straightforward but the magic happens in the Media types, let’s look at them next.

Media Types

Media types are just like content types or taxonomy vocabularies. They are fieldable configuration entities.

Go to Structure then click on “Media types” to create and manage them.

Drupal 8 ships with four media types; Audio, File, Image and Video.

The File and Image media types are fairly self-explanatory use them to upload images or general files such as PDFs.

Audio and Video media types should be used when you want to locally host the video or audio file. The asset will be played using the HTML tags, <audio> and <video>.  You can’t use the this media type to embed videos from YouTube or Vimeo. To do that you’ll need the “Video embed field” and a new media type which we cover later in this tutorial.

Media Source

Every media type needs to use a “Media source”, this tells Drupal how the file should be handled, i.e., how the file should be stored or if a thumbnail should be generated.

The Media module in Drupal 8.5 comes with four media sources; audio, video, file and image.

So if you want to store and display tweets for example, then all you’ll need to do is create a media type called “Tweet” (or whatever you want) and install the 8.x-2.0 version “Media entity twitter” module. The 8.x-1.x version only works with Media Entity, whereas, the 8.x-2.x works with the core Media module.

Create Embed Video Media Type

Now let’s go and create a new media type for embedding YouTube videos. But first, download the 8.x-2.0 (make sure it’s 2.0) version of “Video Embed Field“. The module ships a sub-module called “Video Embed Media” which has a media source for handling embedded videos.

composer require drupal/video_embed_field

Once downloaded go and install “Video Embed Media” from the Extend page.

1. Go to Structure, “Media types” and click on “Add media types”.

2. Add “Embed video” into Name and “Used for embedding videos” into Description.

3. Select “Video embed field” from the Media source drop-down box.

4. From the field mapping section, you can store specific metadata about the video into a custom field.

For example, if you want to store the YouTube ID, which’ll be the “Video ID”. All you need to do is create a custom field and select it from the drop-down to map it.

5. Once everything is complete click on Save at the bottom of the page.

Edit Media Type

When you edit the Embed video media type, you should see three familiar tabs: Manage fields, Manage form display and Manage display.

A media type is just a fieldable configuration entity same as content types or vocabularies so managing fields are the same.

If you click on Manage fields you see a single field called “Video Url”. This is where the URL to the embedded video will be stored. We didn’t create the field, instead “Video Embed Media” programmatically attached it for us when we created the media type.

Create an Embed Video

Now that we’ve created our media type, let’s create the actual asset.

1. Go to Content and click on the Media tab.

2. Click on “Add media” then “Embed video”.

3. Enter a name into the Name field and enter in a URL to a YouTube video, then click Save.

It’s important to note that Video Embed Field supports more than just YouTube. Out-of-the-box it supports YouTube and Vimeo but it has support for other video providers via contrib modules. Check out the “Video Providers” section on the project page for more details.

“Video Providers” section on the Video Embed Field project page.

4. Once you’ve saved the form, you’ll be redirected to the media display page.

But as you can see in the screenshot above, the page looks messy. It’s displaying all the fields; date, author, thumbnail and at the bottom the actual embedded player.

Modify Media Display

Let’s clean up the display of the embedded video so only the embedded player shows.

1. Go to Structure, “Media types”.

2. Click on “Manage display” from the Operations drop-down on the “Embed video” row.

3. Move all the fields to the Disabled section except for “Video Url”.

4. Now if you go to the media display page you should only see the embedded player.

Part 2: Displaying Media Assets

You learnt how media assets are stored in part one and how to create your own media types. Now we’ll look at how to display the assets on a content type using a field.

I mentioned earlier that an asset is just an entity. So if you want to attach it to a basic page or article, all you need to do is create an entity reference field. Of course there’s a bit more to it, so let’s look at it now.

Create Media Field

The Media module comes with a field called Media. It simply lets you reference assets using an entity reference field. Let’s create one on the Article content type.

1. Go to “Content types”, “Manage fields” on the Article row.

2. Click on “Add field.

3. Select Media from the “Add a new field” drop-down and enter Asset into the Label field.

4. On the “Field settings” page, leave it as is and click on “Save field settings”.

5. Down in the “Reference type” field-set, you need to select which media type you allow. In this example, I’ll choose Image, then click on “Save settings”.

Now it’s time to test it out.

Go to Content, click on “Add content”, then Article and you should see the Asset field with an autocomplete field.

Then simply search for an asset using the “Use existing media” autocomplete field.

If you need to create a new asset, you’ll need to click on the “media add page” link or just go to Content, Media and create it from there.

But there is a problem with this method. You can’t create an asset directly from the article page. You need to go to the add media page, a totally seperate screen, upload the image then come back and search for it in the autocomplete field.

This workflow is not ideal. Now I’ll show you how to use Inline Entity Form module so you can create the assets without leaving the page.

Use Inline Entity Form to Upload Media Assets

Go download and install the Inline Entity Form module.

composer require drupal/inline_entity_form

1. Once installed, go to the “Manage form display” on the Article row.

2. Then select “Inline entity form – Complex” from the Widget drop-down on the Asset field.

3. Click on the cog wheel and make sure you check both “Allow users to add new media entities.” and “Allow users to add existing media entities.”.

3. Then click on Save.

Now if you go back to the create Article form, you’ll notice that the Asset field looks different.

Just click on “Add new media” if you want to create a new asset. When you click on the button, the create media form appears right here so you can create a new asset and attach it to a content type without leaving the form.

The “Add existing media” button allows you to select existing assets via an autocomplete field.

As you can see Inline Entity Form really does create a better user experience for editors. From the same page you can create/edit/delete and attach assets to a content type without leaving the page.

Part 3: Embedding Assets into the Editor

So far we’ve looked at how to attached assets to fields, but now let’s look at embedding them in the editor.

To build this functionality we’ll need two modules: Entity Embed and Embed.

Entity Embed allows you to create a button which is added to the editor. When you need to embed an asset, just click on the button, select the asset and embed. The module isn’t tied to the Media entity, it can be used to embed any entity type.

Using Composer, download the following modules then enable Entity Embed.

composer require drupal/embed
composer require drupal/entity_embed

Create Embed Button

1. Go to Configuration and click on “Text editor embed buttons”.

2. Click on “Add embed button”, enter Assets into Label and select Entity from “Embed type” and Media from “Entity type”.

3. Further down the page you can specify which bundles (Media types) should be allowed. If none are selected then all are allowed.

You can also upload an icon for the button. I’ll be using the media embed icon which comes with the Drupal 8 version of the Media module. You can grab a copy of it from here.

Once you’ve configured the form click on Save.

Manage Buttons

You can have as many buttons as you want and they can all be managed from the List page. If you need to modify a button then just click on the Edit button in the operations column.

Add Button to Editor

Now that we’ve created the button let’s add it to the editor. It won’t automatically appear in the editor unless we add it ourselves.

1. Go to Configuration and click “Text formats and editors”.

2. Click on Configure on the “Basic HTML” text format.

3. Find the button in the “Available buttons” section and move it into Media in the “Active toolbar” section.

Configure Filters

Now comes the tricky part, we’ve added the button but now we need to configure the filters in a specific order.

Few important steps need to happen here:

  1. Add the correct tags to the “Allowed HTML tags” text area.
  2. Enable “Display embedded entities” filter
  3. Reorder filters in specific order.

Configure “Allowed HTML tags” list

Once the button was added you should see the following tags in “Allowed HTML tags”.

<drupal-entity data-entity-type data-entity-uuid data-entity-embed-display 
data-entity-embed-display-settings data-align data-caption data-embed-button>

Enable “Display embedded entities” Filter

Next, enable the “Display embedded entities” filter from Enabled filters check list.

Confirm Order of “Align images” and “Caption images”

The Entity Embed README.txt mentions if you’re using the “Align images” and “Caption images” filters, to order “Align images” before “Caption images”.

Problem with “Restrict images to this site” Filter

The “Restrict images to this site” filter stops an image being displayed if you embed it and select an image style.

The filter stops a user from pointing to an image which is not hosted on the site. For example, if your Drupal site is hosted at my-drupal.com, then it won’t allow you to add an image such as <img src="http://random-site.com/image.jpg" />, all your images need to be <img src="http://my-drupal.com/image.jpg" />.

There is an open issue on drupal.org about it.

The workaround for now, unfortunately, is to remove the filter.

Once everything has been configured, make sure you click on “Save configuration” at the bottom of the page.

The filters list should look like this:

How to Embed Assets into the Editor

Now that the “Basic HTML” text format has been configured, we should be able to embed assets.

1. Go to Content, “Add content” and click on Article.

2. Click on the embed button and a pop-up should appear with an autocomplete field.

Search for the asset using its “Media name” and click on Next.

3. If it’s an image, select Thumbnail from “Display as”, select an image style, align and add a caption.

Then click on Embed.

4. Once embedded you should see the image on the right with the caption.

Save the page and you’re good to go.

Embedding YouTube Videos

In the section above it was easy to embed an image. You simply upload it, select a thumbnail size and you’re done.

Adding a video using the “Embed video” media type we created earlier is just as easy.

1. Click on the embed button within the editor, and search for a video in the Name autocomplete field.

2. Then select “Full content” from the “Display as” drop-down and click on Embed.

3. Once embedded you should see the YouTube player in the editor.

If you do not see an embedded player and just the video thumbnail then you’ll need to configure the formatter on the Media type.

Go to Structure, “Media types” and click on “Manage display” on the Embed video row.

Make sure the “Video Url” field is using the Video formatter.

Part 4: How to Browse Media Assets

We had to use an autocomplete field to find and embed an asset into the editor in the last section. This type of user experience is not great. You can’t upload an image after clicking on the embed icon, without going to a different page, and you can’t easily search assets, you have to know the name of it.

In section, you’ll learn how to use Entity Browser which lets you create a screen where you can search, select and upload new assets.

Using Composer, download the following modules then enable Entity Browser and Chaos tools.

composer require drupal/ctools
composer require drupal/entity_browser:~2.0

Make sure you download the 8.x-2.0 version of Entity Browser.

How to Create an Entity Browser

Configuring Entity Browser requires two steps:

  1. First you’ll need to create a view using a display called “Entity browser”. This view will be used to list out all assets.
  2. Then you’ll need to configure an entity browser and select the created view.

Create Entity Browser View

1. Go to Structure, Views and click on “Add view”.

2. Fill out the “Add view” form, using the values defined in Table 1-0 and click on “Save and edit”.

Table 1-0. Create a new view

Option Value View name Media browser Machine name Media_browser Show Media type of All sorted by Newest first Create a page Unchecked Create a block Unchecked

3. Next to the Master tab click on “Add” and select on “Entity browser.

It’s important that you select the “Entity browser” display or you won’t be able to select this view when we’re configuring the actual browser.

Let’s change the view to a table so it looks better.

4. Click on “Unformatted list” next to Format.

5. Select Table and click on Apply.

At this point we’ve switched the view from an unformatted list to a table.

Now we need to add two more fields: Thumbnail and “Entity browser bulk select form”.

6. Click on Add next to Fields, add the Thumbnail field.

This will display a thumbnail of the media asset.

7. Then add the “Entity browser bulk select form”.

This field is used to select the asset when browsing. It is a required field.

8. Reorder the fields so they’re as follows:

9. Once complete the preview should look like the image below:

10. Don’t forget to click on Save.

Create Entity Browser

Now that we’ve created the view, let’s configure the browser.

1. Go to Configuration, “Entity browsers” and click on “Add entity browser”.

2. Enter “Assets browser” into Label, select iFrame from “Display plugin” and Tabs from “Widget selector plugin”.

Leave “Selection display plugin” as “No selection display”.

Then click on Next

Do not select Model from Display plugin if you’re using the browser with Entity Embed it isn’t compatible (Issue #2819871).

3. On the Display page, configure a width and height if you like but do check “Auto open entity browser. This will save an extra click when embedding.

Then click on Next.

4. Just click Next on “Widget selector” and “Selection display”.

5. On the Widgets page, select “Upload images as media items” from the “Add widget plugin”. Change the Label to “Upload images”.

6. Then select View from “Add widget plugin”.

7. From the “View : View display” drop-down, select the view which we created earlier.

If you can’t see your view, make sure you select “Entity browser” when configuring it:

8. Once configured the Widgets page should look like:

Configure Entity Embed to use Browser

Entity Embed now needs to be linked to the browser we just created.

1. Go to Configuration, “Text editor embed buttons” and edit the embed button.

2. You should see a drop-down called “Entity browser”, select the browser you just created and click on Save.

Using the Entity Browser

Go into an article or page and click on the Entity Embed button.

You should now see a pop-up with two tabs: “Upload images and view.

From the “Upload images” tab, you can upload a new image and it’ll create an Image media entity.

If you click on view, you’ll see all the media assets.

To embed an asset, just choose which one you want and click on “Select entities”.

Summary

With every new Drupal 8 release you can see that the media functionality is getting better. In Drupal 8.5 , there’s still a lot of manual configuring required but the foundation of how assets are stored exists. If you want to keep track of how everything is progressing then look at “Media in Drupal 8 Initiative” and “Media initiative: Essentials – first round of improvements in core“.

Ivan Zugec

About Ivan Zugec

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 10 years and has successfully completed several large Drupal projects in Australia.

Feb 27 2018
Feb 27

The ability to create and maintain redirects on a website is vital for long-term success.

Once your site has a lot of content, you may need to do a content audit. This will require merging or deleting pages which are no longer important. To maintain the traffic from these deleted or merged pages, you’ll need to create URL redirects. Now I understand this isn’t the most exciting part of site building but it’s important to get it right.

The module which will handle all of this is perfectly named; Redirect.

The Redirect module lets you create and manage redirects using a simple user interface. Just define a source and destination and you’re good to go. You can also track 404 errors, using a sub-module, so if you have a page indexed in Google with a broken path then it’ll be logged and a redirect can be easily created.

In this tutorial, you’ll learn how to:

  1. Create a redirect
  2. Track broken paths
  3. Add domain level redirections
  4. Import redirects via a CSV

Learn how to automate the generation of URL aliases using Pathauto in Drupal 8.

Getting Started

Before we begin, make sure you download and install the Redirect module.

If you use Composer, run the following:

$ composer require drupal/redirect

Or Drush,

$ drush dl redirect

Create a Redirect

Once you have installed the module creating a redirect is very easy.

1. Go to Configuration and click on “URL redirects”.

2. Click on “Add redirect”, enter in a Path (old path) and then select a To (new path).

The To field is an autocomplete field which you can use to lookup content on the site. But you can also add an external URL into the field.

3. From the “Redirect status” drop-down box, you can select which status will be used. Most of the time it’ll be a 301 or 302. Once you’re finished click on Save.

4. You’ll be redirected back to the Redirect page where you can manage existing redirects and create new ones.

Track Broken Paths

The Redirect module ships with a handy sub-module called Redirect 404.

The sub-module logs all the 404s and displays them all with a count in the “Fix 404 pages” page in “URL redirects”. When dealing with redirects, half the battle is figuring out which paths need to be redirected. This sub-module will log all 404s and add a button called “Add redirect” which you can use to create the redirect.

This sub-module could cause performance issues if your site gets a lot of traffic so test accordingly.

Domain Level Redirects

Another sub-module, which Redirect comes with is called “Redirect Domain”, it allows you to create domain level redirects.

A good use of this is when you want to redirect a whole domain, i.e., old-domain.com to new-domain.com. You can create a rule which will redirect anything from old-domain.com/* to new-domain.com, without manually creating redirects.

Import Redirects

Creating redirects manually won’t cut it if you need to add more than 20. If you have a spreadsheet full of redirects then it’s best to look at using Path redirect import.

The module lets you import redirects using a CSV file. All you need to do is prepare everything in a spreadsheet then once you’re ready, export the sheet as a CSV and import it into Drupal using the module.

The format of the CSV is pretty simple:

From,To,Redirect,Language
hello-world,node/1,301,en

From and To are the only required columns. Redirect and Language are optional.

Run CSV Import

Once you’ve installed Path redirect import, go to Configuration, “URL Redirects” and click on the Import tab.

Select a file using the CSV File upload field and click on Import. Once the import is complete you’ll see a message telling you which redirects imported and which didn’t.

The reason the redirects in the above image were bypassed (not imported) is because the page did not exist. When preparing your CSV file make sure the paths and nodes actually exist. For example, if you’re creating a redirect to node/123 and that page doesn’t exist then the module won’t import it in.

Update Existing Redirects

When importing, if you want to update existing redirects then all you need to do is check the “Override existing sources” checkbox when importing.

Global Redirect merged into Redirect Module

The functionality of the Global Redirect module has been merged into Redirect for Drupal 8.  This is great because it means there’s one less module to install.

The Global Redirect settings can be configured by going to the Settings page with “URL redirects”.

Summary

Redirect is one of the must-have modules which is installed on most Drupal sites. But you can use it for more than just managing historical links. Another good use-case is to create vanity URLs. For example, you could create a redirect path domain.com/d8, that’ll redirect to another page within your site. This is especially useful when adding URLs into a presentation, the shorter the URL the more memorable it is.

Ivan Zugec

About Ivan Zugec

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 10 years and has successfully completed several large Drupal projects in Australia.

Feb 13 2018
Feb 13

On a recent project, I had to create a custom page which displays content by the logged in user, think of it as a “My articles” or “My blogs” page. I knew how to do it by writing code but I thought I’d try it with Views and see how far I could get without writing any custom code. Long story short, I was able to do it all by using just the Views module.

In this tutorial, you’ll learn how to create a page which will appear as a tab (local task) on the user profile page.

Getting Started

For once there are no extra modules to download and install. In Drupal 8, Views ships with core and will be automatically installed if you installed Drupal using the Standard installation profile.

If it’s not already installed, go to Extend and install Views and “Views UI”.

Create User Profile Page

The first bit of work we need to do is create an actual Views page.

This page will display a table of articles which is owned by the user, we’ll call it “My articles” and the URI to the page will be /user/%user/my-articles the %user argument will be the user ID which will be used by the contextual filter.

The owner of the content is defined by the user added to the “Authored by” field on the content edit page.

1. Go to Structure, Views and click on “Add view”.

2. Fill in the “Add view” form with the values defined in Table 1.0.

Table 1.0: Add view

Option Value View name My Articles Machine name my_articles Show Content (default) Of Type Article Create a page Checked Page title My Articles Path user/%user/my-articles Display format Table

3. If you go to /user/%user/my-articles replace %user with any number, it should return a table of articles.

Create Contextual Filter

The %user argument getting passed through the URI is not being used at this point. Let’s now add a contextual filter which will use the argument and only display articles which are authored by the user ID.

1. While on the Views edit page, click on Advanced then Add next to Contextual filters.

2. Search for “Authored by” in the Content category and click on Add.

3. Select the “Provide default value” radio button and choose “User Id from route context”

4. Further down the page:

  1. Check “Specify validation criteria”.
  2. Select “User ID” from Validator.
  3. Check “Validate user has access to the User”.
  4. Under “Access operation to check” select Edit.

5. Click on Apply to save the contextual filter, then click on Save to save the view.

Now if you go to the page, /user/%user/my-articles make sure you change %user with an actual user ID, you should only see their articles.

Page Access Control

Please make sure you’ve checked “Validate user has access to the User” and have chosen Edit under “Access operation to check”.

This means that only users who have edit access can access the page. This would be users accessing their own accounts or site administrators who can edit other user accounts.

If you do not then any user who knows the URI /user/%user/my-articles could go directly to it and see which articles are owned by the user.

Display Page as Tab (Local Task)

At this point, we’ve created the page and added a contextual filter to only display articles owned by the user.

Now let’s create a menu for the page so it’s accessible via a tab on the user profile page.

1. While on the views edit page, click on “No menu” link in the “Page settings” section.

2. In the “Page: Menu item entry” window, complete the following:

  1. Select “Menu tab” from Type.
  2. Add “My articles” to “Menu link title”.
  3. Select “<User account menu>” from Parent. This is important if you don’t do this then the tab won’t appear.
  4. Add 5 to weight.

3. Now if you go to the “My articles” page it should go from this:

To this:

If you can’t see the tabs but have configured it properly then try rebuilding the site cache. Go to Configuration, Performance and click on “Clear all caches”.

Summary

The ability to create these types of pages is where Views really shines. Often a client will ask for a content specific page such as a “My blog” or “My articles” page and Views makes it very easy to create these types of pages.

FAQs

Q: “My Articles” tab is not appearing.

First, make sure you’ve chosen “<User account menu>” from the Parent drop-down. Second, try rebuilding the site cache (go to Configuration, Performance and click on “Clear all caches”) and see if that fixes it.

Ivan Zugec

About Ivan Zugec

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 10 years and has successfully completed several large Drupal projects in Australia.

Feb 06 2018
Feb 06

Webform allows you to create powerful forms in Drupal without writing any custom code. One feature I want to show you today is predefined options.

If this is the first time you’ve heard of the module and want to learn more check out our two part series on using Webform.

Predefined options ease the creation of forms by offering common lists such as days, months, time zones, titles, etc…

For example, if you want to add a select list where users choose a country, instead of manually entering in all countries yourself, use the predefined one that comes with the module.

Webform comes with around 30 predefined lists which can be added to radio buttons, checkboxes, select list and menus. You can also create your own.

If you have a website that will use the same set of options on multiple forms, look at creating a predefined options list to save time.

In this tutorial, you’ll learn how to create and use predefined options.

Getting Started

This is part of the Webform module, so I’m going to assume you have it installed.

If you’ve never installed it check out our “Getting Started with Webform in Drupal 8” tutorial.

Use a Predefined Option

Let’s now look at using one of the predefined options in a select element. Let’s assume you need to create a select element with days as the options, Monday, Tuesday, etc…

1. From the Webforms page, go to the Build page of any form by clicking on Build.

2. Then click on “Add element”, search for “select” and click on “Add element” on the Select row.

2018-02-02_22-14-10.png

3. Enter in a title for the element, you could call it Day.

4. From the Options drop-down, select Days and then Save.

2018-02-02_22-16-21

5. If you view the form, you should see a drop-down called Day with days as the options.

2018-02-02_22-19-10.png

You just saved yourself the effort of manually filling out the days.

Manage Predefined Options

To manage all the predefined options go to Structure, Webforms, Configuration and then click on Options.

2018-02-02_14-16-48.png

From this page, you can view all the options create custom options and modify existing ones.

Let’s now modify the Days options so that Monday is the first day.

1. Click on Edit on the Days row.

2. Reorder the options so that Sunday is at the bottom then click on Save.

2018-02-02_22-29-27.png

3. Now if you view the form, Monday should be the first option.

Take note, if you’re using the same predefined option on multiple elements and change the options (like we just did), then the change will appear on all elements.

Create Predefined Options

Creating your own predefined options is very easy.

1. While on the Options page, click on “Add options”.

2. Give your options a label and some values, then click on Save at the bottom of the page.

3. Select your predefined options from the Options drop-down on a select or checkbox element and you’re done.

Summary

The editors and marketers who use Webform to create custom forms will love this functionality. Out-of-the-box it comes with a bunch of common options such as days, months, “time zones”, “country codes” and more. On top of that you can create your own custom options which’ll save you a lot of time in the long run.

Ivan Zugec

About Ivan Zugec

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 10 years and has successfully completed several large Drupal projects in Australia.

Jan 30 2018
Jan 30

If you’re planning to use Bootstrap on your Drupal 8 site, the first obvious thing to do is download and set up the Bootstrap theme. Then, during the site building process, there will come the point where you need to create a few layouts. These layouts could be used for content types with Display Suite, or for custom pages using Panels.

Implementing layouts using the Bootstrap grid system is simple thanks to the Bootstrap Layouts module.

Read our “Getting Started with Bootstrap in Drupal 8” tutorial to learn how to use Bootstrap in Drupal 8.

Bootstrap Layouts is a module that ships a bunch of prebuilt layouts using the grid system in Bootstrap. Best of all, these layouts can be used between Display Suite and Panels, or any module which supports the Layout Discovery module.

The layouts are configurable through Drupal’s administrative UI. For example, you can adjust the width of a two column layout by choosing grid CSS classes from a multi-select field.

All this can be done without overriding a template or writing a custom preprocess hook.

In this tutorial, you’ll learn how to use Bootstrap Layouts with two popular modules: Display Suite and Panels.

Getting Started

Before we begin, go download and install the Bootstrap Layouts theme.

If you use Composer, run the following:

$ composer require drupal/bootstrap_layouts

Or Drush,

$ drush dl bootstrap_layouts

Other Requirements

First, make sure you’re using Bootstrap on your Drupal site. This could be via the Bootstrap theme or another theme which implements Bootstrap.

Read our “Getting Started with Bootstrap in Drupal 8” tutorial to learn how to use Bootstrap in Drupal 8.

Second, you’ll need to use it via a module which implements layouts using the Layout Discovery module. So far, two popular modules which use it are Display Suite and Panels.

Implement Layout using Display Suite

To implement this using Display Suite go ahead and install the module.

If you’re new to Display Suite then read our “Using Display Suite in Drupal 8: How to Customize Content Pages” tutorial with a video.

1. Go to the “Manage display” page of a content type. You can access it by going to Structure, “Content types” and click on “Manage display” from the Operations drop-down.

2. From the “Layout for article in default” tab, select a layout under Bootstrap.

3. Once selected you should see a preview of the layout.

Don’t forget to click on Save.

Change Column Width

One thing I love about Bootstrap Layouts is that you can change the column width without overriding the template.

The preview of layout shows it as having two columns, each 50% wide. Or in “Bootstrap speak”, 6 columns wide. You can change the width of the column by choosing a different class from the Classes select box from a region tab.

Implement Layout using Panels

Now that you know how to configure Bootstrap layouts using Display Suite, let’s look at using it with Panels and Page Manager.

If you’ve never used Panels or Page Manager, then check out our tutorial “How to Build Custom Pages Using Page Manager and Panels in Drupal 8“.

I’m going to assume you’ve already created a Panels page and will be switching the layout to one of Bootstrap Layouts’.

1. Go to Structure, Pages and edit an existing page.

2. Go to the Layouts section in the variant.

3. From the Layout drop-down select a Bootstrap layout, then click on “Change Layout”.

4. After clicking on “Change Layout” another link will appear below Layout on the left called “Layout Regions”. From this page you must add the existing blocks into the new regions. Once completed click on “Update and save”.

I must admit, it’s easy to miss this new page, but it’s a required step to changing layouts.

5. Now you should see a new link below Layout called “Layout Settings”.

From this page you can change the layout settings such as the grid CSS classes for each region. Same as when using Display Suite.

Summary

Bootstrap Layouts makes it really easy to build layouts because it comes with many prebuilt. But the most impressive feature is the ability to change the grid classes from the interface without having to override a template.

FAQs

Q: After clicking on “Change Layout” in Panels for a second time I get an error “You must select a different layout if you wish to change layouts.”. But nothing changes.

After clicking on “Change Layout” a new link will appear called “Layout Regions” below Layouts. You must reassign blocks into the new layout regions. This new link can easily be missed after clicking “Change Layout.

Ivan Zugec

About Ivan Zugec

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 10 years and has successfully completed several large Drupal projects in Australia.

Jan 23 2018
Jan 23

Bootstrap is a front-end framework for building websites. It ships prebuilt CSS and JavaScript components that make building sites fast. It comes with all sorts of common components that every website needs such as a grid system, buttons, drop-down, responsive form elements, carousel (of course) and so much more. As a developer I don’t want to spend time styling yet another button. I just want to know which CSS class to add to an <a> tag so it looks like a button and I’m good to go.

One complaint about Bootstrap is you can spot it a mile away because a lot of developers use the default look-and-feel. When you see the famous Jumbotron you know it’s a Bootstrap site. But with a little bit of effort you can make your site look unique.

Now, another good reason to use Bootstrap is when you’re working with an agency who will design the site but has no Drupal expertize. If they can supply HTML wireframes using Bootstrap then it’s much easier to implement them into Drupal. Yes, in the perfect world it’ll be great to receive a fully built Drupal theme which can be enabled and that’s it. But in reality, most design agencies, unless they specialize in Drupal, don’t know it and this is where Bootstrap can help.

By using Bootstrap, it’ll be easier to work with designers and design agencies because you can discuss things using Bootstrap terminology. For example, a designer may ask, “can we have a sidebar on the right which is 3 columns wide”? Or, they may ask, “make this button on the blog listing page small”.

If you have experience using Bootstrap you should know what I mentioned above.

Luckily for us building a Drupal site using Bootstrap is easy thanks to the Bootstrap theme.

In this tutorial, you learn the following:

  1. Bootstrap theme configuration
  2. Create a Bootstrap sub-theme
  3. Compile Bootstrap locally using Sass

What About Bootstrap 4?

The Bootstrap theme as of this writing only supports Bootstrap 3. For details look at #2554199 in the issue queue.

Other Bootstrap Based Themes

Another theme you should evaluate is the Radix theme. If you know of any other Bootstrap based themes please leave a comment.

Getting Started

Before we can begin, go download the Bootstrap theme from drupal.org.

If you use Composer, run the following:

$ composer require drupal/bootstrap

Or Drush,

$ drush dl bootstrap

Configuring Bootstrap Theme

Before we jump into the advanced topic of sub-theming or compiling Sass. Let’s first look at what the theme offers out-of-the-box. In this section, we’ll look at some of the theme options.

The level of configuration in a Drupal theme varies a lot, however, the Bootstrap theme has a healthy amount of options. Enough to give you flexibility but not too much that you’re overwhelmed or confused.

Once you’ve downloaded the theme go to Appearance and click on “Install and set as default” on the Bootstrap theme.

Hover over 'Install and set as default'

Once installed click on “Settings”.

Bootstrap Settings

From the “Override Global Settings” you can configure common Drupal options such as the logo or favicon. If you’ve configured a Drupal theme in the past this should look familiar.

Override Global Settings options in Bootstrap

The vertical tabs under “Bootstrap Settings” is where you can configure specific Bootstrap options, let’s look at a few.

Fluid container

The “Fluid container” option,  which can be accessed by going to General then Container, this option adds the container-fluid class which’ll display the main region at full width. By default, the main region has a width of 1200px.

For more details check out the Containers section.

Images

While still under General, click on the Images field-set. This option let’s you configure how images will be handled.

Leave “Responsive Images” checked. This adds an img-responsive class to images making them responsive. It adds a max-width:100% so images are resized when viewed on mobile.

The “Default image shape” drop-down allows you to choose a different style for images which is done via CSS. I always leave this set to “None”.

For more details check out the Images section.

Advanced

Let’s now jump down to the “Advanced” section.

In this section, you can configure if Bootstrap will be served from a CDN and which version you want to use.

Theme

From the “Theme” drop-down you can choose a different theme. Most of the options come from Bootswatch.

So your Bootstrap site could go from this:

To this:

Tip: After I selected a theme I had to rebuild the site cache. Go to Configuration, Performance and click on “Clear all caches”. By the way, I chose Slate if you’re wondering.

Loading Bootstrap via a CDN is quick to setup, but hard to customize. If you’re planning to use a CSS processor such as Sass or Less then you’ll need to store Bootstrap locally and compile it.

We didn’t cover every option under “Bootstrap settings”, just the main ones. The rest you can figure out on your own.

Create Bootstrap Sub-theme

So far we’ve looked at changing options within the theme which is great for testing, but if you’re going to use Bootstrap on a proper project then it’s recommended you create a sub-theme.

Why Sub-theme?

When you create a sub-theme, the Bootstrap theme will be the “base theme” which means your sub-theme will automatically inherit all templates and assets such as the CSS and JavaScript.

Your sub-theme will automatically use any template from the base theme unless it’s overridden. If you want to modify the page.html.twig then simply copy it from Bootstrap into your sub-theme templates directory and customize. Drupal will automatically pickup the page.html.twig in your sub-theme instead of the one in Bootstrap.

You should never modify the Bootstrap theme. This way you can keep the Bootstrap theme up-to-date.

If you want to learn more about sub-themes in general. Check out the Creating a Drupal 8 sub-theme, or sub-theme of sub-theme documentation page.

Bootstrap Sub-themes

The way you create a sub-theme can vary. Some themes offer a Drush command to create a sub-theme while others offer starter kits which you just copy and change a few file names.

Bootstrap comes with three starter kits: CDN, Less and Sass. You can see them by going into the starterkits folder in the theme.

If you’re happy with Bootstrap being served over a CDN then choose the CDN kit. If you want to compile Bootstrap using Less or Sass (CSS pre-processors) then choose the corresponding starter kit.

There’s a lot of benefits in compiling Bootstrap CSS locally. You can customize it further and modify the variables which lets you change the colors, headings, fonts and more.

Step 1: Create Sub-theme

Let’s now create a sub-theme using the Sass starter kit. Why Sass? Well that’s my CSS pre-processor of choice. But the following steps can be applied to the other starter kits.

1. Go into the Bootstrap theme and copy the sass folder from starterkits and then paste the folder into /themes/custom.

2. Rename the folder from sass to bootstrap_sass (you can rename it to whatever you want). Once copied and renamed, the path to the sub-theme should be /themes/custom/bootstrap_sass.

Are you required to add sub-themes into a custom folder? No, it’s just best practice when it comes to managing sub-themes.

Your themes folder should look something like this:

3. In the bootstrap_sass sub-theme, replace all instances of THEMENAME in the file name to bootstrap_sass.

Look for the following files:

  • THEMENAME.libraries.yml   => bootstrap_sass.libraries.yml
  • THEMENAME.starterkit.yml => bootstrap_sass.info.yml (NOTE: make sure you change starterkit to info)
  • THEMENAME.theme            => bootstrap_sass.theme
  • /config/install/THEMENAME.settings.yml => bootstrap_sass.settings.yml
  • /config/schema/THEMENAME.schema.yml => bootstrap_sass.schema.yml

4. Now we need to open up a few files and perform a find and replace on the string THEMENAME.

Open the following files:

  • bootstrap_sass.info.yml: Give your sub-theme a name such as “Bootstrap Sass” and find all THEMENAME and replace them with bootstrap_sass.
  • /config/schema/bootstrap_sass.schema.yml: Find all instances of THEMENAME and replace with bootstrap_sass.

Step 2: Download Bootstrap

In the above section we just copied a folder and did a find and replace in the THEMENAME string. Now we need to download the actual Bootstrap library and compile the Sass.

1. Go to the Bootstrap Getting Started page and download the Sass version.

2. Extract the downloaded file into bootstrap_sass, once extracted the path should be bootstrap_sass/bootstrap. You may have to rename the folder after it’s extracted.

3. Now we need to copy over the variables in Bootstrap into our Sass files. This will allow us to override the variables without having to modify the actual Bootstrap library.

Go to bootstrap_sass/bootstrap/assets/stylesheets/bootstrap/_variables.scss and copy the variables into bootstrap_sass/scss/_default-variables.scss. Paste them just below the $icon-font-path variable.

Sass allows you to override variables. When we compile our Sass files, it’ll use the variables in _default-variables.scss instead of the default _variables.scss that ships with the library.

Step 3: Compile Sass using laravel-mix

The final piece to complete this sub-theme is to compile Sass. I won’t go into details on how to install and configure Sass, that’ll be a whole tutorial or two on it’s own. Instead, I’ll show you one of many ways to compile Sass. We’ll use laravel-mix which is a wrapper on top of webpack. Before you begin make sure you download and install Node.js.

Want to use Yarn instead? Look at this issue on GitHub.

1. Go into the sub-theme directory and create a package.json, you can do this by running the following command:

$ npm init

Just follow the prompts. Once complete you should see /themes/custom/bootstrap_sass/package.json.

2. Then install laravel-mix with the following command:

$ npm install laravel-mix

3. In the sub-theme create another file called webpack.mix.js and add the following to it:

let mix = require('laravel-mix');

mix.sass('scss/style.scss', 'css/');
mix.options({
  processCssUrls: false
});

The code above is pretty straightforward, it’ll tell laravel-mix to compile scss/styles.scss into the css directory. Once compiled there will be a single file styles.css and the path will be css/styles.css.

4. Open up package.json and replace the scripts section with the one below:

"scripts": {
  "dev": "NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
  "watch": "NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
  "hot": "NODE_ENV=development webpack-dev-server --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
  "production": "NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},

This adds NPM scripts which you’ll need to use to compile the Sass. You’ll need to run these commands from within the sub-theme.

The two important scripts are:

$ npm run watch

Use this script to automatically compile when a file is changed. This should be used locally while developing a site.

$ npm run production

This script should be run when you’re ready to deploy to production. It’ll uglify the CSS and JavaScript file to reduce the size.

Summary

I hope now you have a better understanding on how to use Bootstrap in your next Drupal project. From a developer’s perspective, it’s great because you can focus on building the site without dealing with small design issues such styling a button. The Bootstrap theme has a good mix of configuration and flexibility. You can use the theme to quickly spin up a website, however, it’ll look very Bootstrappy. Or you can still use it if you want to fully customize the look-and-feel by compiling it yourself.

Other Bootstrap Modules for Drupal 8

There’s a whole bunch of modules which help you use Bootstrap in other parts of Drupal. There’s a page on drupal.org called Bootstrap related modules which lists them out. The two modules I always use with Bootstrap in Drupal 8 is Bootstrap Layouts and Bootstrap Paragraphs.

Bootstrap Layouts lets you configure a layout using its grid system in Panels and Display Suite. Bootstrap Paragraphs ships a bunch of pre-built paragraph types for Bootstrap.

We’ll cover both modules in more detail in future tutorials.

FAQs

Q: I created a sub-theme but I can’t see it on the Appearance page?

Make sure you change THEMENAME.starterkit.yml to bootstrap_sass.info.yml, replace starterkit with info.

Q: I enabled my sub-theme but the site looks broken.

This can happen when you enable a sub-theme before the parent. The simple workaround is to uninstall your sub-theme and then install the Bootstrap theme first, then install the sub-theme.

Q: None of the JavaScript files are getting loaded?

First, make sure you renamed THEMENAME.libraries.yml to bootstrap_sass.libraries.yml. Then in bootstrap_sass.info.yml make sure you update the libraries sections.

From this:

libraries:
 - 'THEMENAME/global-styling'
 - 'THEMENAME/bootstrap-scripts'

To this:

libraries:
 - 'bootstrap_sass/global-styling'
 - 'bootstrap_sass/bootstrap-scripts'
Ivan Zugec

About Ivan Zugec

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 10 years and has successfully completed several large Drupal projects in Australia.

Jul 11 2017
Jul 11

The ability to create a form quickly and easily is a vital piece of functionality in any content management system. A content editor needs the capacity to create a form and add or remove fields.

The days of asking a developer to create a custom form are long gone. An editor should be able to spin up a form for whatever they need.

Luckily Drupal 8 has two good options for building forms: Contact and Webform.

Contact

The Contact module in Drupal 7 and below has always been the go-to module for basic forms as long as you’re happy with the hard-coded fields. If you need an extra field, you would have to write custom code to add it.

Now in Drupal 8, you’re no longer stuck with a single form. Instead, you can create different fieldable contact form types. You can create different contact forms and attach fields to them, the same way as you do on content types.

The Contact module won’t keep any form submissions in Drupal. It’ll send them to a designated email address. To store submissions use Contact Storage module.

Webform

Webform is the original form builder for Drupal. If content editors needed the ability to create forms then this is the module they would use. The module is suited for basic contact forms as well as long multi-page forms.

The 8.x-5.x version of Webform started out as YAML Form and it was decided to make YAML Form the Drupal 8 version of Webform.

Webinar on Contact and Webform

I recently recorded a webinar on Contact and Webform, where I cover both modules and show you how to create a form in each one.

Watch the webinar above or directly on YouTube.

Or jump to a specific section using the links below.

Contact Module

  • What’s new in Contact module (02:03)
  • Manage contact form types (04:34)
  • Create Contact form type (05:05)
  • Default fields on Contact form (06:37)
  • Add field to contact form (07:44)
  • View submission (09:01)
  • Configure “Manage display” (09:57)

Webform Module

  • What’s new in Webform module (12:25)
  • Install Webform (14:11)
  • Overview of Webform admin page (16:31)
  • Create form using Webform (18:33)
  • Adding elements to forms (18:56)
  • Add pages to forms (21:17)
  • Conditionally display fields (22:20)
  • Form settings (28:58)
  • Add email notification to form (31:15)

Webform Integration with Google Sheet

  • Introduction to Zapier (36:30)
  • Create zap in Zapier (38:40)
  • Configure Webform to send post to webhook (39:36)
  • Test integration with Google Sheets (43:27)

Questions

  • Question: how to prevent spam (46:08)
  • Question: Views integration with Webform (55:25)

Mentioned Resources

Jun 14 2017
Jun 14

Pathauto is a module which lets you automate the generation of URL aliases in Drupal. Instead of the URL being “/node/123”, you can have “/blog/article/why-use-drupal”.

The module allows you to define custom patterns which are generated when an entity is created.

URL aliases or URL slugs, help with search engine optimization and they’re more user-friendly.

Drupal core has supported URL aliases for a long time, but they weren’t automatically generated. Pathauto helps with automating the process.

In this tutorial, you’ll learn how to create aliases and patterns, and how to bulk generate paths.

Getting Started

Before we begin, go download and install the following modules:

  1. Pathauto
  2. Token
  3. Ctools

Using Drush:

$ drush dl pathauto token ctools
$ drush en pathauto

Or, using Composer:

$ composer require drupal/pathauto

Manually Create URL Aliases

Pathauto is not required to create aliases. Drupal core uses a module called Path to create them, and it depends on this module. Pathauto simply helps you automate the creation process.

URL aliases can be created in two ways: from the content edit form and the “URL Aliases” page.

To create an alias from the form, click on the “URL path settings” field-set on the right of the form. Then enter the path into “URL alias”.

Another way, go to Configuration, “URL Aliases” and click on “Add alias”.

Create Pathauto Patterns

Let’s first look at how to setup Pathauto patterns. A pattern lets you define what the structure of the URL alias should be. For example, we’ll add “article/[node:title]” for the Article content type.

The module will convert “article/[node:title]” to “article/node-title”. [node:title] will be replaced by the article title.

1. Go to Configuration, “URL aliases” and click on the Patterns tab.

2. Click on “Add Pathauto pattern”.

3. Select Content from “Pattern type” and enter “article/[node:title]” into “Path pattern”.

If you want to see all available tokens, click on “Browse available tokens”.

4. Check Article from “Content type”.

This means that this pattern will only be applied to Article content types.

5. And finally, add Article into Label.

Then click on Save.

Generating an Alias

If you go to the “URL path settings” on a content type, you’ll notice that it looks different once a pattern has been enabled. Now you get a new checkbox “Generate automatic URL alias”.

If this stays checked, then an alias will be generated. If you want to override the generated one, then uncheck it and add your custom alias into the “URL alias” field.

Pathauto Settings

The module settings can be configured by clicking on the Settings tab from the “URL aliases” page.

You can configure a lot on this page, but the few important ones are:

Enable entity types

This lets you turn on Pathauto support for custom entities.

Update action

This lets you define what the module should do when an entity is updated.

Strings to Remove

This lets you define which words will be stripped from the alias.

Punctuation

This allows you to control how special characters are handled.

Now just a friendly warning. Do NOT play around with these settings on a live site. The last thing you want to do is break the URLs on a site that’s already in production. Backup the database before you make any changes.

Bulk Generate Aliases

If you already have a ton of content and want to generate aliases or you want to regenerate them, you can do this by clicking on the “Bulk generate” tab.

First, select which entity type you want to bulk generate. Then select which aliases you want to be generated.

Before running any bulk generation make sure you backup your database.

Delete Aliases

You can batch delete aliases from the “Delete aliases” tab. You can choose which entity types you want to be deleted, or delete all aliases.

But take note of the “Delete options”, make sure you check “Only delete automatically generated aliases”.

This won’t delete aliases which are manually created.

Menu Structure as Path

The challenge in creating a good pattern is trying to figure out which token to use.

Just click on “Browse available tokens.” and look at all the available options. It can be overwhelming to try and figure out what token does what.

One common pattern which I’ve used a few time is to have a path use the parent menu path.

Take for example the following structure:

- Drupal (/drupal)
-- Site Building (/drupal/site-building)
--- Using Views (/drupal/site-building/using-views)

Just imagine the above example is part of the main navigation. “Drupal”, is the first level, “Site Building” is the second and “Using Views” is the third.

Notice how the path for “Using Views” has its parent path, “/drupal/site-building/using-views”. To achieve this type of path just use “[node:menu-link:parent:url:path]” to get the parent.

The full pattern with the title will be: “[node:menu-link:parent:url:path]/[node:title]”.

If you know of any useful tokens, let us know by leaving a comment.

Summary

Pathauto is an essential module which I’ve installed on every Drupal site I’ve worked on. The importance of URL aliases isn’t obvious at first. But if you spend a bit of time coming up with a good set of patterns, it’ll help your site rank well in search engines.

May 30 2017
May 30

You’re not short on choice when it comes to debugging a Drupal website.

You can install Devel and use Kint to print variables to the screen. Or you could use Web Profiler to add a toolbar at the bottom of your site to see how things are performing.

If you’re looking for a proper debugger look no further than Xdebug. It integrates with a lot of IDEs and text editors and I’d recommend you try it out if you’ve never used it.

I recorded a webinar about Drupal 8 debugging which you can watch above.

Here is what I covered in the video:

  • Turn off caching (02:01)
  • Twig debugging (08:26)
  • Using Kint (19:25)
  • Print variables using Kint in Twig template (21:16)
  • Using WebProfiler (22:15)
  • WebProfiler IDE link (26:37)
  • Drupal console debugging commands (31:41)
  • Adding breakpoints to PhpStorm (39:14)
  • Adding breakpoints to Twig templates (43:48)
  • Drupal integration with PhpStorm (45:26)
  • PhpStorm plugins (47:52)

PHP Functions

PHP has two handy functions which can be used to print variables, objects and arrays to the screen.

print_r()

var_dump()

Drupal core comes with its own function: debug().

Devel Module

Devel has been around for as long as I’ve been using Drupal. It comes with a bunch of helper functions for module developers and it has a few handy sub-modules.

The two sub-modules worth mentioning are Kint and Web Profiler.

Kint

This module integrates the Kint library into Drupal and allows you to print variables using the PHP functions: ksm() and kint().

You can also print variables in Twig templates using {{ kint() }}.

Click here to learn how to use Kint in Drupal 8.

Web Profiler

The Web Profiler sub-module adds a toolbar at the bottom of your site and displays useful stats about the number of queries, memory usage and more.

The toolbar gives valuable insight into what’s happening in your Drupal site.

If you want to learn more about Web Profiler, check out our tutorial on using Web Profiler in Drupal 8.

Drupal Console

Drupal Console is a CLI tool for Drupal. It’s implemented using the Symfony Console component. It can be used to provision new Drupal sites, generate boilerplate code and debug Drupal.

Drupal Console comes with a bunch of debug commands. Just search for any command with the term “debug”.

drupal list | grep "debug"

The two that I found most useful are router:debug and container:debug.

Drupal Settings

Drupal 8 caches a lot more things than Drupal 7. Individual rendered elements like a block for example will be cached. Even if you’re logged in or not.

Rendered Twig templates are also cached. This makes Drupal 8 fast, but it can complicate things when you’re writing code. You don’t want to rebuild the site cache every time you make a change in a template or a rendered array.

Most of this caching can be turned off by disabling them in a settings file.

Drupal.org has a good page: “Disable Drupal 8 caching during development”.

Twig Template Discovery

To turn on Twig debugging, make sure you follow the link above. Then add the following into development.services.yml:

parameters:
  twig.config:
    debug: true
    auto_reload: true
    cache: false

The debug: true parameter turns on Twig’s debugging, Twig will display information such as which template it used and its path. It does this my adding HTML comments.

Use the HTML comments to figure out which Twig template you should override and its file name.

PhpStorm

PhpStorm is a commercial IDE which is popular with PHP and Drupal developers. It integrates nicely with Xdebug and the Drupal code base.

Xdebug

Using PhpStorm, you can add a breakpoint somewhere in PHP code and step through as the Drupal request is executed. You can also see what variables are available.

Learn how to configure Xdebug in PhpStorm.

Drupal Integration

PhpStorm also offers Drupal integration and when enabled it allows autocomplete functionality for hooks. No longer will you have to remember a specific hook and its arguments.

Make sure you turn on the integration by searching for “drupal” in the Preferences section.

Extra PhpStorm Plugins

Drupal 8 uses the YAML format for a lot of things throughout its code base; services, routing, permissions, etc…

And in these files you’ll see references to classes and methods.

Take for example this route:

node.add:
  path: '/node/add/{node_type}'
  defaults:
    _controller: '\Drupal\node\Controller\NodeController::add'
    _title_callback: '\Drupal\node\Controller\NodeController::addPageTitle'

There’s no easy way to navigate to the NodeController other than searching for the class name.

However, if you install these three PhpStorm plugins, you’ll be able to navigate to the class or method by pressing command or control then clicking on the reference.

Once you’ve downloaded these plugins, enable them and then enable “Symfony integration”.

Then you should be able to navigate to classes by clicking on the reference while pressing command or control.

Summary

As you can see, you have options when it comes to debugging. If you’re looking for something simple then use Kint. If you prefer a proper debugger then look at Xdebug.

What’s your preferred technique? Leave a comment below.

Apr 18 2017
Apr 18

Prefer watching a video?

Click here to sign up to our newsletter and watch an exclusive video on Image Widget Crop and Focal Point.

If you’ve done any Drupal site building, I’m sure you’ve experienced the following issue. You create an image style with the “Scale and crop” effect and everything is going great until an editor uploads an image with a different aspect ratio.

Now instead of images getting cropped correctly, they’re getting cut in half, or the top part is chopped off, and images are not displaying nicely.

You could fix this problem by tweaking the image style to handle different aspect ratios, but it’ll never be the perfect solution.

The best option is to crop images directly in Drupal, and this is what you’ll learn today.

In this tutorial, you’ll learn how to avoid these situations by using Crop API.

Now, Crop API doesn’t offer any interface on its own; it’s just an API. The two modules that provide an interface are Image Widget Crop and Focal Point. We’ll take a look at these modules in detail, in this tutorial.

Image Widget Crop gives an editor the most flexibility by allowing them to crop images directly within Drupal.

The only downside is they’ll need to manually crop an image every time they upload an image which is okay if you only have a single crop. But it can be cumbersome if you have multiple crops.

If you want full control over how the image is resized then look at using this module.

Focal Point lets an editor select a point on an image and Drupal will crop around it. It’s more automated but doesn’t give you absolute control like Image Widget Crop.

If all you want to do is make sure a particular region of the image is cropped then look at using this module.

Caching

If you’re using some reverse proxy or CDN such as Varnish or CloudFront, you will have issues with images not changing after being cropped. I can’t offer a solution in this tutorial because every case is different so this won’t be covered.

If you know of a good workaround to handle invalidating images, then leave a comment.

Getting Started

Before we begin, go download Crop API, Image Widget Crop and Focal point. For the first part, we’ll only install “Image Widget Crop.”

Using Drush:

$ drush dl crop image_widget_crop focal_point

Crop Images using Image Widget Crop

We’ll start things off my using Image Widget Crop to allow content editors to crop the image on the Article content type.

First, make sure you installed the “ImageWidgetCrop” module.

Create Crop Type

1. Go to Configuration, Crop types and click on “Add crop type”.

2. Enter in Large into Name and “Used to crop the Large image style.” into Description.

3. In Aspect Ratio add 1:1.

This will make it easier to select a crop because the aspect ratio will stay the same.

4. Once completed click on “Save crop type”.

What’s a Soft Limit and Hard Limit?

When you set a soft limit, the select region will change color indicating the soft limit has been reached. But the user can still resize the crop area smaller.

Hard limit, on the other hand, will stop a user from selecting a crop smaller than what’s been defined.

Configure Image Style

Now that we’re created a crop type. The next bit of work we need to do is configure an image style.

In this example, we’ll use the “Large (480×480)” image style which comes with the Standard installation profile.

1. Go to Configuration, “Image styles” and click on Edit on the image style named “Large (480×480)”.

2. Select “Manual crop” from the “Select a new effect” drop-down and click on Add.

3. Select Large from the “Crop type” and click on “Add effect”.

4. Re-order the effect, so it’s above “Scale 480×480” and click on “Update style”.

Let’s recap what we’ve done.

We added a manual crop effect which use the Large crop type we defined earlier. The image style will first process what’s been cropped manually, and then it’ll scale the image to 480×480.

The last effect, “Scale 480×480” is still necessary because the cropped size can be anything greater than 480×480.

Configure the Image Widget Crop

So far we’ve created a crop type and tweaked the Large image style to use the crop. Now let’s set up Image Widget Crop on the image field.

1. Go to Structure, “Content types” and click on “Manage form display” on the Article row.

2. From the Widget drop-down on the Image row, select “ImageWidget crop”.

If you can’t see the option make sure you’ve installed Image Widget Crop module.

3. Click on the cog-wheel and select Large from within the “Crop Type” drop-down.

If you can’t see your crop type make sure you’ve added it to an image style. You can’t just create a crop type; it must be added to an image style for it to appear here.

4. Click on Update to close the “Widget settings”, then scroll to the bottom and click on Save.

Test Image Cropping

Create a test article or modify an existing one. Upload an image, and you should see a collapsed fieldset called “Crop image”, click on it.

Select your crop and click on Save.

Now if you go to the article page the Large image style should display the cropped region.

Automatic Crop using Focal Point

In the last section, you learnt how to manually crop images. The problem, however, is that cropping an image is a manual process. An editor will have to crop each image they upload. It’s okay if you only have one, but on large projects, you could have a couple of crop types. Manually cropping images could be tedious.

Focal Point takes the manual work away and automatically crops around a defined focal point.

Select a focal point once, when you upload an image, and Drupal will handle the rest.

If you’re following along, go ahead and install Focal Point. We’ll configure Focal Point on the Large and Medium image style.

Set Focal Point

Go to any image field widget, and you should see a crosshair on the image. You’re not required to configure a custom image widget. Focal Point takes over the standard image widget.

The only bit of configuring we need to do is modify the Large and Medium image style.

1. Go to Configuration, “Image styles”

2. Click Edit on the Large row.

3. Select “Focal Point Scale and Crop” from the “Select a new effect” drop-down and click on Add.

4. Enter 480 into widget and height.

5. Delete the “Scale 480×480” effect.

6. Click on “Update style”.

Do the same thing for the medium image style. But instead of adding 480 to the width and height, add 220.

Image Widget

Focal Point will only work if you’re using the standard Image widget. You can’t use Focal Point and Image Widget Crop at the same time.

Preview Focal Point

Once the image styles have been configured, you can preview what the crop will look like.

Just go back to an image field and click on the Preview link.

Set Focal Point

To select a focal point just move the crosshair to where you want the focal point and save the form. Drupal will handle the rest.

Summary

Drupal has always been great at manipulating images but Crop API gives power back to the content editors and offers a flexible solution. No longer are you required to hardcode widths and heights into image styles.

Let the editor choose how they want their images cropped.

FAQs

Q: Can I use Image Widget Crop and Focal Point together?

No.

Q: I can’t select a crop from the “Crop type” drop-down even though I created a crop type.

You need to add a crop to an image style for it to appear in the drop-down.

Q: I re-cropped an image, but it hasn’t updated.

Try performing a hard refresh, ctrl+f5 on Windows or cmd + shift + r on Mac.

Feb 20 2017
Feb 20

I’ve been building websites for the last 10 years. Design fads come and go but image galleries have stood the test of time and every client I’ve had has asked for one.

There are a lot of image gallery libraries out there, but today I want to show you how to use Juicebox.

Juicebox is an HTML5 responsive image gallery and it integrates with Drupal using the Juicebox module.

Juicebox is not open source, instead it offers a free version which is fully useable but you are limited to 50 images per gallery. The pro version allows for unlimited images and more features.

If you’re looking for an alternative solution look at Slick, which is open source, and it integrates with Drupal via the Slick module. I will cover this module in a future tutorial.

In this tutorial, you’ll learn how to display an image gallery from an image field and how to display a gallery using Views.

Getting Started

First, go download and install the Juicebox module.

Using Drush:

$ drush dl juicebox
$ drush en juicebox

Download Juicebox Library

Go to the Juicebox download page and download the free version.

Extract the downloaded file and copy the jbcore folder within the zip file into /libraries and rename the jbcore directory to juicebox.

Once everything has been copied and renamed, the path to juicebox.js should be /libraries/juicebox/juicebox.js.

Create a Gallery Using Fields

We’ll first look at how to create a gallery using just an image field. To do this, we’ll create an image field called “Image gallery” and this field will be used to store the images.

1. Go to Structure, “Content types” and click on “Manage fields” on the Article row.

2. Click on “Add field” and select Image from “Add a new field”.

3. Enter “Image gallery” into Label and click on “Save and continue”.

4. Change “Allowed number of values” to Unlimited and click on “Save field settings”.

You’ll need to do this if you want to store multiple images.

5. On the Edit page leave it as is and click on “Save settings”.

Configure Juicebox Gallery Formatter

Now that we’ve created the image fields, let’s configure the actual Juicebox gallery through the field formatter.

1. Click “Manage display”, and select “Juicebox Gallery” from the Format drop-down on the “Image gallery” field.

2. Click on the cogwheel to configure the gallery. Now there a lot of options but the only change we’ll make is to set the image alt text as the caption.

3. Click on the “Lite config” field-set and change the height to 500px.

4. Reorder the field so it’s below Body.

5. Click on Save at the bottom of the page.

Now if you go and create a test article and add images into the gallery you should see them below the Body field.

Create a Gallery Using Views

You’ve seen how to create a gallery using just the Juicebox gallery formatter, let’s now look at using Views to create a gallery.

We’ll create a single gallery that’ll use the first image of every gallery on the Article content type.

1. Go to Structure, Views and click on “Add view”.

2. Fill in the “Add new view” form with the values defined in Table 1-0.

Table 1-0. Create a new view

Option Value View name Article gallery Machine name article_gallery Show Content type of Article sorted by Newest first Create a page Unchecked Create a block Unchecked


3. Click on Add in the Fields section.

4. Search for the “Image gallery” field and add it to the view.

5. Change the Format from “Unformatted list” to “Juicebox Gallery” and click on Apply.

6. On the “Page: Style options” select the image field in “Image Source” and “Thumbnail Source”. The one you added to the View earlier.

You can configure the look and feel by expanding the “Lite config” field-set. You can change the width and height, text color and more.

7. Click on Apply.

8.Click on Add next to Master and select Page from the drop-down.

9. Make sure you set a path in the “Page settings” section. Add something like /gallery.

10. Do not forget to save the View by clicking on Save.

11. Make sure you have some test articles and go to /gallery. You should see a gallery made up of the first image from each gallery.

Summary

The reason I like Juicebox in Drupal is because it’s easy to set up. With little effort you can get a nice responsive image gallery from a field or a view. The only downside I can see is that it’s not open source.

FAQ

Q: I get the following error message: “The Juicebox Javascript library does not appear to be installed. Please download and install the most recent version of the Juicebox library.”

This means Drupal can’t detect the Juicebox library in the /libraries directory. Refer to the “Getting started” section.

Feb 13 2017
Feb 13

The definition of “what a search page is” varies from project to project. Some clients are happy with the core Search module, others want a full blown search engine.

Drupal offers a wide range of options when it comes to building custom search pages. You can create a basic search page using the core Search module or if you’re looking for something advanced you could use Search API.

In the recorded webinar I cover the following:

  • Search in Drupal 7 (1:24)
  • What’s new in Drupal 8 (8:37)
  • Create Search Page using Core Search (15:24)
  • Create Search Page using Views (19:20)
  • How to Modify Search Results (22:34)
  • Introduction to Search API (25:28)
  • How to Create Facets (38:20)

Modules Mentioned in Webinar

Extra Resources

Jan 26 2017
Jan 26

If you ever need to modify content pages, Display Suite is a good choice. It offers a lot of flexibility without learning a brand new interface. You just use the standard “Manage display” page to select a layout and move fields into regions.

Yesterday, I presented a webinar on how to use Display Suite in Drupal 8. The webinar went for around 50 minutes and I covered the following:

  • What’s new in Drupal 8 (2:20)
  • How to set up a Display Suite layout on a view mode (8:20)
  • How to change the wrapper elements (11:03)
  • How to add custom CSS classes (14:15)
  • How to use Display Suite fields (16:10)
  • How to use the “Display Suite Switch View Mode” sub-module (29:00)
  • And finally, how to override a layout (35:47)

Extra Resources

  1. Using Display Suite in Drupal 8: How to Customize Content Pages
  2. Using Display Suite in Drupal 8: How to Use Display Suite Fields
  3. Using Display Suite in Drupal 8: How to Use Switch View Mode Sub-module
Share
Jan 20 2017
Jan 20

Prefer a tutorial? Then read “How to Manage Media Assets in Drupal 8

Yesterday I presented a webinar on how to manage media assets in Drupal 8. The webinar went for just over an hour and we looked at the current state of media management in Drupal 7 and what’s new in Drupal 8.

I spent the rest of the time demonstrating how to:

Jan 16 2017
Jan 16

Join us for a FREE live webinar this week on managing media assets in Drupal 8.
Click here to save your seat!

I attended a core conversation titled “LET’S FIX FILE AND MEDIA HANDLING ONCE AND FOR ALL” at DrupalCon Prague in 2013.

This got my attention, not because the title was in all caps, but because Drupal needed to fix media management, as the title says: “ONCE AND FOR ALL”.

Let’s face it, Drupal doesn’t handle media very well when compared to other systems. I’ve worked with clients who are used to a certain level of functionality when it comes to managing images or videos on websites.

In Drupal 7 you had a few options.

You could use the Media module. But embedding images through the editor could be buggy depending on which module you’d use to implement the editor, i.e., Wysiwyg or CKEditor.

Then you have Scald, which is a pretty good module. Another module which has been around for a long time is IMCE.

However, adding media management into a Drupal site isn’t as straightforward as you think. That’s why I attended the core conversation in Prague. I too thought Drupal needed a great and robust media system.

Fast forward a couple of years since DrupalCon Prague and things have changed.

Thanks to the work from the Drupal Media team, managing media in Drupal 8 has got a lot better.

Now they are working on getting this functionality in Drupal core, which I think is absolutely amazing.

In this tutorial, I’ll show you how to set up media management in Drupal 8.

3 Parts to Handling Media in Drupal

Everyone has their own definition of media management. In this tutorial, I’m going to focus on three parts:

  1. Storing assets
  2. Embedding assets
  3. Browsing assets

I want to give users the ability to create media assets. Then have a button in the editor which they can use to browse assets and then embed them.

We’ll utilize three modules to handle this: Media Entity, Entity Embed and Entity Browser.

What’s Happened to the Media Module?

In Drupal 7, the Media module was jam-pack with a lot of functionality. In Drupal 8, a lot of its functionality has been broken out into seperate modules. There is a Drupal 8 version of Media and it’ll be used to create an out-of-the-box solution. The module doesn’t do much other than ship a bunch of configuration.

Part 1: How to Create Media Entities

To store media assets you’ll need the Media Entity module. The module itself won’t handle any media, it’s just a base entity.

So you’ll need to download other modules which are media providers. For example, if you want to handle images then download and install “Media entity image“. If you want to handle audio files you’ll need the “Media entity audio” module.

For a full list of media handlers go to the Media Entity project page.

I’m only going to focus on two types of assets in the tutorial: images and embedded videos (YouTube or Vimeo).

Let’s start by downloading the following modules:

Then install, “Media image entity” and “Video embed media” (sub-module of “Video embed field”)

Using Drush:

$ drush dl media_entity entity media_entity_image video_embed_field
$ drush en media_entity_image video_embed_media

Create Image Media Bundle

To handle images we’ll need to create a media type for images.

1. Go to Structure and click on “Media bundles”.

From this page you manage all the different media bundles. This is similar to the “Content types” page.

2. Click on “Add media bundle”.

3. Enter Image into Label, “Used for images.” into Description and select Image from the “Type provider” drop-down.

Ignore the other fields for now and scroll to the bottom and click on “Save media bundle”.

You can ignore the “Field with source information” drop-down. We’ll need to create a field and map it after.

4. Now click on “Manage fields” from the Operations drop-down.

We need to create an Image field that’ll be used to store the actual image field.

5. Click on “Add field”, select Image from “Add a new field” and enter Image into the Label field.

6. Leave the “Field settings” page as is and click on “Save field settings” at the bottom.

7. Leave the Edit page as is and click on “Save settings” at the bottom.

8. Click on the Edit tab from the “Manage fields” page to edit the media bundle.

9. Make sure the “Field with source information” drop-down has selected the image field which we created and click on “Save media bundle”.

Type Provider Configuration

The “Media entity” is like any other entity type: it’s fieldable. You can add custom fields, you can configure the form display and general display like you do with content types.

The only difference is, we need to tell the media bundle which field will store the actual file. If you’re creating a document media bundle, then you’d create a File field and select that in “Field with source information”.

Field Mapping

The “Field mapping” section lets you store metadata from the image into custom fields. If you want to store the width, then you’ll need to create a text field and select it from the Width drop-down.

Take note, the possible metadata properties are determined by the type of provider. You’d get different options if you were configuring a document media bundle.

Create Embed Video Media Bundle

Now it’s time to create another media bundle and this one will be used for embedding videos, i.e., YouTube or Vimeo videos.

1. Go back to “Media bundles” and click on “Add media bundles”.

2. Enter “Video embed” into Label, “Used for embedding videos.” into Description and select “Video embed field” from the “Type provider” drop-down.

3. Scroll to the bottom and click on “Save media bundle”.

We won’t have to create a “Video embed” field and map it across like we did for the Image bundle because “Video embed media” module did it for us.

Take note of this message:

So we’ve created our media bundles now let’s look at how to create a media asset.

How to Create a Media Assets

At this point, you can only create assets from the Media page.

1. Go to Content and click on Media.

From this page you can add a media asset and view existing ones.

2. To create an asset just click on “Add media”.

Go ahead and create an image and embeddable video.

Part 2: How to Embed Media Entities

Creating media assets is useful but if you can’t embed them what’s the point of having them.

In this section we’ll embed assets directly into the editor using Entity Embed.

The Entity Embed module allows a site builder to create a button which lets an editor embed entities into a text area, hence the name Entity Embed. It can be used to embed any type of entity not just media bundles. So be creative, you could use it to embed event content types.

To begin, download the following modules:

Using Drush,

$ drush dl embed entity_embed
$ drush en entity_embed

Create Embed Button

1. Go to Configuration and click on “Text editor embed buttons”.

2. Click on “Add embed button”.

3. Add Media into Label, select Entity from the “Embed type” and Media from the “Entity type” drop-down.

4. Once an entity type has been chosen, you can choose which media bundles can be embedded. If none are selected, then all are available.

And finally, upload a button icon which’ll be used in the editor. The default button is just an “E”.

Use this one from the media module: http://cgit.drupalcode.org/media/plain/images/media_embed_icon.png?h=8.x-1.x

At this point you should have two buttons, the Media button which we created and the Node button that comes default with the module.

Add Embed Button to Editor

We created the embed button, now we need to add it to the editor.

1. Go to Configuration, “Text formats and editors” and click Configure on the “Basic HTML” (or any text format) row.

2. Move the icon from the “Available buttons” into the “Active toolbar”.

From this:

To this:

Configure Filters

The next part we need to do is configure the filters.

We need to make sure a few things happen:

  1. Correct ordering of filters or the embedding may not work
  2. Making sure the “Allowed HTML tags” list accepts the tags used by Entity Embed

Configure “Allowed HTML tags” list

As soon as we added the button to the active toolbar, the following tags should be in the “Allowed HTML tags” list:

<drupal-entity data-entity-type data-entity-uuid data-entity-embed-display 
data-entity-embed-display-settings data-align data-caption data-embed-button>

Make sure these tags are in the text field. If not then embedding media assets WILL NOT WORK.

Enable “Display embedded entities”

Enable the “Display embedded entities” filter. This is required for the embedding to work.

Confirm Order of “Align images” and “Caption images”

The Entity Embed README.txt mentions if you’re using the “Align images” and “Caption images” filters, to order “Align images” before “Caption images”.

Problem with “Restrict images to this site” Filter

The “Restrict images to this site” Filter stops an image being displayed if you embed it and select an image style.

The filter stops a user from pointing to an image which is not hosted on the site. For example, if you’re Drupal site is hosted at my-drupal.com, then it won’t allow you to add an image such as <img src="http://random-site.com/image.jpg" />, all your images need to be <img src="http://my-drupal.com/image.jpg" />.

There is an open issue on drupal.org about it.

The workaround for now, unfortunately, is to remove the filter.

Once everything has been configured, make sure you click on “Save configuration” at the bottom of the page.

The filters list should look like this:

How to Embed Media into a Page

Now that the “Basic HTML” text format has been configured, we should be able to embed assets.

1. Go to Content, “Add content” and click on Article.

2. Click on the embed button and a pop-up should appear with an autocomplete field.

Search for the asset using its “Media name” and click on Next.

3. Select Thumbnail from “Display as”, select an image style, align and add a caption.

Then click on Embed.

4. Once embedded you should see the image on the right with the caption.

Save the page and you’re good to go.

Embedding YouTube Videos

In the section above it was easy to embed an image. You simply choose it, selected a thumbnail size and you’re done.

But if you try and embed a YouTube video using the “Video embed” bundle we created earlier. You’ll just see the video thumbnail and not an embedded player, not the desired result.

Create Media Bundle View Mode

The simple solution is to create a custom view mode for the “Video embed” media bundle. Let’s do this now.

1. Go to Structure, “Display modes”, “View modes” and click on “Add view mode”. Then click on Media.

2. Call this view mode Embed and click on Save.

3. Go to Structure, “Media bundles” and go to the “Manage display” page for the “Video embed” bundle.

4. Enable the Embed view mode which we just created by clicking on “Custom display settings” and select it, then click on Save.

5. Go to the view mode by clicking on it on the top left. Remove all the fields except “Video URL”. Make sure Video is selected from Format and “– Hidden –” from Label.

Then click on Save.

Now when you embed a video, select Embed from “Display as”. If you can’t see the new view mode clear the site cache.

Part 3: How to Browse Media Entities

When we chose an asset, we were given just a single autocomplete field.

This is not ideal. You shouldn’t expect your editors to remember the asset name. It’ll be better to have some sort of browser where we can see all the available media assets.

We’ll use Entity Browser to create browsing functionality and best of all, it integrates nicely with Entity Embed.

Let’s set this up now.

To begin, go download the following modules:

Using Drush,

$ drush dl entity_browser ctools
$ drush en entity_browser ctools

How to Create an Entity Browser

There are two steps involved in creating a browser using the module.

First you’ll need to create a view using a display called “Entity browser”. This view will be used to list out all assets. Then you’ll need to configure an entity browser and select the created view.

Create Entity Browser View

1. Go to Structure, Views and click on “Add view”.

2. Fill out the “Add new view” form, using the values defined in Table 1.0 and click on “Save and edit”.

Table 1-0. Create a new view

Option Value View name Entity browser Machine name entity_browser Show Media type of All sorted by Newest first Create a page Unchecked Create a block Unchecked

3. Next to the Master tab click on “Add” and click on “Entity browser.

It’s important that you select the “Entity browser” display or you won’t be able to select this view when we’re configuring the actual browser.

Let’s change the view to a table so it looks a little better.

4. Click on “Unformatted list” next to Format.

5. From the pop-up, select Table and click on Apply.

At this point we’ve switched the view from a list to a table.

Now we need to add two fields: Thumbnail and “Entity browser bulk select form”.

6. Click on Add next to Fields, add the Thumbnail field.

This will display a thumbnail of the media asset.

7. Then add the “Entity browser bulk select form”.

This field is used to select the asset when browsing. It is a required field.

8. Reorder the fields so they’re as follows:

9. Once complete the preview should look like the image below:

10. Don’t forget to click on Save.

Create Entity Browser

Now that we’ve created the view, let’s configure the browser.

1. Go to Configuration, “Entity browsers” and click on “Add entity browser”.

2. Enter “Assets browser” into Label, select iFrame from “Display plugin” and Tabs from “Widget selector plugin”.

Leave “Selection display plugin” as “No selection display”.

Then click on Next

Do not select Model if you’re using the browser with Entity Embed it isn’t compatible (Issue #2819871).

3. On the Display page, configure a width and height if you like but do check “Auto open entity browser. This will save an extra click when embedding.

Then click on Next.

4. Just click Next on “Widget selector” and “Selection display”.

5. On the Widgets page, select “Upload images” from the “Add widget plugin”. Change the Label to “Upload images”.

6. Then select View from the drop-down.

7. From the “View : View display” drop-down, select the view which we created earlier.

If you can’t see your view, make sure you select “Entity browser” when configuring it:

8. Once configured the Widgets page should look like:

Configure Entity Embed to use Browser

Entity Embed now needs to be linked with the browser we created.

1. Go to Configuration, “Text editor embed buttons” and edit the embed button.

2. You should see a drop-down called “Entity browser”, select the browser you just created and click on Save.

Using the Entity Browser

Go into an article or page and click on the Entity Embed button.

You should now see a pop-up with two tabs: “Upload images and view.

From the “Upload images” tab, you can upload a new image and it’ll create an Image media bundle.

If you click on view, you’ll see all the media assets.

To embed an asset, just choose which one you want and click on “Select entities”.

How do you Add a YouTube Video from the Entity Browser Page?

I haven’t figured this out yet. If you know how, leave a comment.

Summary

Adding functionality to a Drupal 8 site to handle media assets can be done and it’s fairly solid. But as you can see there’s a lot of configuration involved. Hats off to the Drupal Media team for creating a flexible suite of modules. With the “Media in Drupal 8 Initiative” in the works, things are looking very promising.

Extra Resources

FAQs

Q: I created a new view mode but can’t see it when I embed an asset.

Clear the site cache.

Q: When I embed an image and select an image style all I see is a red cross.

Disable the “Restrict images to this site” filter.

Jan 12 2017
Jan 12

Yesterday I presented WebWash’s first webinar on Page Manager and Panels. I had lots of fun doing the presentation and was asked some pretty good questions at the end.

In the video above, I cover the following:

  • What’s new in Drupal 8
  • Demonstrate how to create a custom page
  • Show you how to use multiple variants
  • Demonstrate Panels IPE (in-place editor)
  • Finally, I show you how to use Bootstrap Layouts

The video goes for about 45 minutes with questions at the end.

Register for the next webinar: How to Manage Media Assets in Drupal 8.

Jan 09 2017
Jan 09

Join us for a FREE live webinar this week on Page Manager and Panels in Drupal 8.

Click here to save your seat!

Panels has always been my go-to module when it comes to building custom pages in Drupal 7.

Now in Drupal 8 things have changed.

A lot of what Panels did in Drupal 7 has been moved over to Page Manager. Panels itself doesn’t offer a user interface and it is just a variant type in Drupal 8. Also, Page Manager is now its own project, whereas, in Drupal 7 it was part of the Ctools module.

Panels in Drupal 8 integrates with Page Manager and offers a custom variant type which allows you to select different layouts and manage blocks in the layouts. On its own, Panels doesn’t really do anything, you need something like Page Manager to utilize it.

So with that being said, what can Page Manager do?

The module can be used to create arbitrary landing pages such as a homepage or category landing pages. Then Panels can be used to select a layout and add blocks to layout regions.

In this tutorial, we’ll create a homepage which displays a different layout if a user is logged in or not.

Getting Started

Before we can begin, go download the following modules:

Then install Panels and Page Manager UI.

Drush:

$ drush dl panels layout_plugin ctools page_manager
$ drush en panels page_manager_ui

Drupal Console:

$ drupal module:download panels --latest
$ drupal module:download layout_plugin --latest 
$ drupal module:download ctools --latest 
$ drupal module:download page_manager --latest 
$ drupal module:install panels 
$ drupal module:install page_manager_ui

Create Custom Homepage

Let’s begin this tutorial by first creating a custom homepage.

1. Go to Structure, Pages and click on “Add page”.

2. Enter Homepage into “Administrative title” and “homepage” into Path.

3. From the “Variant type” drop-down select Panels. This is where Panels integrates with “Page manager”. Leave everything as is and click on Next.

If you can’t see Panels in the drop-down make sure you’ve installed Panels.

4. On the “Configure variant” page, select Standard from Builder and click on Next.

5. On the Layout page, select “Two column” and click on Next.

If you can’t see layouts in the drop-down try rebuilding the site cache.

6. From the Content page, you can select which blocks appear in which region. Just click on Finish and we’ll configure it in the next section.

Now we’ve completed the “Add page” wizard.

Let’s now customize the layout.

7. Click on Content on the left and from here you can add blocks to regions and change the page title.

8. To add blocks, just click on “+ Add new block”, click on “Recent comments”, select “Left side” from Region and click on “Add block”.

9. Again, click on “+ Add new block”, click on “Recent content”, select “Right side” from Region and click on “Add block”.

Finally, enter “Custom homepage” into “Page title”.

10. Scroll to the bottom and click on “Update and save”.

Set Page as Front Page

Once you’ve saved the page, go directly to “/homepage” and you should see the page with the two blocks on each side.

Now let’s set this page as the front page.

1. Go to Configuration, “Basic site settings” and change the “Default front page” to “/homepage”. Don’t forget the forward slash. This is new in Drupal 8.

2. Now if you go to the homepage you should see the new layout with the two columns.

Page Variants

One thing I loved about Panels in Drupal 7 was the ability to create different page variants. In Drupal 8 Page Manager, has taken over this functionality.

So what are variants?

Variants let you configure multiple layouts on a single page and you configure a selection criteria to determine which variant should be displayed.

For example, we’ll configure the homepage to display a different variant depending if the user is logged in or not. The correct variant is displayed based off the configured selection criteria.

Let’s configure the homepage now.

1. Go to Structure, Pages and click Edit on the Homepage row.

We already have a variant called Panels. Let’s change it so it’s only visible to authenticated users (logged in users).

2. Click on General under the Panels variant and change the Label to “authenticated user”. Then click on “Update and save”.

3. Click on “Selection criteria”, select “User Role” and click “Add condition”.

4. Check “Authenticated user” under “When the user has the following roles” and click Save. Again, click on “Update and save”.

5. Click on Content and change the “Page title” to “authenticated user”. We’ll do this so we know for sure that the right variant is selected.

6. Now click on “Update and save”.

At this point, the variant will only be visible for authenticated user. If you access it as an anonymous user you’ll get a “page not found” error.

Add Variant

Now we need to create another variant for anonymous users.

1. Go back into the homepage edit page and click on “Add variant” in the top right.

2. Enter in Default into Label, select Panels from Type and click on Next.

We won’t need to configure any “Selection criteria” because this should be used as the default homepage. When building sites with variants you should have a default variant ordered last which’ll be used if no selection criteria returns true.

3. On the “Configure variant” page, just click on Next.

4. On the Layout page, select “Two column” from the Layout drop-down and click on Next.

5. Leave the Content page as is and click on Finish.

6. Click on Content and add the “Recent comments” and “Recent content” blocks like we did before.

7. Add “Default homepage” into the “Page title” field so we know the right variant is picked up.

Now test the homepage with two browsers: one as an anonymous user and another as an authenticated user.

Order of Variants

The order of the variant is important. Any variant that has no selection criteria will always return true and be displayed. Ones with a selection criteria should be ordered above ones without any.

So in our case, Page Manager will check the selection criteria for the authenticated user variant, if the user viewing it is logged in then it’ll return true and display the variant. If not, it’ll go to the next variant and check its selection criteria and continue until one returns true.

If no variant returns true, then the user will get a “page not found”.

Variants can be reordered by clicking on “Reorder variants” in the top right corner.

Summary

As you’ve seen, Page Manager and Panels are great for creating custom pages. The page variant functionality alone is worth installing and using the modules. If this is the first time you’re using either module give yourself a bit of time to get up-to-speed with them. They’re powerful, but if you’ve never used them before they can be a bit complicated.

FAQ

Q: Can’t see Panels in the drop-down?

Make sure you’ve downloaded and installed Panels.

Nov 15 2016
Nov 15

In this tutorial series on using Display Suite, we’ve covered the two fundamental use-cases of the module: how to modify layouts and use Display Suite fields.

Now we’ll take a closer look at one of its sub-modules: “Display Suite Switch View Mode”.

The “Display Suite Switch View Mode” module allows an editor to switch which view mode is used on a content page. By default, Drupal will use the “Full content” view mode (if enabled) on content pages, i.e., “node/1”.

But what if you want to choose between two different “Full content” view modes? Well this module has you covered.

So instead of being stuck with a single view mode, you could have one for a layout with a sidebar and another for pages which go full width.

2016-11-08_22-05-03

In this tutorial, you’ll learn how to configure and use the”Display Suite Switch View Mode sub-module.

Getting Started

You’ll need Display Suite installed and ready to go. Read the “Getting Started” section in the first tutorial on how to do this.

The only extra work you’ll have to do is enable “Display Suite Switch View Mode”.

2016-11-08_21-20-36

Create New View Mode

I’ll assume you’ve already configured the “Full content” view mode. Let’s now create a view mode for the second “Full content”.

1. Go to Structure, “Display modes”, “View modes” and click on “Add new Content view mode”.

2016-11-08_21-22-26

2. Click on Content from the “Choose view node entity type”.

2016-11-08_21-23-47

3. Enter “Full content sidebar” into Name, then click on Save.

2016-11-08_21-25-22

At this point we’ve created the view mode, let’s now configure it.

Configure View Mode

1. Go to Structure, “Display Suite” and click on “Manage display” on the Article row.

2. Scroll down to the “Custom display settings” and enable “Full content sidebar”.

2016-11-08_21-27-25

3. Click on the “Full content sidebar” tab and configure the view mode using Display Suite.

I won’t cover how to enable a layout here since it’s covered in this tutorial in detail: “Using Display Suite in Drupal 8: How to Customize Content Pages“.

How to Switch View Modes

Once everything’s been configured, go to the article form and you should see a “Display settings” vertical tab.

Within the tab you can switch view modes by selecting them from the drop-down.

2016-11-08_22-05-03

Permissions

The sub-module offers a useful set of permissions. They can be granted on a per content type basis or you can get access to the drop-down on all content types.

2016-11-09_21-35-47

Summary

By using this module and creating a set of useful view modes, you’ll create a flexible CMS which editors would enjoy using. If you have a requirement to handle different layouts for content types then give this module a go.

FAQs

Q: Can I have this functionality on other entity types?

No, unfortunately this is only available for content types.

Nov 07 2016
Nov 07

In the previous tutorial, you learnt how to customize content pages by using a Display Suite layout. Today, I want to show you how to use Display Suite fields.

Display Suite fields shouldn’t be confused with the standard field system. The best way to think of a field in Display Suite is as a fancy formatter. The field will only render content.

You can’t use it to store values or define a widget like you can with the standard field system.

You’ve already seen these fields in action. If you select a layout you’ll notice a bunch of new fields appear.

2016-11-01_21-48-23

These are Display Suite fields which are implemented by the module.

A field can be created in two ways: in code or through the Display Suite user interface (UI).

Today we’ll look at how to create fields using the Display Suite UI. In a future tutorial, you’ll learn how to implement a field in code.

Getting Started

You’ll need Display Suite installed and ready to go. Read the “Getting Started” section in the last tutorial on how to do this.

I’ll assume you’ve already read the last tutorial and configured the Article content type to use a Display Suite layout.

Create Block Field

The block field is the one you’ll use the most. It allows you to display any block in a Display Suite layout.

At first this may not seem like much, but remember the block system in Drupal 8 is a thousand times better than in Drupal 7. You’ll use blocks in Drupal 8 a lot more to render basic components.

Another reason is, if you want to render a view within a layout. All you need to do is create a view using a block display and add it to the layout using the block field

1. To create a block field, go to Structure, “Display Suite” and click on the Fields tab.

2016-10-30_16-07-04

From this Fields page you can create new fields and manage existing ones.

2. Click on “Add a block field”.

3. Enter “Recent content” into Label, check Node from the Entities check list and select “Recent content” from Blocks and click on Save.

2016-10-30_16-13-50

Limit field
The “Limit field” textarea is useful if you want to control which bundle and view mode a field should appear on. This is especially important if you created a block view which requires a particular field which is only on a specific entity bundle.

4. Once you’ve clicked on Save, you’ll be redirected to a page to configure any block settings. Not all blocks will have settings so you’ll only see this page if they’re present.

2016-10-30_16-15-41

5. Now go to the “Manage display” page on the Article content type we configured in the last tutorial.

Go to Structure, “Display Suite” and click on “Manage display” on the Article row.

2016-10-30_16-28-05

6. Click on the “Full content” tab.

You should see the “Recent content” field in the disabled section.

2016-10-30_16-29-26

7. Move the “Recent content” field in the Header region and select Inline from the Name drop-down.

Scroll to the bottom and click on Save.

8. Go to an article page and you should see the block in the header region.

2016-10-30_16-32-01

Create Token Field

The Token field allows you to display text with token variables, i.e., [node:title].

Click here to learn more about the token system in Drupal 8.

You’d use this field to display static text which wouldn’t change that often. If you need some level of dynamic content then use a token.

Static Content

Let’s now create a basic token field with just static content.

1. Go back to the fields page by going to Structure, “Display Suite” and click on the Fields tab.

2. Click on “Add a token field”.

3. Enter in “Header text” into the Label and select Node from Entities.

2016-10-30_16-39-33

4. In the “Field content” textarea you enter in the actual content with tokens. Enter in “Static header content.”.

2016-10-30_16-40-02

5. Click on Save.

6. Click on the Displays tab then “Manage display” on the Article row.

7. Go into the “Full content” view mode and move “Header text” into the Header region.

8. Now you should see the static text in the header region.

2016-10-30_16-42-31

Using Tokens

Now that you know how to use the token field, let’s place an actual token in it.

1. Go back to the fields page by going to Structure, “Display Suite” and click on the Fields tab.

2. Edit the “Header text” field which you created previously.

3. Change the “Field content” to:

Static header content.

Title: [node:title]

2016-10-30_16-44-42

4. If you go to an article, the title should replace [node:title].

2016-10-30_16-45-42

If you’ve refreshed the page and can’t see the rendered token then you may need to rebuild the site cache. Go to Configuration, Performance and click on “Clear all caches”.

Token User Interface.

I chose [node:title] because I know it’s available on content entities. If you want an interface for viewing all possible tokens then download and install the Token module.

2016-10-30_21-32-03

You’re not required to use the module but it does offer a nice pop-up which lets you view all available tokens.

Copy Display Suite Field

The last bit of functionality we’ll look at is the ability to copy an existing Display Suite field.

I explained in the introduction that when you enable a Display Suite layout you’ll get a bunch of new fields. These Display Suite fields are implemented in code but you only have a single copy of them.

Take for example Title field. You can only assign it to a single region, but what if you want to display the title twice; in header or right region?

Then this is where you’d create a copy of the field. By copying a field it lets you have multiple instances of a single field. This, in turn, lets you add the fields into different regions because they’re separate fields.

Let’s now create a copy of the Title field.

1. Go back to the fields page by going to Structure, “Display Suite” and click on the Fields tab.

2. Click on “Create a copy of a Display Suite Field”.

3. Enter “Second title” into Label.

4. Select Node from Entities.

5. From the Fields drop-down, select “Node – Title”. Then click on Save.

2016-10-30_21-35-07

Now we need to add the field to the Article content type.

1. Click on the Displays tab then “Manage display” on the Article row, then click on the “Full content” tab.

2. Move “Second title” into the Right region and to prove the original field still works, move Title into Header.

3. Click on Save.

4. Now go to an article page and you should see both titles appear.

2016-10-30_21-36-47

Summary

As you’ve seen Display Suite fields are a versatile piece of functionality. They help you add dynamic components such as Views and Blocks into entity pages.

FAQS

Q: I change the content in the fields but nothing appears?

You’ll need to flush the site cache. Go to Configuration, Performance and click on “Clear all caches”.

Q: Is there a way to find the available tokens?

Install the Token module and you’ll get a “Browse tokens” link which’ll show you available tokens. Drupal core does support tokens, but just from an API standpoint. If you want a user interface then you’ll need the module.

Oct 31 2016
Oct 31

You’ve just installed a fresh Drupal 8 website, created a few content types and attached fields to them. So far so good.

Now you want to customize the content pages. On the “Manage display” page you can re-order fields and disable them but you can’t move them into any type of region.

Display Suite enhances the “Manage display” page by offering a drag-and-drop interface for fields.

You can select different layouts and each layout has its own set of regions. The drag-and-drop interface then is used to move fields into these regions, all without writing a single line of code.

The real benefit in using Display Suite is you always have a standard workflow for modifying content pages.

If you’re working in a team, this is even more important; you want to standardize how entity types are customized. Or you’ll end up in a situation where each developer does things their own way.

In this tutorial, you’ll learn how to modify the Article content type layout using Display Suite.

Getting Started

Before we begin, download the following modules: Display Suite and Layout plugin.

Then just install the Display Suite module.

Below are the Drush and Drupal Console commands to download and install:

Drush:

$ drush dl ds layout_plugin
$ drush en ds

Drupal Console:

$ drupal module:download ds --latest
$ drupal module:download layout_plugin --latest
$ drupal module:install ds

Modify “Full content” View Mode

To modify the Article content type, go to Structure and click on the “Display Suite” link.

From this page, you can jump directly to the “Manage display” page for specific entity types and you can modify other Display Suite settings.

2016-08-13_16-19-30

Now, click on “Manage display” on the Article row.

Access “Manage display” from Content Types Page

You can also access the “Manage display” page by going to Structure, “Content types” and click on the down arrow then “Manage display”.

2016-08-24_14-56-57

Both links send you to the same page so it doesn’t matter which is clicked on.

Enable “Full content” View Mode

Scroll down and click on the “Custom display settings” vertical tab, select “Full content” and click on Save.

2016-08-13_16-25-47

This will enable the “Full content” view mode which is used when viewing the article on its own page.

Now at the top you should see a “Full content” tab, click on it.

What’s with the Default view mode?

I personally avoid the Default view mode if possible, it’s used as a fallback. If Drupal displays an entity with a disabled view mode it’ll fallback to the default one.
So just remember, if you want to customize how an article looks on its own page, then enable and use the “Full content” and leave the Default view mode as simple as possible.

2016-08-13_16-35-42

Select Layout

To enable Display Suite on a view mode, scroll down to the vertical tabs and select a layout from the drop-down.

2016-08-13_17-40-13

Select “Two column stacked layout” and click on Save.

You should now be able to move fields into different regions. Go ahead and add the fields into the following regions:

  • Move Body into Left
  • Move Image, Tags and Links into Right
  • Move Comments into Footer

2016-08-13_17-53-42

Don’t forget to click on Save.

At this point, you’ve successfully modified the Article content type using Display Suite.

Enabling Display Suite on a view mode is straightforward. Just select a layout on a specific view mode and that’s it.

Test Layout

Now that everything has been configured, go and create a test article, it should look like the image below:

2016-08-13_18-03-45

Override Layout Template

So far you’ve learnt how to setup Display Suite on the Article content type. We’ve setup the “Full content” view mode to use the “Two column stacked” layout which comes with the module.

What if you want to modify the layout? Luckily, the layout is a template and it can be overridden like any other.

The layout template location and template suggestions can be found on the “Manage display” page.

2016-08-20_21-22-51

In the image above, you can see that the ds-2col-stacked layout is in “modules/contrib/ds/templates”.

2016-08-20_21-27-03

The filename should be ds-2col-stacked.html.twig. Simply copy the template into your theme and adjust the filename based off the template suggestions, then rebuild the cache.

Now you’re ready to modify the template whichever way you want.

Change Wrapper HTML Tags in Layout

Before you start overriding templates, if all you want to do is change which HTML tag is used for a region then take note of this option.

From the “Custom wrappers” vertical tab, you can change the wrapper HTML tag on regions and the layout.

2016-08-20_21-42-58

So if you were to select Footer from the “Wrapper for Footer” drop-down. The Footer will be wrapped with a <footer> tag instead of <div>.

From this:

2016-08-20_21-50-27

To this:

2016-08-20_21-49-46

Add Custom Classes to Regions

Changing the wrapper is useful but you can also add custom classes to regions. This will help designers apply specific styles to certain regions.

If you click on the “Custom classes” vertical tab, on the “Manage display” page, you’ll see the message “You have not defined any CSS classes which can be used on regions.”

2016-08-21_08-36-30

Click on the “Manage region and field CSS classes” link and enter in the following into “CSS classes for regions”.

custom-footer|Custom footer

2016-08-21_08-39-28

Once you click on “Save configuration”, you should be redirected back to “Manage display”.

Now in “Custom classes” you should see the following, here you can choose multiple classes for any of the regions.

2016-08-21_08-43-32

All selected classes will appear on the wrapping element.

2016-08-21_08-48-23

Summary

I really see Display Suite as a must have module. You can do a lot with it just by using its interface. But if that’s not enough, you can override layout templates and even implement custom layouts.

FAQ

Q: I can’t see the “Custom wrappers” or “Custom classes” vertical tabs?

The vertical tabs will only appear once a layout has been selected.

Q: I need to rebuild cache when I change anything in a Twig template.

Twig templates are heavily cached. Even the rendered results of a template is cached.

You’ll need to turn on Twig debug to stop it from caching (learn how to turn on Twig debugging). But make sure you turn off debugging before going live.

Oct 19 2016
Oct 19

I wrote a custom module recently where I needed to programmatically attach a field; similar to how a Body field is added to content types.

If you create a content type, via the “Content types” page, a Body field is automatically added to the content type. If you don’t need the field just delete it, but the default functionality is to have it added.

I needed this same functionality in my custom module; when an entity is created a field is programmatically attached to it.

So I reverse engineered how the Body field gets added to content types. In the Node module, the Body field is exported as field.storage.node.body.yml and the field is attached using the node_add_body_field function.

I implemented my custom module in a similar fashion and everything worked until all the entity bundles with the custom field were deleted. When a new entity type was created you’d get a fatal error saying the custom field, which was programmatically attached, doesn’t exist.

So what happened?

Change Configuration Yaml

Drupal by default will delete a field if it’s no longer used. Now the fix for this is pretty simple.

Open the field storage yaml for a specific field, look for “field.storage.ENTITY.FIELD.yml”.

Persist with no field

Simply set persist_with_no_fields to TRUE in the yaml file. For example, persist_with_no_fields: true.

Let’s take the Body field as an example. If you open up the field storage yaml file, field.storage.node.body.yml, you’ll see that the persist_with_no_fields option is set to TRUE. By default Drupal will set it to FALSE.

Don’t Forget to Import the Configuration Change

Once you’ve modified the yaml file don’t forget to import the configuration change. If you want to learn more about configuration manage in Drupal 8, check out page “Managing your site’s configuration“.

Summary

I do understand this is a fairly niche problem. But if you want fields to persist then set this option to TRUE and you’re good to go.

Jul 28 2016
Jul 28

[embedded content]

While developing a module or modifying a template in Drupal you’ll often print variables, especially if you’re in a preprocess hook.

You learn early on how to use var_dump and print_r function. But these functions can sometimes display too much information and can be hard to filter through the arrays or methods in the variable.

In Drupal 7, with the Devel module, you could use the dpm or dsm function. When used, these functions will print variables at the top of the page or in the message area using Krumo.

Now in Drupal 8, Devel has adopted a new library to print variables and it’s called Kint.

Fig 1.0

Please note, Krumo has been removed from the Drupal 8 version of Devel. The dpm and dsm functions are still there but the variables are printed without formatting.

Fig 1.0

Getting Started

Kint ships as a sub-module in Devel and the library itself is also in the sub-module. So all you need to do is download and install it.

Below are the Drush and Drupal Console commands to download and install:

Drush:

$ drush dl devel
$ drush en kint

Drupal Console:

$ drupal module:download devel --latest
$ drupal module:install kint

Using Kint

As mentioned earlier, Kint comes as a sub-module so it hasn’t replaced the good-old beloved dpm and dsm, these functions are still there.

Instead, you get two new ones: kint and ksm.

kint()

Fig 1.0

The kint function prints everything at the top of the page.

ksm()

Fig 1.0

The ksm function prints the Kint output in the message region of your theme.

Expanding and Collapsing

Once you have a variable printed on the screen you want to drill down and see what’s in it.

Kint allows you to navigate around in two ways. First, if you click anywhere on the row, it’ll expand just the next level.

But if you click on the + icon, it’ll expand all child items below.

Have a look at the GIF below to see how it works.

Fig 1.0

Viewing Stack Trace

When viewing a printed variable, Kint also displays a stack trace just below the output. Click on the + icon below the variable and it’ll expand a stack trace.

Fig 1.0

Using Kint in Twig

Kint can also be used in Twig templates. To print a variable, just add {{ kint() }} into the template and pass a variable in, for example, {{ kint(page) }}.

For this to work, you must turn on Twig debugging. I won’t cover it in this tutorial, but read this documentation page on drupal.org to learn how to do it.

If you’re using the 8.x-1.0-alpha1 version of Devel, then you’ll get a PHP warning when using Kint in a Twig template. This has been fixed in the latest dev version.

Summary

Kint is a good upgrade for the Devel module. The only drawback is you’ll have to retrain your muscle memory to type kint or ksm instead of the old functions.

FAQs

Q: Has dpm() and dsm() been removed?

No, these functions are still there but they won’t print the variable using Krumo as it has been removed from Devel in Drupal 8.

Q: I’m trying to print a variable in a Twig template and nothing is happening.

You must turn on Twig debugging for the {{ kint() }} function to render. Read this page on drupal.org to learn how.

Jun 21 2016
Jun 21

[embedded content]

In the beginning of any Drupal project the site loads very quickly because there aren’t many modules installed. But as you add modules, the performance of the site will become slower and slower.

There’s always a certain point in the project where you realize it’s time to look at the problem and see if it’s a rogue module or some dodgy code, we’ve all seen this.

Trying to debug a performance issue can be tedious work. But often, it comes down to having too many queries loaded on a page.

If you’re on Drupal 7, just enable query logging using the Devel module. This will show all the queries generated at the bottom of the page.

But for Drupal 8 we have something better: Web Profiler.

Fig 1.2

Web Profiler is a Drupal 8 port of the Symfony WebProfiler bundle. The port is possible because Drupal 8 uses Symfony components.

Web Profiler adds a toolbar at the bottom of every page and shows you all sorts of stats such as the amount of database queries loaded on the page, which services are used and much more.

Now there’re a few other ways to profile your Drupal site. A popular one is to use XHProf and Devel integrates with it. You also have the XHProf module.

In this tutorial, you’ll learn how to install and use Web Profiler.

Getting Started

Web Profiler used to be its own project. However, now it’s part of Devel.

Go download the Devel module then install the Web Profiler sub-module.

Fig 1.2

Below are the Drush and Drupal Console commands to download and install:

Drush:

$ drush dl devel
$ drush en webprofiler

Drupal Console:

$ drupal module:download devel --latest
$ drupal module:install webprofiler

Install Libraries

Add highlight.js and D3.js

As far as I can tell these two JavaScript libraries are optional. Web Profiler will still work even if you don’t have these installed.

Highlight.js is used, as you can guess, to add syntax highlighting to code. You can see it used when listing out database queries.

To add highlight.js, just head over to its download page and click on the Download button in the “Custom package” section. Then extract the downloaded zip file into /libraries/highlight so the path to the library is /libraries/highlight/highlight.pack.js.

D3.js is used when viewing the Timeline page.

Fig 1.2

To add D3, just go to its homepage and download the library by clicking on d3.zip. Extract the zip file copy the d3 folder into the /libraries directory so it’s /libraries/d3/d3.min.js.

Using Web Profiler

One thing I like about Web Profiler is that it’s easy to setup. Just install the module and the toolbar will appear on the page. Straightaway you’ll be able to see useful information such as the query count, memory usage and more.

Here are two useful items which’ll appear on the toolbar.

Timeline

Fig 1.2

This shows you the time it took to render the page and memory usage.

If you click on the Timeline item and see an empty page it means you haven’t finished configuring it. You’ll need to add D3 and some code to your settings.php. You can grab the code from the “Displaying Timeline” section.

Database

Fig 1.2

This shows you the amount of queries used to render the page and the total query time. If you want to see all the queries, just click on the Database item.

Enable Extra Toolbar Items

Not all available toolbar items are active by default. To enable them, go to the configuration page by hovering over the Drupal icon on the left and clicking on “Configure Webprofiler”.

Fig 1.2

In the “Active toolbar items” checkbox list you’ll see all the toolbar items. To enable or disable, just check the checkbox and click on “Save configuration”.

Fig 1.2

If you’re learning how to write you’re own service or event, which is new for Drupal 8, then I’d recommend you activate them in the toolbar.

Let us know which toolbar item you like to use in the comments below.

Configuring Web Profiler

Open Discovered Classes in IDE or Text Editor

In a lot of the reports that you get back from Web Profiler, it references a class and method. Take for example the database queries. You can see where the queries are called from.

Fig 1.2

Web Profiler lets you navigate directly to the class and method by clicking it. It’ll open the configured IDE and go directly to the method. This makes it easy to get to the source with a single click.

Let’s configure Web Profiler to open PhpStorm.

Go to the “Webprofiler settings” page (admin/config/development/devel/webprofiler) or click on the “Configure Webprofiler” link by hovering over the Drupal icon on the left.

Click on the “IDE SETTINGS” field-set and add phpstorm:[email protected]&[email protected] into “IDE link”.

Fig 1.2

Please note, I’ve only tested this using PhpStorm on a mac.

Displaying Timeline

For Web Profiler to display the details on the timeline page you must add the following two lines to your settings.php or settings.local.php.

$class_loader->addPsr4('Drupal\\webprofiler\\', [ __DIR__ . '/../../modules/contrib/devel/webprofiler/src']);
$settings['container_base_class'] = '\Drupal\webprofiler\DependencyInjection\TraceableContainer';

Be aware that the code above assumes you’ll add the devel module in /modules/contrib/devel.

Summary

The Web Profiler is a must-have module if you’re doing any development in Drupal 8. It gives you visibility into parts of Drupal which can be hard to debug. If you need to find the order in which events are loaded or how many blocks are displayed, it can help.

I’d recommend you have the toolbar displayed while building the site. This way if a page takes a while to render, then the toolbar will help you debug it.

FAQ

Q: Nothing appears on the timeline page

First, make sure you’ve add the D3 library and you’ve add the bit of code in the “Displaying Timeline” section.

May 25 2016
May 25

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

1. Core Search

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

2. Views Filter

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

3. Search API

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

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

May 10 2016
May 10

[embedded content]

Building a search page isn’t as straight forward as you’d think. At first a client will want something which users can search content, then they may want to modify the search results or even change the ranking of certain content. Long story short, something you thought would be as simple as enabling a module, ends up taking twice as long.

If you need to create custom search pages in Drupal 7, more often than not, you use Search API or create a search page using Views. But the core Search module for Drupal 8 has become more powerful than in Drupal 7. One of the big changes, for site builders, in Drupal 8 is the ability to create custom search pages.

Fig 1.0

However, there’re a few limitations to creating a search page. First, it’ll have a prefix of “search/” in front but the full URL can be changed by creating a URL alias. Second, you can only adjust the content ranking on these pages. If you want to index extra fields or remove ones from being indexed, you’ll still need Search API to do this.

In this tutorial, you’ll learn how to create a custom search page and how to modify the search results by overriding a template.

Getting Started

Just make sure you’ve installed Drupal using the Standard installation profile. By using the Standard profile, it’ll automatically install and configure the core Search module.

If you’re using the Minimal profile, then you’ll need to install the Search module manually.

Generating Test Content

It’s useful to have real content indexed while building a search page. If you’re like me, you don’t like to spend too much time creating dummy content only to have it blown away.

So to generate test content, I’ll use the “Devel generate” sub-module which ships with Devel.

Just install the sub-module and then go to Configuration, “Generate content”. Select which content types you want generated and click on Generate.

How to Create a Search Page

1. Go to Configuration, and click on “Search pages” from within the “Search and Metadata” section.

Fig 1.1

2. Scroll down to the “Search pages” section and from here you can manage the existing pages and create new ones.

Fig 1.2

3. From the “Search page type” select Content then click on “Add new page”.

4. Enter “Site search” in the Label field and add site to Path.

Fig 1.3

Then scroll to the bottom and click on “Add search page”.

5. Once you’re back on the “Search pages” page, you can reorder how they’re displayed.

Fig 1.4

And, you can set the default page by clicking on the down arrow in the “Operations” column.

Fig 1.5

Index Content

Before we can test the search page make sure the site content has been indexed. If it hasn’t then nothing will appear in the search results.

To check the index status, go to the “Search pages” page, the one we’re previously on and look at the “Indexing progress” section.

Fig 1.6

If you see “0% of the site has been indexed.”, then make sure you index the site, by running cron. It can be ran manually by going to “admin/config/system/cron” and clicking on “Run cron”.

Once indexed you should see “100% of the site has been indexed.”.

How to Search for Content

To access the search page directly go to /search and you should see all the search pages as tabs. If you’re logged in as an administrator, you’ll see Content, Users and “Site search” (the one we created).

Fig 1.7

If you’re an anonymous user, by default you won’t see the “Advanced search” field-set and the Users tab. This can be changed by adjusting permissions in Drupal.

So to search for content enter in a keyword into “Enter your keywords” and click search icon.

Permissions

I mentioned in the last section that certain parts of the search page, i.e., “Advanced search” and the Users tab are only accessible if you have permission.

The Search module comes with three permissions: “Administer search”, “Use advanced search” and “Use search”.

Administer search

This permission let’s you access the “Search pages” configuration page.

Use advanced search

This permission allows access to the “Advanced search” field-set.

Use search

This permission is required to access the search. This permission is granted to anonymous and authenticated users when you use the Standard installation profile.

Where is the Permission for Users Tab?

You may have noticed there’s no specific permission for the Users tab. That’s because there is none. Instead, the “View user information” permission from the User module is used to access the tab. This is a bit confusing and I had to look in the code to see which permission is required to access the tab.

So if you want users to search account profiles, give them the “View user information” permission.

How to Modify Search Results

Sometimes you may want to change the markup that’s rendered in the search results. This can be achieved by overriding a specific template. Just copy over the search-result.html.twig file which can be found in the Search module or your base theme.

Summary

The functionality of the search page can very from site to site. Sometimes the out-of-the-box solution is enough other times it’s not. The core Search module should only be used if you’re happy with what it offers. If you need something custom then you’ll need to build your own page using Views (we’ll look at this in the next tutorial) or Search API.

FAQs

Q: Nothing appears when I search for something?

Make sure you’ve indexed the content by running cron.

Q: Anonymous users can’t access the advanced search section?

Assign the Anonymous role the “Use advanced search” permission and they’ll have access to the advanced search form.

Q: Can I change the URL to a search page?

Yes. Just create a URL alias for the search page you want to change.

Mar 29 2016
Mar 29

At March’s Sydney Drupal user group, I did a lightning talk on Page Manager and Panels in Drupal 8. In the talk, I demonstrate both modules and show you how to create a custom homepage with a few clicks. You can watch the whole talk in the video above.

Panels in Drupal 8 has changed considerably. The UI for building pages is now offered by Page Manager, with Page Manager UI installed, and not Panels itself. The UI also changed, but I think it’s much easier to use than in Drupal 7, but that’s my opinion.

How to Install Page Manager and Panels

If you don’t want to watch the video, below are the basic steps to install Page Manager and Panels.

1. Download Page Manager, Panels, Ctools and Layout Plugin.

Drush:

$ drush dl page_manager panels ctools layout_plugin
$ drush en page_manager_ui panels

Drupal Console:

$ drupal module:download page_manager panels ctools layout_plugin --latest
$ drupal module:install page_manager_ui panels

2. Go to Structure, Pages and click on “Add page” to create a custom page.

3. Then click on “Add new variant” and click on Panels in the pop-up.

The “Block page” variant is not meant to be used on production sites. Just use the Panels variant.

Fig 1.1

Feb 16 2016
Feb 16

[embedded content]

Want to learn more about Paragraphs? Then check out our online video course called “Build Edge-to-edge Sites using Paragraphs in Drupal 8“.

So far I’ve introduced you to the Paragraphs module where we created a basic paragraph type which allows you to display content as movable components. Then we looked at how to create container paragraphs, and this time we created a Banner which let us display nested paragraph items.

By now you should have a basic understanding of why you should use Paragraphs and how to use the module.

Today I want to teach you how to display paragraphs edge-to-edge using Bootstrap as the theme. We’ll use the Banner paragraph, which we created in the last tutorial, to display an image full width but have the nested paragraphs centered.

Below is an image of the end result:

Fig 1.2

It’s All About the Containers

We’ll use Bootstrap to streamline the build but we’ll need to change how the container class is used in the page template. For people who don’t know, the container is used to wrap the site content and “contain” any grids within it. In other words, it simply centers the content. Any content outside of the container goes edge-to-edge.

So to style everything, we’ll need the Banner paragraph type to be outside of the container and then have the container on any nested paragraph items.

This is where most of the complexity lays in building this type of site. Controlling where the container gets added or removed can be tricky in Drupal.

For simplicity, we’ll assume all paragraphs (except nested ones) will be displayed at full width. Things start to get complicated when you want to display a paragraph edge-to-edge as well as in a sidebar. So for simplicity all paragraphs will go edge-to-edge.

Getting Started

Make sure you have Paragraphs and Entity Reference Revisions installed and download Bootstrap.

Below are the Drush and Drupal Console commands to download and install:

Drush:

$ drush dl paragraphs entity_reference_revisions bootstrap
$ drush en paragraphs

Drupal Console:

$ drupal module:download paragraphs 8.x-1.0-rc4
$ drupal module:download entity_reference_revisions 8.x-1.0-rc4
$ drupal module:download bootstrap 8.x-3.0-beta2
$ drupal module:install paragraphs

Step 1: Create the Content and Banner Paragraph Type

For this tutorial, you’ll need the Content and Banner paragraph type which we created in the last two tutorials. You can learn how to create the Content paragraph type by reading “Build Edge-to-edge Sites using Paragraphs Module in Drupal 8“. And for the Banner, read “How to Create Powerful Container Paragraphs in Drupal 8“.

Make sure you’ve created these two paragraph types before continuing.

Implement the Banner Preprocess Hook

The Banner paragraph needs a bit of code in its preprocess, don’t forget to implement it or the banner won’t work.

function HOOK_preprocess_paragraph__banner(&$variables) {
  $paragraph = $variables['paragraph'];
  if (!$paragraph->field_image->isEmpty()) {
    $image = $paragraph->field_image->entity->url();
    $variables['attributes']['style'][] = 'background-image: url("' . $image . '");';
    $variables['attributes']['style'][] = 'background-size: cover;';
    $variables['attributes']['style'][] = 'background-position: center center;';
  }
}

Step 2: Configure Bootstrap Theme for Drupal 8

As mentioned in the introduction, we’ll use Bootstrap for the front-end. So go ahead and make sure it’s been downloaded and create a sub-theme. We’ll need to override a few templates so it’s preferable to create your own sub-theme.

Refer to the Bootstrap theme documentation to learn how to create a sub-theme.

Step 3: Modify the Page Template (page.html.twig)

Now that we’ve configured the paragraph types and our Bootstrap theme, let’s make the Page content type edge-to-edge.

As mentioned earlier, the container is used to wrap the site content. The problem now is the page.html.twig, which wraps the content types and paragraphs, implements a container. For this to work, we’ll need to remove the .container class from the page.html.twig.

Now, to make the site some what useful, we only want to remove the container if we’re on a node or content page. We’ll need to create a file called page--node.html.twig which’ll be used if you’re on an article or page.

On a proper site, you may only want a single content type to go edge-to-edge. Often I create a “Landing page” content type which’ll be used to create fluid pages. But an article may have a sidebar so it shouldn’t go edge-to-edge.

To handle this type of logic, a fair bit of custom code is required. For this tutorial, we’ll keep things simple and just assume all content will be edge-to-edge.

Go into your Bootstrap theme and create a file called page--node.html.twig and replace the {% block main %} with the following:

Fig 1.0

{# Main #}
{% block main %}
  <div role="main" class="main-container js-quickedit-main-content">
    <div class="container">
      <div class="row">
        {# Header #}
        {% if page.header %}
          {% block header %}
            <div class="col-sm-12" role="heading">
              {{ page.header }}
            </div>
          {% endblock %}
        {% endif %}
 
          {# Highlighted #}
          {% if page.highlighted %}
            {% block highlighted %}
              <div class="highlighted">{{ page.highlighted }}</div>
            {% endblock %}
          {% endif %}
 
          {# Breadcrumbs #}
          {% if breadcrumb %}
            {% block breadcrumb %}
              {{ breadcrumb }}
            {% endblock %}
          {% endif %}
 
          {# Action Links #}
          {% if action_links %}
            {% block action_links %}
              <ul class="action-links">{{ action_links }}</ul>
            {% endblock %}
          {% endif %}
 
          {# Help #}
          {% if page.help %}
            {% block help %}
              {{ page.help }}
            {% endblock %}
          {% endif %}
      </div>
    </div>
    {# Content #}
    <section>
      {# Content #}
      {% block content %}
        <a id="main-content"></a>
        {{ page.content }}
      {% endblock %}
    </section>
 
  </div>
{% endblock %}

Click here to view the full updated version of page--node.html.twig

In the above code, all we’ve done is move a few DIVs around and made sure the content region has no container.

Once you’ve created the twig file, don’t forget to rebuild the cache.

Step 4: Add Container to Content Paragraph Type

Now we need to add the .container class to the Content paragraph type. This means that when it’s displayed the text will be centered, while the banner will be displayed edge-to-edge.

1. Find the paragraph.html.twig and copy it into the theme and rename it to paragraph--content.html.twig.

2. Replace the code in the file with the following:

{%
set classes = [
'paragraph',
'paragraph--type--' ~ paragraph.bundle|clean_class,
view_mode ? 'paragraph--view-mode--' ~ view_mode|clean_class,
'container',
]
%}
<div{{ attributes.addClass(classes) }}>
 {{ content }}
</div>

Click here to view the full updated version of paragraph--content.html.twig

All we’ve done is add the container class to the classes variable.

3. Don’t forget to rebuild the cache.

Step 5: Test Banner Paragraph

Go ahead and create a banner paragraph with a few nested content paragraphs. Once created it should look something like the image below:

Fig 1.2

Summary

I’ll admit, this is not the easiest thing to build. There’s a lot of moving parts and depending on your requirement it can be built in a few different ways. But it all comes down to who controls the container. Just remember, you must move the responsibility of the container from the page template to the paragraph.

FAQ

Q: I made changes in a template and those changes are not appearing.

Did you rebuild the cache (clear site cache in Drupal 7)? Every time you override a template you must rebuild the cache, same as in Drupal 7.

Jan 24 2016
Jan 24

[embedded content]

Want to learn more about Paragraphs? Then check out our online video course called “Build Edge-to-edge Sites using Paragraphs in Drupal 8“.

In the last Paragraphs tutorial, you were introduced to the module and we created a basic paragraph type called Content. We only skimmed the surface of what the module can really do. To utilize Paragraphs to its full potential you need to learn how to create a container paragraph type and nest paragraph items.

The concept of a container is fairly simple. It’s a paragraph type that has its own paragraph field on it and allows a user to nest paragraph items.

Below is an example of how it’ll be rendered.

Fig 1.0

In this tutorial, we’ll create a container paragraph called Banner, it’ll have two fields: image and paragraphs.

When a banner paragraph is created and an image is uploaded, the image will be displayed as a background style. Now, I do understand there’re multiple ways of doing this, but for simplicity we’ll set it using a background style on the paragraph element.

All nested paragraphs will be rendered inside the container and displayed with the background. If you want to add any other settings, i.e., parallax configuration, you would place it on the container paragraph.

Here is what the end product looks like on a Drupal site.

Fig 1.10

Getting Started

To save time, let’s reuse the paragraph type we created in the last tutorial. Don’t worry, you won’t have to reread the last tutorial again. Simply download this sandbox repo and enable it. Once the module has been enabled you should see the Content paragraph type.

Now make sure you have Paragraphs and Entity Reference Revisions installed.

Below are the Drush and Drupal Console commands to download and install:

Drush:

$ drush dl paragraphs entity_reference_revisions
$ drush en paragraphs

Drupal Console:

$ drupal module:download paragraphs 8.x-1.0-rc4
$ drupal module:download entity_reference_revisions 8.x-1.0-rc4
$ drupal module:install paragraphs

Create Container Paragraph Type

The first bit of work that needs to be done is create the container paragraph type.

1. Go to Structure, “Paragraphs types” and click on “Add a Paragraphs type”.

Fig 1.1

2. Enter in Banner into Label and click on Save.

Fig 1.2

Add Fields to Container Paragraph Type

We created the Banner paragraph type, let’s now add two fields: Image and Paragraphs (the nested field).

1. Expand the Edit button and click on “Manage fields” on the Banner row.

Fig 1.3

2. Click on “Add field”, Select Image from “Add a new field” and add Image into Label. Then click on “Save and continue”.

Fig 1.4

3. Leave the “Field settings” page as the default and click on “Save field settings”.

4. On the Edit page, check the “Required field” checkbox, scroll to the bottom and click on “Save settings”.

So far we’ve done nothing ground breaking. All we did was create an image field and made it mandatory. Now let’s create a paragraph field which’ll be used to nest the paragraphs.

5. Click on “Add field” again, select Paragraph from “Add a new field” and enter Paragraphs into Label. Then click on “Save and continue”.

Fig 1.5

6. On the next page, leave it as the default then click on “Save field settings”.

7. On the edit page, scroll down to the list of paragraph types and select only Content. This will make sure the right paragraph is available. Then click on “Save settings”.

Fig 1.6

Field Widgets

So far we’ve simply created the fields, let’s now make sure the field widgets are configured.

1. Click on the “Manage form display” tab. If required, you can go ahead and change the widget settings. We’ll leave them as the default. Scroll to the bottom and click on Save.

Fig 1.7

Field Formatters

Finally, let’s quickly configure the field formatters.

1. Click on the “Manage display” tab.

2. Set the Label drop-down on the Paragraphs formatter to - Hidden -.

3. Make sure you move the Image field to the Disabled section. We’ll write a bit of code to add the image as a background to the paragraph. So this formatter isn’t needed.

4. The default settings on the paragraph formatter is fine so we won’t touch it. Scroll to the bottom and click on Save.

Fig 1.8

Implement Preprocess Hook

The final piece to this epic puzzle is the preprocess hook. As mentioned in the introduction the image will be added as a background style. We’ll need to implement this via a preprocess hook.

Copy the code below into a module or theme and replace the string “HOOK” with the actual theme or module name.

function HOOK_preprocess_paragraph__banner(&$variables) {
  $paragraph = $variables['paragraph'];
  if (!$paragraph->field_image->isEmpty()) {
    $image = $paragraph->field_image->entity->url();
    $variables['attributes']['style'][] = 'background-image: url("' . $image . '");';
    $variables['attributes']['style'][] = 'background-size: cover;';
    $variables['attributes']['style'][] = 'background-position: center center;';
  }
}

Don’t forget to clear the site cache after adding the hook.

If the above code doesn’t work make sure that the machine name of the banner paragraph is simply banner and that the image field name is field_image. If the machine name for the paragraph or field is different then the code won’t work.

Create a Banner Paragraph

I’ll assume you already added the paragraph field on a content type. We learnt how to do that in the last tutorial. If this is new to you then please read the “Add Paragraph field” in the previous tutorial.

Go ahead and create an article with a paragraph field and create a banner. If everything has been setup, you should see the text in the Content paragraph displayed with the image as the background.

Fig 1.9

Summary

Creating a container paragraph is more advanced but the concept is simple. It simply groups a bunch of paragraphs together and that’s it. When creating these types of paragraphs, it’s good to stand back and map out all the possible paragraph types. Building these types of paragraphs can get very messy if the site requirements keep changing.

Dec 21 2015
Dec 21

Want to learn more about Paragraphs? Then check out our online video course called “Build Edge-to-edge Sites using Paragraphs in Drupal 8“.

Over the last couple of years edge-to-edge, or fluid looking websites, have become popular. You just have to look at a few digital agency websites and you’ll notice the common pattern.

With this design, the page is broken out into separate components. A component could be something as simple as a single text field, or something complex like an image gallery. You may also see scrolling animation on these components. As a user scrolls the text could zoom in from the right and an image could fade in from the left.

How would you build this type of website in Drupal?

Let me introduce you to Paragraphs.

The module allows you to build Paragraph types which an editor can then add to a page using a Paragraph field.

On a decent size website, you could have a few paragraph types: one for entering in text and another to display content in a grid, or another which displays a video.

In this tutorial, you’ll learn the basics of Paragraphs and we’ll setup a simple paragraph type for adding basic text.

In future tutorials, we’ll look at using Paragraphs to manage a dynamic sidebar and how to create an image gallery.

We have a lot to do, so let’s jump right in.

Getting Started

Before we begin, download and install Paragraphs and Entity Reference Revisions.

Below are the Drush and Drupal Console commands to download and install:

Drush:

$ drush dl paragraphs entity_reference_revisions
$ drush en paragraphs

Drupal Console:

$ drupal module:download paragraphs 8.x-1.0-rc4
$ drupal module:download entity_reference_revisions 8.x-1.0-rc4
$ drupal module:install paragraphs

Creating Paragraph Type

When creating a paragraph-powered website the first thing you need to do is look at the designs and look out for common patterns.

For example, there may be a need to display an image and text side-by-side in a grid, or testimonials may need to be displayed. These two examples are perfect candidates for their own paragraph type.

For this tutorial, we’ll create a basic Content paragraph type which’ll have just two fields: Title (text field) and Content (textarea).

1. On the navigation bar click on Structure and “Paragraphs types”.

Fig 1.0

From this page you can create new paragraph types and you’ll be able to manage existing ones. Currently, there are none, so you can’t see any.

2. Click on “Add a Paragraphs type”.

3. Enter Content into the Label and make sure the machine name is content. Then click on Save.

Fig 1.1

4. Now you should be back on the “Paragraphs types” page and you should see the new Content paragraph type which we just created.

If you click on the Edit button down arrow, in the Operations column, you should see a bunch of options such as “Manage fields” and “Manage displays”.

Fig 1.2

If you know how to add fields to content types or other entities than this should look familiar. Managing fields on a paragraph type is the same as on content types and other entities.

Adding Fields to Paragraph Type

I mentioned earlier that the Content paragraph type will have two fields: Title and Content. Let’s now create those fields.

1. From the Edit drop-down click on “Manage fields”.

Fig 1.3

2. Click on “Add field”, select “Text (plain)” from the “Add a new field” drop-down and enter in Title into the Label field.

Fig 1.4

Then click on “Save and continue”.

3. Leave the next page, “Field settings” as is and click on “Save field settings”.

4. Leave the Edit page as is as well and click on “Save settings”.

5. Now, let’s create the Content field. Click on “Add field”, select “Text (formatted, long)” from the “Add a new field” drop-down and enter in Content into the Label field.

Fig 1.5

Then click on “Save and continue”.

6. Same as when creating the Title field, leave the “Field settings” and Edit page as is and simply create the field.

Once the field has been created you should see both of them on the “Manage fields” page.

Fig 1.6

Manage Field Widgets

The astute learner among us may notice that we haven’t configured any widgets yet. We’ve created the fields but we haven’t modified the widgets.

In Drupal 8, the field type and field widgets have been separated between two pages. On the “Manage fields” you simply create the field. On the “Manage form display” you get to configure the field widget.

I talk about “Form displays” in the “Build a Blog in Drupal 8: Content types and Fields” tutorial. I won’t repeat it here so if you want to learn more about it go to the tutorial.

1. Click on “Manage form display” and you should see the two fields we created. The Title widget should be Textfield and for Content it should be “Text area (multiple rows)”. If you like, you can reorder the widgets and configure their settings by clicking on the cogwheel.

Fig 1.7

Once you’ve configured the widgets make sure you click on Save at the bottom of the page.

Manage Field Display

Let’s now configure how the paragraph will be displayed. We do this via the “Manage display” page. If you’ve used Drupal 7 then you should be familiar with this page.

1. Click on the “Manage display” tab.

Fig 1.8

2. The only thing we’ll do is hide the labels. From the Label drop-down select - Hidden - for both fields then click Save.

Fig 1.9

At this point we’ve completed the following:

  1. Created a paragraph type.
  2. Added custom fields to paragraph type.
  3. Configured widgets and formatters on fields.

Add Paragraph Field

When building a paragraph-powered site, you need to setup two things. First, you need to create some paragraph types, which we’ve already done. Second, you need to add a Paragraph field to a content type.

Now let’s add a Paragraph field to the Article content type and start building paragraphs.

1. On the navigation bar click on Structure and “Content types”.

2. Click on “Manage fields” on the Article row. Then click on “Add field”.

3. Select Paragraphs from the “Add a new field” drop-down. Enter in Paragraphs into the Label field. Then click on “Save and continue”.

Fig 1.10

4. Leave the “Field settings” as is and click on “Save field settings”.

5. We’ll also leave the “Edit” as default and click on “Save settings”.

Configure Field Widget

With the field created let’s now configure the widget.

1. Click on the “Manage form display” tab.

2. Drag the Paragraphs field so it sits below the Body field. Then click on Save.

Fig 1.11

Widget Settings

The widget settings for a paragraph field let’s you configure a few things. Let’s take a look at the options. Click on the cogwheel on the field row.

Fig 1.12

Paragraph Title and Plural Paragraph Title

Fig 1.13

This allows you to change the label on the field. Often the word “Paragraph” could confuse users. So you could change the terminology to “Module” or “Component”.

Edit Mode

Fig 1.14

Edit modes allow you to control how the paragraph will be displayed on the node edit form.

Open

Fig 1.15

When using the Open edit mode, the fields on the paragraph type are editable. This is great because you can edit the field easily. However, once you have more than a few paragraph items it can be difficult to reorder them if they’re all opened.

Closed

Fig 1.16

The Closed edit mode collapses all paragraph items. This makes it easy to reorder them. But to modify the paragraph you must first click the Edit button which can be a pain if you’re trying to find a particular paragraph.

Preview

Fig 1.17

The Preview edit mode, similar to the Closed mode, collapses the paragraph item. But the edit mode renders the collapsed paragraph item using a custom view mode called Preview. You can configure how the preview will be displayed by modifying the Preview view mode.

Add mode

The Add mode option lets you configure how new paragraph items will be selected.

You have the three following options. They’re pretty self-explanatory once you see them.

Select list

Fig 1.18

Buttons

Fig 1.19

Dropdown button

Fig 1.20

Form display mode

The Form display mode option lets you select a different form display mode. This is something new in Drupal 8. Form display modes are similar to view modes but they let you control field widgets instead of formatters.

On most websites you’ll leave this as default.

Once you’ve finished configuring the widget settings, click on Update, then Save at the bottom of the page.

Configure Field Formatter

The final bit of configuration we need to do is reorder the field formatter.

1. Click on the “Manage display” tab.

2. Reorder the Paragraph field so it sits under Body and select the Label to - Hidden -.

Fig 1.21

Scroll to the bottom and click on Save.

We’ve finally configured everything. Let’s now go and create an Article with a Paragraph.

Create Article with Paragraphs.

1. Go to Content, “Add content” and click on Article.

2. Enter “Test article” in the Title and scroll down to the Paragraphs field.

3. Click on the “Add Content” and enter in “Paragraph title” in the Title field and “Paragraph content.” into Content.

Fig 1.22

4. Scroll to the bottom and click on “Save and publish”.

You should see the paragraph being displayed after the Body field.

Summary

When building a paragraph-powered website, you must visualize the content as reusable components instead of creating custom fields on content types.

In the next tutorial, we’ll use Display Suite and add sidebar paragraphs to the Article content type.

Dec 07 2015
Dec 07

This tutorial is part of the “Build a Blog in Drupal 8” series:

  1. Content types and Fields
  2. Adding Comments
  3. Using Views
  4. Managing Blocks
  5. Create and Manage Menus
  6. Custom Contact Forms

In the last tutorial, we added a few menus to flesh out the site navigation. Let’s now build on this by creating a few contact forms.

In Drupal 7, the Contact module is used to create basic contact forms. When a user fills them out, an email is sent to configured email addresses.

One limitation in Drupal 7 is you can’t modify the fields on the form. You can create different categories but the form stays the same.

In Drupal 8, things have changed. Instead of having a single form, you can now create different contact form types. Following in good old Drupal tradition, these contact form types are fieldable. This means you can add any custom field to them and this let’s you create proper, albeit basic forms.

So in this tutorial, we’ll create a custom contact form called “Drupal question”. This form will be similar to the standard contact form but we’ll add an extra field called “Drupal version”. This will let the user select a version of Drupal from a drop-down list.

Let’s jump right in.

Standard Contact Form

A default form called “Website feedback” is created when you install Drupal using the Standard installation profile. This form is used as the basic site-wide contact form and a link is displayed in the footer.

Fig 1.1

When the form is filled out an email is sent to a designated email address.

Custom Contact Form

As mentioned in the introduction, contact forms in Drupal 8 are now fieldable. This is great because you can create custom forms directly in core without installing extra modules.

Let’s create our “Drupal question” form.

1. Go to Structure, “Contact forms” and click on “Add contact form”.

Fig 1.0

2. Enter “Drupal question” into Label and enter in an email address into Recipients.

Fig 1.2

Once the form has been filled out, scroll to the bottom and click on Save.

3. You should’ve been redirected back to the “Contact forms” page. Now click on “Drupal question” to see the form.

Fig 1.3

You’ll notice that the form already has a few default fields.

Each contact form will have the following:

  • Sender name
  • Sender email
  • Subject
  • Message
  • Send copy to sender

Even though these are the default fields, you can disable them from the “Manage form display” page so they won’t be shown.

Add Field to Custom Contact Form

In Drupal 8, contact forms are fieldable. So let’s add a drop-down list which let’s users select a Drupal version.

Adding fields to the contact form is the same as adding one to a content type or block type. If you know how to add fields to them, you’ll know how to add them to contact forms.

1. Go to Structure, “Contact forms” and click on “Manage fields” from the Edit drop-down.

Fig 1.4

2. Click on “Add field”, then select “List (text)” from “Add a new field” and add “Drupal version” to the Label field.

Fig 1.5

Then click on “Save and continue”.

3. Enter in the following values into “Allowed values list”. Then click on “Save field settings”.

drupal-8|Drupal 8
drupal-7|Drupal 7

Fig 1.6

4. Finally, let’s make the field mandatory by checking “Required field”, then click “Save settings”.

Fig 1.7

Configure Field Widgets

New in Drupal 8 is the separation between the field and its widget. I discuss the difference between fields and widgets in part one: “Build a Blog in Drupal 8: Content types and Fields

Let’s now configure the field widgets which’ll be displayed on the form.

1. Click on the “Manage form display” tab.

2. Move “Drupal version” to the top, then disable “Subject” and “Send copy to sender”. You can disable them by dragging them into the “Disabled” area.

Once complete the page should look like the image below:

Fig 1.8

Don’t forget to click on Save.

Test Form

Now go to the form by going to “/contact/drupal_question” and you should see the “Drupal version” drop-down list at the top.

If you’re logged in, the “Your name” and “Your email address” will be pre-populated.

Fig 1.9

If you view the form as an anonymous user then you’ll see the full form.

Fig 1.10

Site-wide Contact Form

Each form comes with its own unique URL. This URL is “/contact/[machine_name]”, or in our case it’s “/contact/drupal_question”.

Another thing you can do is configure a site-wide contact form. This form will be accessible via the general URL “/contact”. If you now go to “/contact” you’ll see the “Website feedback” form, this is the default functionality but it can be changed.

Let’s now point it to our “Drupal question” form.

1. Go to Structure, “Contact forms” and click on Edit in the “Drupal question” row.

2. Check “Make this the default form” then click on Save.

Fig 1.11

3. Now if you go to “/contact” you’ll see the form we created.

Storing Submissions

The Contact module in Drupal 8 and all other versions sent the submission as an email. It never stored it in the database.

If you needed to store submissions there was always Webform and Entityform in Drupal 7.

However, in Drupal 8 there’s a module called Contact Storage which stores the submissions in the database.

Configuring it is fairly simple. Just enable it and you’re good to go. All submissions will then be stored in the database.

Submissions can be viewed by going to Structure, “Contact forms” and click on the List tab.

Fig 1.2

Dealing with Spam

If you’re allowing anonymous users to submit contact forms then make sure you implement countermeasures to handle spam.

In Drupal 7, to combat spam you would start by configuring Honeypot and Mollom. Luckily, both modules have Drupal 8 version so make sure you set them up on your Drupal 8 site.

Summary

The Contact module in Drupal 8 is more powerful than any other version of Drupal. You can do a lot out-of-the-box because forms are now fieldable. But will it replace Webform or eForm (Entityform for Drupal 7)? No it won’t. If a client wants the ability to create survey style forms then Webform is still the number one choice. But if all you require is a basic contact form then look at using the Contact module.

Resources

Links

Modules Mentioned

Nov 23 2015
Nov 23

This tutorial is part of the “Build a Blog in Drupal 8” series:

  1. Content types and Fields
  2. Adding Comments
  3. Using Views
  4. Managing Blocks
  5. Create and Manage Menus
  6. Custom Contact Forms

A website’s navigation plays an important part in how easy a site is to use. It’s essential that you spend time fleshing out the overall IA (Information architecture) or you’ll end up with a site that’s hard to use and difficult to navigate through.

Previous versions of Drupal have always offered a simple interface for managing menus, and Drupal 8 is no exception.

In this tutorial, we’ll continue building our site by adding in some menus. We’ll create a custom menu which’ll be used to display links to popular categories, then create an “About us” page and add a menu link to the footer.

This tutorial is part of the “Build a Blog in Drupal 8“. Make sure you’ve read the previous tutorials if you want to follow along.

How to Manage Menus

When you install Drupal 8 using the Standard Installation profile, a menu called “Main navigation” is used as the primary site navigation with the single link called Home. Another, called Footer, is used in the footer region with the single link pointing to the contact form.

Fig 1.0

Create Menu

Let’s now create a custom menu which’ll display a list of curated popular categories. On a blog, these links will help you promote categories and send traffic to those pages.

1. Go to Structure, Menus and click on “Add menu”.

2. Enter “Popular categories” into the Title field and “Curated list of categories.” into “Administrative summary”. Then click on Save.

Fig 1.1

Once it’s been created, you’ll be redirected to the menu edit page. You’ll be able to manage all menu links from here.

Create Menu Link

1. Now click on “Add link”.

2. Enter “Drupal content” into “Menu link title”, enter in the taxonomy term URL to your Drupal category. On my site it’s “/taxonomy/term/1” so I’ll enter that in. Then in Description, enter in “Latest Drupal content.”

Fig 1.2

The Link field is something which is new in Drupal 8 and it allows you to link directly to internal content pages by typing in the title of the content.

However, the autocomplete will only work for node content. You can’t search for a taxonomy term. You can add one manually by adding the internal URI e.g, /taxonomy/term/1. You can also link to external pages or domains just by entering in the absolute URL.

Fig 1.3

Place Menu into Region

Now let’s go and add our new menu into the footer.

1. Go to Structure, “Block layout” and click on “Place block” in the “Footer first” region. Search for “Popular categories” and click on “Place block”.

Fig 1.4

2. Leave the “Configure block” modal pop-up as is and click on “Save block”.

3. Don’t forget to click on “Save blocks” at the bottom of the page.

4. Go to the homepage and in the footer region you should see the menu.

Fig 1.5

The menu links can be managed by hovering over it and clicking on “Edit menu”.

Fig 1.6

Create About Us Page

Now we need to create an “About us” page and place a menu link in the main navigation so it’s easily accessible. We’ll add the menu link directly from the content edit form.

1. Go to Content, “Add content” and click on “Basic page”.

2. In the Title field add “About us” and some text into the Body field.

Fig 1.7

3. In the right sidebar, click on the “Menu settings” vertical tab then check the “Provide a menu link” checkbox.

Fig 1.8

From this settings, you can set the menu link title; this is automatically pulled from the Title field. If you want text to appear when you hover over the link, then add it to the Description field.

The “Parent item” drop-down lets you select a parent menu link or a menu group. By default you can only add menus to the “Main navigation” but other menus can be accessible from this drop-down if configured.

Finally, the Weight field lets you control the order in which the links will be displayed. But I recommend you reorder the links from the menu page because it’s much easier.

Once you’ve defined the menu link, scroll to the bottom and click on “Save and publish”.

4. Now in the header you should see the “About us” before the Home link.

Fig 1.9

Reordering Menu Links

In the image above, “About us” appears before the Home link which is not ideal. Let’s reorder the links so it’s Home first then “About us”.

To reorder the links you must go to the menu edit page and this can be done in two ways. First, you can edit the menu by going to Structure, Menus and by clicking on “Edit menu” in the “Main navigation” row. Another way, is to hover over the menu and click the edit icon then “Edit menu”.

Fig 1.10

Once you’re on the edit menu page, simply drag the Home menu to the top and then click on Save.

Fig 1.11

Now Home should be the first link in the menu.

Summary

From a site building standpoint, the UI for managing menus has stayed relatively the same. If you know how to manage menus in Drupal 7 then you should be fine in Drupal 8.

But from an architectural standpoint, the routing system in Drupal 8 has been rebuilt using Symfony components. If you want to learn more about the technical changes check out this great post, “What Happened to Hook_Menu in Drupal 8?“.

Dec 17 2014
Dec 17

Ctools content types, not to be confused with general content types, are Panels version of blocks. Another name for them are panel panes, but just think of them as more powerful blocks. Because they are Ctools plugins, the code to implement them is easy to write and maintain. Each plugin has their own file, whereas with blocks, you have to cram everything into hook_block_view().

They also integrate with Ctools contexts, which means you get a context object passed directly in the content type and most of the time this is an entity object. No longer will you have to write code which grabs the entity ID from the URL and load the entity.

In this post, we'll create a Ctools content type which displays a "Read more" link, with the link text being configurable. You'll learn how to create a plugin and a settings form for it. Basic PHP knowledge is required if you want to follow along.

Step 1: Integrate your Module with Ctools

Go into your custom module and add the following hook:

/**
 * Implements hook_ctools_plugin_directory().
 */
function morpht_ctools_content_type_ctools_plugin_directory($module, $plugin) {
  if ($module == 'ctools' && !empty($plugin)) {
    return "plugins/$plugin";
  }
}

This hook is used to tell Ctools where plugins are stored. It'll look for the content type plugin in "plugins/content_types".

Step 2: Create Plugin File

Create a file called "read_more.inc" and place it in "plugins/content_types", create these folders if required. Once created, the path to the file should be "plugins/content_types/read_more.inc".

Step 3: Describe Plugin

Open up "read_more.inc" and add the following bit of code at the top:

$plugin = array(
  'title' => t('Read more link'),
  'description' => t('Displays a read more link.'),
  'single' => TRUE,
  'content_types' => array('read_more'),
  'render callback' => 'read_more_content_type_render',
  'required context' => new ctools_context_required(t('Node'), 'node'),
  'edit form' => 'read_more_content_type_edit_form',
  'category' => array(t('Morpht Examples'), -9),
);

The $plugin array is used to describe the plugin. Let's break down this array:

  • 'title': This is the title of the plugin. It'll be used in the Panels administration area.
  • 'description': This is used as the description of the plugin, it's only used in the Panels administration area.
  • 'single': Content types have a concept called subtype, which is an advanced feature and beyond the scope of this tutorial. For basic content types leave this as TRUE. If you want to learn about subtypes check this Drupal Answers post.
  • 'content_types': This is the machine name of the plugin.
  • 'render callback': This is a callback to a function which will be used to render the content type.
  • 'required context': This tells Ctools which context is required for this content type. By using ctools_context_required(t('Node'), 'node'), this content type will only be available for node entities.
  • 'edit form': This is a callback for the edit form. Please note, this edit form must be implemented if you define a 'required context' key.
  • 'category': This allows you to add a content type into a Panels category.

Step 4: Settings Form

The "Read more" link for the content type needs to be configurable. Creating a configuration form for it is pretty easy. In the $plugin array we added "read_more_content_type_edit_form" as our form.

Go ahead and add the following bit of code after the $plugin:

/**
 * Ctools edit form.
 *
 * @param $form
 * @param $form_state
 * @return mixed
 */
function read_more_content_type_edit_form($form, &$form_state) {
  $conf = $form_state['conf'];
  $form['read_more_label'] = array(
    '#type' => 'textfield',
    '#title' => t('Label'),
    '#description' => t('The read more label.'),
    '#default_value' => !empty($conf['read_more_label']) ? $conf['read_more_label'] : 'Read more',
  );
  return $form;
}

/**
 * Ctools edit form submit handler.
 *
 * @param $form
 * @param $form_state
 */
function read_more_content_type_edit_form_submit($form, &$form_state) {
  foreach (array('read_more_label') as $key) {
    $form_state['conf'][$key] = $form_state['values'][$key];
  }
}

I won't go into too much detail about this because it's a basic Drupal form. The read_more_content_type_edit_form() function is the form and read_more_content_type_edit_form_submit() is the submit handler.

Important: If you want to use the 'required context' key, then you must implement an edit form. Thanks Sam152 for the heads up.

Step 5: Render Function

The last piece of the puzzle is the render function. This is the main function which will be used to render the content type. It is the equivalent of using hook_block_view() if you're creating a block.

Add the following function into the plugin:

/**
 * Render callback function.
 *
 * @param $subtype
 * @param $conf
 * @param $args
 * @param $context
 * @return stdClass
 */
function read_more_content_type_render($subtype, $conf, $args, $context) {
  $node = $context->data;
  $block = new stdClass();

  $block->content = l(t("@read_more", array('@read_more' => $conf['read_more_label'])), 'node/' . $node->nid);

  return $block;
}

The HTML that you want to render needs to be added to the "content" property on the $block object, e.g, $block->content.

The "Read more" label from the settings form can be accessed via the $conf variable. And finally, you can get the node entity from the $context via $context->data.

Summary

Now that you know how powerful Ctools content types are I hope this opens your eyes to new possibilities. Best of all, content types can also be used with Display Suite. This means that you can write your content type once and use it with Panels or Display Suite.

Nov 01 2014
Nov 01

Murray and I presented a session at Drupal Camp Sydney 2014 on the Paragraphs module. The presentation had a demo, lecture and a bit of roleplay. We talked about the benefits of chunking content and how Paragraphs could be used.

The Paragraphs module allows you to chunk content together into "paragraphs". Each paragraph type can have its own set of fields. For example, you could have a paragraph type called "List" with an entity reference field that allows you to select and display articles. Once your paragraphs are created you can reorder them by moving them up or down.

To cut a long story short, the module gives editors an amazing amount of flexibility without giving them too much control to break things.

With that said, here are our slides from the presentation:

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