There’s a lot changing in the SEO world everyday. Namely, you don’t have to be super focused on the perfect SEO structure on each page and perfect meta information to achieve ideal placement (though it is still important). Instead, you should be focused on making your website ‘search-friendly’ for external users, and creating a positive UX for on-site users.

This talk gives actionable advice on:

SEO is way more simple than marketers make it out to be, and I want to make sure that all Drupal designers and builders feel confident that their work will be easily found on Google (or Bing if that’s your flavor)!

Watch Designing and Building with SEO in Mind

The authoring experience is core to any content management system. Very few web content admins prefer to work in HTML, so they use a What-You-See-Is-What-You-Get editor nicknamed a WYSIWYG (pronounced whizzy wig). There are many free and paid WYSIWYG solutions out there, but the big two that have been around for 10 years or more and have been adopted into widely available open source projects are CKEditor and TinyMCE. Drupal and WordPress long ago decided to pick one as their recommended editor, and so WordPress uses TinyMCE and Drupal uses CKEditor[1].

The power of a WYSIWYG like CKEditor is in its ability to be customized. Drupal makes it easy to customize the authoring experience for any user role and in any configuration that a site needs. Super Admins can have access to a fully featured “Full HTML” version of the editor while your content authors have access to a “Basic HTML” version that locks out certain kinds of code that may do harm to a website.

Oomph customizes CKEditor for each custom Drupal (or WordPress) site we build. As a best practice, though, we like to start from the same place. We’d like to share our “default” CKEditor set up as well as the steps that you need to take to customize CKEditor yourself.

Customize CKEditor Text Formats by User Roles

Drupal allows multiple CKEditor configurations, and each can be available per user role — as mentioned previously. To understand the ways in which the editor can be customized, we first need to understand the user roles and default configurations.

User Roles

Drupal ships with three main user roles built in — Administrator, Authenticated User, and Anonymous User. More official documentation about User Roles is available from drupal.org.

An Anonymous user is someone that can’t log in — they can only view content on the front end of the site. To call them a “user” is a bit of a misnomer, but their actions are being tracked to the user ID of zero — therefore, Drupal still considers them a user.

An Authenticated user is someone that can log in but they can do very little. A new Drupal installation gives this user only a few permissions — they view Media, view published content, use shortcuts, and use the Basic HTML text format.

Finally, the Administrator can do everything by default. This was the first user created when a new site was installed, and by default, the account has permissions to do everything.

Many more roles can be created and permissioned of course, but these are the ones that come out of a default Drupal install. We usually create a new “Content Editor” user role for our clients as authors on the site with permissions to create and edit content.

Text Formats and Editors

CKEditor is included in Drupal core, so it comes pre-installed. There are three “text-formats” that the default installation of CKEditor comes with — Full HTML, Basic HTML, and Plain text.

These distinctions are very handy, and also by default, they map nicely to the User Roles we described. Plain text for Anonymous users with no ability to create content, Basic HTML for Authenticated users who might be able to author some content, and Full HTML for Administrators that need to have all of the elements that HTML provides.

The Plain text format is there when there is no other format available to a user — there is no WYSIWYG at all, therefore a <textarea> form element is naked of any formatting embellishments.

It is recommended to keep the Plain text editor plain and edit the format as little as necessary, if at all. When starting a new project, we edit the Basic and Full HTML formats to customize them to our liking.

Basic HTML

The Basic HTML editor comes with a small set of options by default — all the controls that you might expect from a rich text web editor, like heading formats, lists, blockquotes, alignment, bold, italic, and others. These options are a little disorganized, in our opinion[2], but since this is Drupal, we can customize it easily.

Out of the box, the Basic HTML format looks like this:

The CKEditor default configuration for Basic HTML text format

In the Toolbar Configuration area, admins can move “Available buttons” from the top row to the “Active Toolbar” below, and arrange them however they wish. We like to follow this grouping of button options:

After the changes are made and saved, the Basic HTML text format looks like this:

Our reconfigured Basic HTML text format

Much better. From here we will probably customize it further as additional modules or custom features add buttons that we decide to turn on for content authors.

One more thing should be looked at before finishing the Basic HTML Text format. If the “Limit allowed HTML tags and correct faulty HTML” filter is enabled (should be the first checkbox right under the Toolbar configuration), there will also be a Filter Settings area at the bottom of the admin page where the allowed HTML is displayed:

The “Limit allowed HTML tags and correct faulty HTML” text area

The default allowed HTML for Basic is:

<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id> <p> <br> <span> <img src alt height width data-entity-type data-entity-uuid data-align data-caption>

We edit ours slightly as follows to be more restrictive:

<a href hreflang target rel> <em> <strong> <cite> <blockquote cite> <code> <ul> <ol start> <li> <dl> <dt> <dd> <h1> <h2> <h3> <h4> <h5> <h6> <p class=""> <br> <img src alt height width> <hr> <sup> <sub> <span lang dir>

Limiting code for the Basic HTML Text format is a good idea. Authors may think that code copied from the web somewhere is fine because it will help them do this one thing, but more often that not it introduces display issues, and at worst, it introduces something malicious.

Full HTML

For Full HTML, the same ideas apply but with a few more options. Again, the default Drupal configuration for the Full HTML text format is this:

The CKEditor default configuration for the Full HTML text format

Not very different from the previous text format — a little more robust — and we improve it our own way.

Our reconfigured Full HTML text format

In addition to the same order and grouping as Basic HTML, we:

After adding StylesMedia, and Language, we get additional plugin settings below the Toolbar Configuration. For Media, edit those settings as you see fit. We try to keep uploads small and force Drupal to compress images that are uploaded straight from a camera. For Languages, depending on the site, you might want to enable to full set of language codes rather than the default six official languages of the United Nations.

Custom Theme Classes in CKEditor

To leverage the power of custom author styles, the Styles dropdown plugin setting is super important. This is how you get theme CSS classes into the editor! The list should take the format of [HTML element to apply the class to].[name of class]|[Label to display to user]

The CKEditor Style dropdown filter settings text area with a sample of what we usually provide to our authors

A subset of the styles that we add are as follows, and might look familiar to people that use Bootstrap utility classes:

p.lead|Paragraph Lead
ul.list-unstyled|List unstyled
span.display-1|Display1
span.display-2|Display2
span.display-3|Display3
span.h1|Header 1
span.h2|Header 2
span.h3|Header 3
span.h4|Header 4
span.h5|Header 5
span.h6|Header 6
span.text-small|Text size small
span.text-lowercase|Text Lower case
span.text-uppercase|TEXT ALL CAPS
span.text-abbr|Abbreviations
span.font-weight-light|Text light weight
span.font-weight-normal|Text normal weight
span.font-weight-bold|Text bold weight

Drupal does not allow the CSS * selector, which would mean that the requested class could be added to any HTML element — the rule can’t look like *.class-name|A Universal Style, for instance. That’s too bad, which is why we do the next best thing and apply most of our custom styles to <span> elements.

These settings allow an author to mix visual heading styles without changing the semantics. We find that it works pretty well. Say, for example, someone is designing the content for their page and they understand that an article with an H1 title needs to have subheads that are H2, and between H2s, you should only use an H3, etc… they understand the semantic structure of the page. But visually, maybe they want the H2s to look like H3s, and the H3s to look like H4s. That can be accomplished with the way we have structured our class naming and the application to <span> tags. The resulting HTML might look like this:

<h1>An introduction to CKEditor</h1>
<h2 class="h3">What is CKEditor?</h2>
<h2 class="h3">Customizing CKEditor</h2>
<h3 class="h4">Basic HTML</h3>
<h3 class="h4">Full HTML</h3>
<h2 class="h3">Getting theme CSS into the Editor</h2>

We get the semantics needed for good SEO and great accessibility, and the author gets the page to look they way that they want.

Matching the preview in CKEditor with your Site Theme

To finalize the customization and to give the author a much more complete experience, we add some code to our site’s theme files that injects the custom visual theme into the CKEditor preview pane. The authors, therefore, will get a much better sense of how their content will look because they will see the site’s fonts, colors, and typography styles.

We go from this:

CKEditor default preview with very basic CSS styles in place

To this:

Our custom theme applied to the contents of CKEditor

By just adding a little bit of code to the theme’s info file, or themes/custom/yourtheme/yourtheme.info.yml:

ckeditor_stylesheets:
  - assets/styles/main.cs

You can use a separate CSS file specifically for CKEditor if you wish, but to keep our CSS DRY, it makes sense to use the same file as the rest of the site — its already loaded and cached after all. When authors apply one of our new custom styles from the Styles dropdown menu they will see it update live in the editor window before they save and view the content.

And that’s it! Your Drupal 8 project has a customized admin experience with CKEditor sharing the same visual styles as your front end.

# Cleaning Text Pasted from Word

Now for a tangent into the world of pasting content from a Microsoft Word document.

Clients are going to cut and paste text from Word documents; you just can’t stop them. Luckily, CKEditor has a robust scrubber that will remove the junk from this code and maintain the most important styling like bold, italic, and headers (even tables if your editor allows them).

The way it works is pretty transparent, too. We keep the button in place for folks who might have used it before, but with CKEditor version 4, anything on the clipboard pasted into the editor will get scrubbed. When the editor detects code on the clipboard that contains junky content from Word, a little notification will pop up and let the user know that it sees what you are doing (shame shame) but it will clean it for you.

The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?
Thanks for the help, CKEditor!

If you press Cancel, the content gets pasted without being scrubbed, while if you press OK, it will. Either way, the paste of new content happens and the allowed tags portion of the Editor configuration will kick in and do its job (which may remove some of the code from Word, but probably not all).

Test it yourself with the sample Word document on this page: ckeditor.com/docs/ckeditor4/latest/features/pastefromword.html

Just one Gotcha

But there is a pretty big catch to all of this. It might seem obvious, but it needs to be stated — don’t expect Paste from Word to work unless “Limit allowed HTML tags and correct faulty HTML” is turned on. If you are using the Full HTML text format, and the format allows any and all HTML code, Paste from Word will do nothing!

We had a scenario in which the client used the Full HTML editor because they needed access to Drupal Tokens and a few custom pieces that are rather advanced. When they pasted content from Word, though, they were getting all of the code that Word exports and the visual experience was not what they expected. When we took a look and saw the source code, we didn’t understand at first why the Paste from Word filter was not working.

What we (at Oomph) should have done was give them these advanced features in the Basic HTML editor, with “Limit allowed HTML tags and correct faulty HTML” turned on and perhaps a more complex and lengthy list of allowed HTML. This would have been a little more work but it would have saved time in the long run.

Sidebar to the Sidebar: Why is content from Word so bad?

You may be wondering, why does this matter? Microsoft Word is publishing software that 83% of the business world uses, how can it be that bad? Well, Word was created for the world of printing documents, not managing content on the web. On the web and in the projects we create, there is a visual theme that should control the look of all the content. The content pasted from Word tries to force its own visual styles over the styles of the custom theme. On top of all that, the code is terribly bloated.

Here is a simple example of a single three-word headline:

<h1 align="center" style="margin:12pt 0in; -webkit-text-stroke-width:0px; text-align:center"><span style="font-size:22pt"><span style="line-height:31.386667251586914px"><span style="break-after:avoid-page"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-weight:normal"><span style="caret-color:#000000"><span style="color:#000000"><span style="font-style:normal"><span style="font-variant-caps:normal"><span style="letter-spacing:normal"><span style="orphans:auto"><span style="text-transform:none"><span style="white-space:normal"><span style="widows:auto"><span style="word-spacing:0px"><span style="-webkit-text-size-adjust:auto"><span style="text-decoration:none"><span style="font-family:Georgia"><span style="color:black">&nbsp;Recognition of Achievement</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></h1>

All this should actually be is:

<h1>Recognition of Achievement</h1>

In performance speak, that’s 922 bytes (one byte is one character) when it should be only 35 — an increase of 2600%!

All of these inline <span> tags with inline “styles” will override the site’s custom theme, making the content of this page look inconsistent. Some of these styles do nothing on the web at all — break-after:avoid-pageorphans:auto, and widows: auto are print styles, and the units pt and in are also for print. Other tags are inefficiently nested — font-family and color are declared twice (the innermost CSS rule wins, by the way). If you want to get really geeky, we discovered that the properties caret-color> and font-variant-caps are not even supported by Microsoft’s own web browser.

So yes, content cut and pasted from Word without any cleanup really is that bad.

What We Learned

And knowing is half the battle… or maybe just one tenth.


Footnotes

  1. Drupal moved CKEditor into core in version 8. Previously, developers needed to pick their preferred editor and install it as a module. Return ⤴
  2. Why is Blockquote grouped with Media, like an image? No text alignment? “Formatting” and “Block Formatting” as labels? C’mon Drupal, we can do better. Return ⤴
  3. Removing the paste option is important as you can read in another section. Since this Text Format allows all HTML, using the paste tools would do nothing to strip content of bad HTML and styles. Return ⤴

In this video from New England Drupal Camp, November 17, 2018, Director of Design & UX J. Hogue reviews how we approach building a flexible set of components for our clients using Drupal 8 and the popular Paragraphs Module. These component-based design systems make it easier to administrate complex landing pages, quicker for the author to design with their content, all within a brand-aware design system that keeps the visuals consistent for the consumer.

Through five projects (and growing), our internal design framework allows our team to craft new design systems for clients that can grow with their content. The design systems we create offer variety within constraints — that is what Paragraphs does so well. Why is a design system so important for clients authoring new content? Because ideally, it removes the pressure from thinking about what the content should look like, and instead, allows the author to focus on which components should I use to tell the best story with my content?

Paragraphs offer the most visual flexibility for the client and the most design-system control for the development team. If you haven’t yet been convinced, this talk just might make you a believer, too.

Real-world Application

We’ve seen this be true for a client earlier this year. We were given about 10 weeks to design and implement two different reports that took the form of long scrolling pages. These reports needed to have some visual distinction from each other — they should have a “family” resemblance, but they also had different audiences so a certain amount of visual distinction was needed. And, oh by the way, the content was not entirely written yet. And they wanted to get started on design now.

How were we going to solve this? How were we going to get 2500 words with images, videos, and testimonials onto two different pages with different look-n-feels? A design system seemed like the best answer.

Myself and our Senior Drupal Architect got together and collaborate on a technical design solution. We whiteboarded some ideas, and what started to emerge was what I am presenting here today. We broke things down into an abstract system first — one that would work within Drupal and Paragraphs, and then applied a visual design on top. Along the way, we identified configuration options that should shift, expand, or contract. We added an animation system. We added custom CK Editor styles for greater typographic control and custom element support. In short, we developed, designed, prototyped, and received client approval in tandem. We met our 10 week deadline and learned a ton in the process.

Our Legos

The pieces we use to design a page are simple in that they have a minimum of configuration needed to work. Any embellishments become visual, not functional, and therefore the author has to only concentrate on their content and how best to present it.

Our system is row-based, with a basic Row and a Hero Row forming the basis of the organization. We then have content components — a WYSIWYG component, a Testimonial, an Accordion, and Media in the form of an Image and a Video.

Our design options are many — horizontal and vertical alignment, 18 different layouts, background colors, background images, borders, animations, and some extras. Don’t worry, the video goes over all of these options in a visual way to make it easier to understand how flexible this system really is.

Getting started with Oomph Paragraphs

For the developers in the audience, our team has rolled out this framework into a public Drupal Module that we have created for ourselves to achieve consistency between projects. Even though it is an internal project, we released it publicly and are working to follow all Module best practices because we think this is a great way to jumpstart development with a solid foundation for a design system. Contributions and feedback are welcome.

Traditional pages should be a thing of the past. The modern web experience is composed of small pieces of content arranged into a cohesive story. For an author, a single content area is fine for a blog post—a single story that expounds upon one thought. But for a modern website with many landing pages—places where the user needs to decide what they want to do next—a single content column will no longer suffice. We need modular content and a better way to manage its creation.

At An Event Apart this April, Ethan Marcotte was talking about the future of design and User Experience in a multi-device world. Specifically, he said that we should:


[…] design networks of content that are composed of patterns. These patterns, which are small responsive patterns themselves, can be stitched together to create composite experiences like pages.


— From Luke W.’s notes

In other words, the idea of “pages” needs to be blown apart into smaller patterns. Break free from the single content area and create compelling experiences for a modern audience!

We at Oomph agree, and the roadmap that we drew last summer while designing and developing the new BCBS.com (launched in November, 2016) was already blowing the old idea of pages apart with a modular content system.

How did we get here?

Why have we been bound by a single content area? This all goes back to the prevalence of blogs and content management systems (CMSs), which, for ease of use, created just one main content area. For an author of a blog post, one content area is enough as they are writing a single story. But for business sites that need to market a product or service, it is usually not enough.

For Blue Cross and Blue Shield Association, when we were discovering ways in which we could redesign their site, we recognized that they needed to break out from the constraints of the single content area provided by CMSs. The new BCBS.com was going to be built on Drupal 8, so we needed to think about solutions within that ecosystem.

Why we Chose the Drupal Paragraphs Module

Modern CMSs have started to handle multiple chunks of content, and within the Drupal community there are a few ways to address it. The downfall—in our minds—with a few of these solutions is that they put all of the power into the hands of the authors. If you have a team of savvy people that understand interface design, responsive design, and are not afraid to get their hands dirty with some HTML, that can work. In our experience, though, it is too much power and authors are more liable to break something—either break the rendering of the page or break too far outside the brand guidelines. These solutions are difficult to use and typically get abandoned by the author.

Instead of unlimited options, what we as the design and development team wanted was the ability to define our own set of options that we could then expose to the authors. We’d build each set of options into a small responsive pattern, which allows the author to concentrate on their content and how they want to tell a story.

The Paragraphs Module can do exactly that. It adds a new field type that works like Entity References, and with it, we can define all sorts of Paragraph Types and configurable options to give to authors. For the end viewer, the experience has visual variety, but it never veers off brand or looks broken. For the author, they have many options but do not need to think about what happens to their content for mobile or tablet. Those decisions have been baked into each Paragraph Type.

What we Built for BCBSA

We based our modular design patterns on a simple “card” consisting of an optional icon, an optional background (could be color, image, or gradient), and a WYSIWYG content field. These elements had many, many options associated with them:

From here, we defined 10 different Paragraph “Rows” of cards and other types of content. Each of these bundles have responsive design built in — they are small responsive patterns that can be stitched together to create pages:

With these options and rows together, the BCBSA team can create fantastic long-form content pages as well as complex landing pages that can still use Drupal’s Body Content area, Featured Images, and even Blocks and Views.

Oomph & BCBSA ❤ Paragraphs

With Drupal and Paragraphs, both the Oomph and BCBSA teams are very excited about the extensive possibilities of a curated system of modular components, options, and rows. Authors have a large but controlled set of options which makes every page feel unique but on brand, and the viewers get a fully responsive experience without any additional work.

We’ve become believers in this kind of system and have already started adapting it to other clients who need to solve a similar problem. We could design a custom system of Paragraphs and options for you, too.


Resources:

Amodern design-to-development workflow for the web involves multiple tools for site maps, wireframing, testing, and design before we even start to touch HTML and CSS in a browser. Is there a way to move from low-fidelity responsive wireframes to high-fidelity design in the browser with an HTML prototype?

Whether or not you use a popular CMS to build your sites, getting into coded HTML and CSS early can benefit any project. J. Hogue, Director of Design & UX at Oomph, recently presented “Prototyping Design to Jumpstart Development” at Design Week Rhode Island, during which he discussed new methods we’re using at Oomph to get a project into code as soon as possible.

We are proud to share his well-attended discussion in its entirety, and we invite you to join the conversation.

Watch “Prototyping Design to Jumpstart Development”