Sep 03 2019
Sep 03

2007 is the year of my first DrupalCon, and the year the #1 most wanted end-user feature was Better media handling. 2019 is the year that Drupal will finally have it. Doing things right takes time!

Back then I never would’ve believed I would some day play a small role in making it happen :)

Without further ado, and without using a mouse:

The text editor assisted in producing this HTML:

<p>Let's talk about llamas!</p>

<drupal-media alt="A beautiful llama!" data-align="center" data-entity-type="media" data-entity-uuid="84911dc4-c086-4781-afc3-eb49b7380ff5"></drupal-media>

<p>(I like llamas, okay?)</p>

If you’re wondering why something seemingly so simple could have taken such a long time, read on for a little bit of Drupal history! (By no means a complete history.)

2007 and Drupal five

Twelve years ago, in Dries’ State of Drupal talk , Better media handling was deemed super important. I attended a session about it — this is the (verbatim) session description:

  • Drupal’s core features for file management and media handling
  • common problems and requirements (restrictions, performance issues, multi-lingual content, dependencies between nodes and files)
  • first approaches: own node types for managing, improved filemananger.module (example: Bloomstreet,European Resistance Archive, Director’s Cut Commercials)
  • next step: generic media management module with pluggable media types, mutli server infrastructure, different protocols, file systems, file encoding/transcoding

It’s surprisingly relevant today.

By the way, you can still look at the session’s slides or even watch it!

2007–2013 (?)

The era of the venerable Media module, from which many lessons were learned, but which never quite reached the required level of usability for inclusion in Drupal core.

2013 (?) – 2019

The Media initiative started around 2013 (I think?), with the Media entity module as the first area of focus. After years of monumental work by many hundreds of Drupal contributors (yes, really!), only one missing puzzle piece was left: WYSIWYG embedding of media. The first thing I worked on after joining Acquia was shipping a WYSIWYG editor with Drupal 8.0, so I was asked to take this on.

To help you understand the massive scale of the Media Initiative: this last puzzle piece represents only the last few percent of work!

Drupal has always focused on content modeling and structured content. WYSIWYG embedding of media should not result in blobs of HTML being embedded. So we’re using domain-specific markup (<drupal-media>) to continue to respect structured content principles. The result is document transclusion combined with an assistive “WYSIWYG” editing UX — which we wished for in 2013.

A little less than two months ago, we added the MediaEmbed text filter to Drupal 8.8 (domain-specific markup), then we made those have previews using CKEditor Widgets for assistive “WYSIWYG” editing, followed by media library integration and per-embed metadata overriding (for example overriding alt, as shown in the screencast).

I was responsible for coming up with an architecture that addressed all needs, but it’s phenaproxima, oknate and rainbreaw who got this actually committed to Drupal core!

Complete media management shipped in increments

Fortunately, for many (most?) Drupal 8 sites, this will not require significant rework, only gradual change. Drupal 8.8 will ship with complete media management, but it’ll be the fifth Drupal core release in a little over two years that adds layers of functionality in order to arrive at that complete solution:

  • Drupal 8.4 added foundational Media API support, but still required contributed modules for it to be usable
  • Drupal 8.5 made Media usable out-of-the-box
  • Drupal 8.6 added oEmbed support (enabling YouTube videos for example) and added an experimental Media Library
  • Drupal 8.7 made the Media Library feature-complete: bulk uploads, massively improved UX
  • Drupal 8.8 will contain the key thing that was blocking Media Library from being marked stable (non-experimental): WYSIWYG integration

Today is the perfect moment to start looking into adopting it shortly after Drupal 8.8 ships in December!

Sep 03 2019
Sep 03


Redfin Solutions started using React Native in early June when a client needed an app that could integrate with their Drupal website. Since it was our first project with React Native, we recorded useful information to share with the rest of the team. This is the first in a series of three blog posts that will cover what we learned and what we found the most useful while using React Native.

Expo & React Native CLI

There are two main framework options for building a React Native app: React Native CLI and Expo.

React Native CLI is the option most people from a native app development background choose because it trades a streamlined workflow for the ability to add native modules written in Java or Objective-C.

Expo is easier for people from a web development background because it provides a streamlined workflow to those who don’t need to link native modules to their app. It comes with integrated libraries, a client app for development, and it doesn’t require the use of Android Studio or XCode to build the project for Android and iOS separately. With a signing key, Expo handles the building process. This speeds up the development process and frees up time to spend on new features for the app.

Components

The React Native design philosophy separates each screen into a hierarchy of components. At the lowest level are simple components like <Text>. Larger components are constructed out of other smaller components. They can also be designed as a specific case of another component. For example, it may be simpler to create a <HelloWorld> component that is a more specific version of the <Text> component if you are repeatedly creating <Text>Hello World!</Text> components. 

Props & State

Every component has two stores of data that contain information about itself, props and state. Props are the parameters of a component. It is primarily set when the component is created. For example, the URL of an image component is passed in when it’s created and stored in props. 

Conversely, state is used to store data that changes. When state changes, the component is re-rendered to show the change. For example, the current value of a volume slider might be stored in state.

JSX

JSX is a syntax extension for JavaScript that comes with React Native. It is a simple way to express how the React Native components should be rendered into elements on the screen. JSX is intuitive because it functions within React Native that same way HTML functions in a webpage. Take a look at this JSX for putting text and an image on a screen:

<View> <Text> Hello World! </Text> <Image source={require('../assets/images/hello.png')} /> </View>

Lifecycle API

Every component follows a lifecycle API. This is a set of methods that React Native calls during certain events in a component’s life. The only required method, besides the constructor of a component, is the render() method, which expresses how to render the component on the screen by returning React elements that are usually defined by JSX. 

Styling

Styling in React Native is similar to CSS. Every component can be styled with a StyleSheet prop, which is a set of CSS-style selectors passed inside of a JavaScript object. They even support Flexbox. For example: 

const styles = StyleSheet.create({ header: { fontWeight: 'bold', fontSize: 30, }, });

And when you want to apply it to a component: <Text style={styles.header}> Hello World! </Text>

To see all the style options available, check out the documentation for each component. 

React Navigation

It is easier to start app designs at navigation by planning out what each screen will contain and how to navigate between them. This top-down approach prevents context switching between screens while writing. 

React Navigation, one of Expo’s integrated libraries, provides tools for creating a navigation system within React Native. Choose the ‘tabs’ option when initializing the project, and Expo will build a simple navigation system.

A StackNavigator is a good way to control screens because it allows them to remain concurrent when swapping between different screens. Each screen will retain its information.

To learn more about technical details check out the React-Navigation Docs.

Building Screens

To create a simple, static screen, you don’t need many moving parts because React Native provides robust components for these already. For example, components like <ScrollView>, <Image>, <Text>, and <Linking> can do most of the lifting on a page that only has to display information and images. A simple screen might look like this:

import React from 'react'; import { ScrollView, StyleSheet } from 'react-native'; export default function HamsterScreen() { return ( <ScrollView style={styles.container}> <Text> Your mother is a hamster! </Text> <Image source={require('../assets/images/hamster.png')} /> </ScrollView> ); } HamsterScreen.navigationOptions = { title: 'Hamster', }; const styles = StyleSheet.create({ container: { flex: 1, paddingTop: 15, backgroundColor: '#fff', }, });

This is just the beginning of learning how to use React Native. Keep an eye out for our upcoming blog post about using React Native with Drupal. In the mean time, watch Designing an App with Drupal and React Native, a Design 4 Drupal session presented by our summer intern developer, Jacob Morin.

Sep 03 2019
Sep 03

Our lead community developer, Alona Oneill, has been sitting in on the latest Drupal Core Initiative meetings and putting together meeting recaps outlining key talking points from each discussion. This article breaks down highlights from meetings this past week.

You'll find that the meetings, while also providing updates of completed tasks, are also conversations looking for community member involvement. There are many moving pieces as things are getting ramped up for Drupal 9, so if you see something you think you can provide assistance on, we encourage you to get involved.

Out of the Box Initiative Meeting

August 27, 2019

Mark Conroy (markconroy) and Ofer Shaal (shaal) talked about:

Drupal Getting Involved Guide Refresh Meeting

August 27, 2019

This meeting:

  • Usually happens on alternate Tuesdays.
  • Is text only!
  • Happens in threads, which you can follow to be notified of new replies even if you don’t comment in the thread. You may also join the meeting later and participate asynchronously!
  • Has a public agenda issue anyone can add to: Meeting - Getting Involved Guide - 27 August 2019
  • Meeting transcripts are still a work in progress, but please comment on the meeting agenda issue so we can grant you credit for attending/contributing!

During the meeting, the following topics were discussed:

Personas

We have consensus on Personas! The issue, Consensus on contribution personas, tracks all of the progress. We need to store those personas as they are in somewhere we can easily reference.

Writing Style Toolset

Loving that we know the styles are already agreed in issue Evaluate, pick, and configure checking/linting tools for the Getting Involved Guide. The toolset is making great progress so far.

Proposed outline 

The outline needs a review - how do we make it attractive and welcoming to new potential contributors? Find documentation and progress updates in the issue Proposed Outline for the Getting involved Guide.

Community Section

Admin UI Meeting 

August 28, 2019

  • Meetings are for core and contributed project developers as well as people who have integrations and services related to core. 
  • Usually happens every other Wednesday at 2:30pm UTC.
  • Is done over chat.
  • Happens in threads, which you can follow to be notified of new replies even if you don’t comment in the thread. You may also join the meeting later and participate asynchronously!
  • There are roughly 5-10 minutes between topics for those who are multitasking to follow along.

Beta & Stable Blockers Revision

  • Field cardinality can be unpostponed after table drags has been finished.
  • Cards issue is blocked by action links so that could use some help.
  • Image and file fields are blocked by design work.
  • Status report page is blocked on design unless we go with the existing one for beta.
  • Probably Media designs won’t be on time, so probably the Media should be moved to stable.
  • We need some help with accessibility revisions.

Layout Redesign: Max-width Limit

We opened this issue for Layout Redesign after facing some problems with Card Style Updates with wide screens.

Customizable Settings

Looking to determine what we would like to have as customizable options. The discussion is started in the issue Provide form for customizable settings.

Sep 03 2019
Sep 03

Often corporate design is focused on logos, fonts, colors and content, but predefined interaction components such as buttons, cards, accordions, sliders, shopping carts, etc., are missing.

In many cases such organizations are missing methodologies and tooling to create a complete corporate design, to make it available to the whole organization, and to maintain it. With maintaining I refer to extending, updating, or changing the design, as well as rolling these changes out.

Design systems to the rescue

A design system is a methodology to build corporate design and break it down into components. Each of these components are named and have a clear definition of how they are to be used.

Typically a design system is comprised of two elements: a design language and an online system to make the components available, including their styles and template source codes.

When creating a design system all stakeholders must work together and agree on the outcome. Stakeholders usually include designers, marketeers, frontend developers, managers, and all other people who create or work with the corporate design.

All stakeholders agree on the naming of the components. This is referred to as creating a design language. They also agree how the components are supposed to be used across all properties. This includes digital properties such as websites, social media profiles, etc., as well as offline properties such as brochures, advertorials, merchandising articles, etc.

Let’s have an example: On a website you typically have overview pages that provide links to landing pages with the actual content. Think of a listing of products or services where the user clicks on the most suitable item. For these items you would typically use an ‘Image Text Card’. Such a card could be assembled by using a ‘Squared Image’, ‘Regular Text’, and a ‘Standard Button’.

Example: ‘Image Text Card’

Example: ‘Image Text Card’

As can be seen above, the design language that all stakeholders have agreed on contains:

  • ‘Image Text Card’,     
  • ‘Squared Image’,     
  • ‘Regular Text’, and     
  • ‘Standard Button’.

This methodology would be used for all aspects of the corporate design.

It is good practice to start with the smallest possible components such as colors, texts, headings, and images. Each must be named and have a clear definition of how it is used. Colors could be named as ‘Primary Color’, ‘Secondary Color’, ‘Danger Color’, etc. Fonts could be named as ‘Regular Text’, ‘Summary Text’, ‘Cited text’, ‘Eyebrow Text’, ‘Link Text’ etc. Headings would typically be organized as ‘1st Level Heading’, ‘2nd Level Heading’, ‘3rd Level Heading’, etc. Images would be organized as ‘Squared Image’, ‘Hero Image’, ‘Banner Image‘, Portrait Image’, etc. Starting with the smallest possible components is also referred to as Atomic Design, any my colleague Jule wrote about this here.
 

Headlines, colors, image formats

Headlines, colors, image formats

Components, as in the examples above, are then used, when the layout for a new page type is created, let’s say for a news article. Such an article typically consists of a ‘1st Level Heading’, a ‘Hero image’, an ‘Eyebrow text’, a ‘Summary Texts’, and ‘Regular Text’ combined with ‘Cited text’ and ‘Link Text’.

Example: ‘News Article’

Example: ‘News Article’

When working with a design system methodology an important aspect is having a concise design language. If all your components have sensible names it is easy for the stakeholders of the design system to communicate.

You could for example ask the designer to change the ‘Regular Button’ on the ‘Text Image Card’ to an ‘Icon Button’.

Example: ‘Regular Button’ and ‘Icon Button’ on ‘Image Text Card’
 

Example: ‘Regular Button’ and ‘Icon Button’ on ‘Image Text Card’

Making design systems available

A design system is typically made available with a web based application, that allows easy navigation of all components simulating different use cases.

Also such software makes templates available, that can be used by other software to use the components of the design system.

Popular examples of design systems are

At 1xINTERNET we use Pattern Lab for creating an online design systems. We primarily develop with Drupal and React and have built our own set of tooling for creating decoupled frontends. As a starting point we have used the well established Particle theme.

The design patterns are made available as templates that can be integrated in other software. Hereby, the design system would typically supply the templates in the programming language needed by the different systems.

Working like this allows us to completely separate frontend development from the development of the actual websites. Once the frontend is ready and all components are made available with as templates, they are used by all websites.

With this approach the highest possible re-usability of frontend is achieved, and after initial creation cost, the development time of new websites can be significantly reduced.

A nice demo is provided by Patternlab.

How do you handle different designs?

Often large organizations have different designs. Sometimes they have different brands, or the same brand is used differently for varying audiences. Such audiences could be students, adults, or pensioners, who are best reached with different communication.

Different designs could be different logos, fonts, colors, etc. But they could also include completely different interaction components like fancy sliders, or traditional accordions.

Depending on the use case such designs could be integrated into the standard design system. The number of available sliders could be increased, and it could be agreed that usage of certain sliders is only allowed for certain use cases.

Alternatively, a variant of the design system could be created. Here fonts and colors could be changed, the majority of components could be integrated from the main design system could be used, some components could be excluded, and other components could be added.

Example: Alternative design for headlines, colors, and image formats

Example: Alternative design for headlines, colors, and image formats

Example: Application of alternative design to different ‘Image Text Cards’

Example: Application of alternative design to different ‘Image Text Cards’

The application of different designs in web projects works the same and with one design system.

Testing component based designs

An important aspect of component based designs, is that they can easily be tested.

All components of a system are developed for different screen resolutions, work for touch- and non-touch screens, are optimized for accessibility, and are optimized for the best possible user experience.

In such a system all components can be tested individually with a variety of testing tools. We always use Visual Regression testing during quality assurance, to analyze what components are affected by the changes.

Screenshot: Visual regression testing of different patterns

Example: Application of alternative design to different ‘Image Text Cards’

How to share design systems across implementation teams

Given that you have created a design system and made it available for users to work with it, the question arises, how this is actually done.

Imagine a scenario in which you have a standardized CMS technology such as Drupal in your organization. Frontend in Drupal is created with so-called Twig templates. Twig is a flexible templating engine for PHP.

These templates can simply be included in your CMS. Technically speaking, the CMS would include the Twig templates from the design system and parametrize these with the content generated by the CMS.

Code snippet: Include another Twig template in Twig

Code snippet: Include another Twig template in Twig

Staying within the example above for generating a news article, the CMS would call the template for ‘1st Level Headline’ to display the headline, the template for ‘Hero Image’ to display the image, etc.

A good way to integrate your design system into a website project is to make it available as a regular source code dependency. That way when all dependencies of the website are updated, the design system is also updated, and the newer version is automatically included in the next version of your website. This is especially useful to automatically roll out extensions, updates, or changes of your design system to all websites.

Let’s have an example. Say, you discover that the component ‘Cited Text’ does not comply with WCAG 2.1. standards for web accessibility, the design team is asked to provide an updated visual design. Then the frontend developers update the component with new styles and supply a new template. Once the new design system is tested a new version is created. As soon as the websites using ‘Cited Text’ are updated, the new version of cited text is rolled out.

When to use Patternlab

We primarily use Drupal and React for building websites. The technology we use for creating design systems is Patternlab (see above).

For both we provide templates. For Drupal we provide Twig templates, for React we provide JSX templates for the different React components.

Patternlab can be extended to also ship other types of templates (Angular, Vue, etc.). The question of whether Patternlab should be used to build up a design system depends on the technology being used in the website projects.

For building standalone JS based applications Storybook is a great tool for developing UI components. 

Sep 03 2019
Sep 03

I have spent my two previous blog posts exploring how requesting an appointment online begins a patient's digital journey and how top US hospitals approach online appointment request forms. Now, I would like to make some recommendations and strategies for building an exemplary appointment request form and follow it with an explanation on to how these recommendations are being applied to the Webform module's "Request a Medical Appointment" form template.

Strategies

Creating an exemplary appointment request form is an iterative process that requires experimentation and testing with analytics to determine which solutions work and which ones don't.

There are many different levels of statistics that can be captured from a form.

Completion
The most immediately available statistic is the form's completion rate, which indicates how many people successfully filled out and submitted the form. Subtracting the completing rate from how many users visit the form provides a general sense of the form drop-off rate. What is missing from these statistics is more nuanced information about the form's drop-off rate that can give a better understanding of the form's user experience.

Events

Tracking a form's events shows which inputs were filled in and in what sequence they were entered. This detailed information helps to determine how a user is interacting with a form. Furthermore, knowing where users drop off from completing a form can help indicate which questions may need to be removed or reworked.

Analytics provides the digital team with insights that lead to experimentation and testing.

A good iterative process should always including testing, which makes sure that changes and improvements are successful.

A/B

Forms built using an iterative process typically have some current version of the form where inputs or labeling could be improved. The best way to confirm that an improvement or experiment is successful is to perform an A/B test where the original and improved variant is randomly presented to end-users, and each variant's success rate is tracked and then compared.

User

At some point, the best way to get direct and helpful feedback about an appointment request form is to ask users their opinion. User testing an appointment request form is tricky because you risk inconveniencing potential patients. Large healthcare institutions should consider doing professional usability testing with real patients who volunteer and are compensated for their participation. Seeing and hearing a user's frustrations with an appointment request results in inspiring a digital team to care more about the patient's experience.

Personally, my experience watching user testing made me realize that the most important thing that needs to happen on an appointment request form is that a patient is able to book an appointment, even if it requires them to make a phone call. Always include a phone number on an appointment request form.

On a related note, witnessing and understanding how users with disabilities navigate a website, inspires everyone to care about accessibility.

Recommendations

There are a lot of resources about form design and usability that provide general form recommendations. The goal here is to highlight common suggestions and recommendations explicitly applicable to appointment request forms.

Navigation

Easy

Make it easy for users to find the appointment request form. Appointment request forms should be accessible within three clicks from a hospital's homepage.
 

Directions

Create landing pages that route users to the correct appointment request form. Landing pages can route domestic and international patients to the proper form and direct referring physicians to doctor portals.

Information

Expectations

Set expectations by indicating how long and what type of response is expected. For example, will patients receive a confirmation email with a callback within 24 hours?

Grouping

Group related inputs by type of information. Common groupings for appointment request forms include contact, patient, diagnosis, and insurance information.

Explanations

Explain why specific healthcare information is needed. Tell users why providing insurance, referring physicians, and diagnoses will help when booking an appointment.

Relevance

Only collect the relevant information required to complete the immediate task of booking an appointment. Scrutinize each input and question and ask is this information needed.

Experience

Layout
Make sure the layout inputs are easy to understand and complete. Top aligned labels are the recommended approach for mobile and desktop forms.

Conditionals

Use conditional logic to ask simple yes/no questions which then ask for more specific answers. For example, asking who is filling out the form should be one of the first questions on all appointment request forms.

Indicator

Clearly indicate what inputs are required or optional. If most of a form's inputs are needed, it may be more appropriate to note which inputs are optional.

Ordering
Required elements should come before optional elements. Placing the required inputs first makes it easier for patients to skip optional inputs.

Accessibility
Make sure users with disabilities can complete the form. Forms should fully accessible to screen readers and keyboard navigation.

The Webform module's templates are intended to provide a starting point. Site builders and architects can customize the suggested elements and information for their specific business requirements.

Request a Medical Appointment Template

Request a Medical Appointment Template

Please note: The new 'Request a Medical Appointment' template is only available to new installations of the Webform module using the latest release of Webform 8.x-5.4+. Otherwise, you can manually install the webform.webform.template_medical_appointment.yml via Drupal's Configuration Management UI (/admin/config/development/configuration/single/import) or API.

Accessibility

Accessibility should not be an after-thought. Appointment requests need to be easy to understand and complete for all users.

JavaScript

For mission-critical forms, it is best to avoid any unnecessary JavaScript enhancements or behaviors that can cause accessibility issues. This is why the appointment request template avoids using Select2 to enhance select menus. There is a fascinating related discussion happening on Drupal.org about improving the usability and accessibility of long select lists. Ben Mullins (bnjmnm) is doing a fantastic accessibility audit of several of the available select menu enhancement libraries.

Indicators

Forms should show an explanation of required (*) fields, so I decided to display the 'Indicates required field" message at the top of the form.

Browser

The appointment request form is configured to display a native browser warning message when a user navigates away from a form with unsaved changes. Because the warning is generated from the web browser and not custom JavaScript, screen readers and other devices for people with disabilities should adequately handle this behavior. For example, Gmail also uses this functionality when a user is about to lose unsaved changes.

Information

The goal of the appointment request is to collect patient and caregiver information. Therefore, it is key to ask for this information directly and make it clear what information is required to complete the form.

For example, the caregiver and patient contact information inputs ask for the same type of information. This makes it easy for an end-user reviewing the form to know that they need the caregiver's or patient's first name, last name, phone, and email.

Labels

This appointment request form tries to keep the labeling as simple as possible. Because the form targets patients and caregivers, it is challenging to create generic labeling that addresses both audiences. In the past, I have written custom JavaScript, which conditionally changes form element labels and descriptions based on the audience. For example, a caregiver would see 'Patient First Name' and a patient would see 'Your First Name.' This approach becomes unmanageable. There are no form builders on the market that support conditional form element labels and description. Conditional form element labels and descriptions would be a tremendous and challenging feature for the Webform module to explore.

Required

Required elements always come first. Besides indicating which elements are required, all the medical information is denoted as (optional) because a care specialist can also collect this information during the appointment scheduling phone calls.

Phone

For phone numbers, I nudge the user to enter the phone number using the standard US format (XXX) XXX-XXXX. Still, we don't need to require users to enter this format. Once again, I avoid using a JavaScript enhancement, like a phone number input mask. Input masks create an accessibility issue for screen readers because the (__)-___-____ is read aloud as "opening parenthesis, underscore, underscore, underscore, closing parenthesis, dash, etc."

Confirmation

The appointment request template displays a straightforward confirmation page and deliberately does not send a confirmation email to the end-user. Sending insecure emails to a patient can be considered a Health Insurance Portability and Accountability Act (HIPAA) violation. Generally, it is recommended to use secure messaging communicate with the patient or caregiver.

Buttons

Drupal and the Webform modules provide a responsive user experience out-of-box. Radios can be challenging to use on a small screen, so I decided to enhance the radios so that they would visual appear and behave like buttons.

In the Webform module, there is a dedicated buttons element that uses jQuery UI Buttons. I opted to use a recent enhancement to radios which makes it possible to style radios as buttons without using jQuery UI.

Layout

Even though single-column forms are more comfortable to complete, allowing some elements to be laid out in two columns makes it possible for someone to see the entire form and, in turn, realize that is is very easy to fill out.

Theming

Drupal's Bartik theme provides a good starting point for a form's visual design. I do find the default table element, used for the phone preferences, to be a little bit visually heavy. Phone preferences are optional and therefore should not be the most visually appealing element on the page. BTW, another reason I chose buttons for the first question, 'Who are you?", was to further draw a user's eye to this question, which is inside a container with a light gray background.

Results

The saving of results is disabled to prevent protected healthcare information (PHI) from being stored in Drupal. The appointment request template sends a confirmation and notification email. In a production environment submissions should be remotely posted to CRM or database.

Widgets

The simpler a form is to fill out, the more likely end-users will complete it. At the same time, it is important to capture the most accurate information. Since an appointment request form results in a phone call back, it is beneficial to know the best time to call a prospective patient or caregiver. I decided to experiment with adding a custom composite element allowing users to enter the best days and times to receive a callback. This widget adds complexity to the form, which is why it is optional. To further reduce this widget's complexity, I removed the adding, removing, and sorting of the days and times.

Honestly, we don't know if the enhancement is useful. If we track all the requests, we can look at how many people provide this information and how many days/times they are providing. A more direct approach is to perform usability testing that would allow us to watch end-users fill-out and submit the form.

There is always room for improvement. I hope my suggestions and tips inspired you to take a second look at your existing webforms and think differently when building new webforms. Building webforms is an iterative process and we should always welcome feedback.

I welcome any feedback to help me improve the webform's 'Request a Medical Appointment' template. Thanks for taking the time with me to research, review, and explore building an exemplary appointment request form.

Almost done…

We just sent you an email. Please click the link in the email to confirm your subscription!

OK

Sep 03 2019
Sep 03

Debugging is not something us developers look forward to. Developer detest bugs but to be able to build a fine quality software, debugging is an indispensable part of a developer’s life. Every PHP developer has a different style and go-to methods for debugging their code. This depends on their experience, their problem-solving approach and most importantly - the amount of time they have in hand! 

How important is debugging and why do you need to debug your code? 

Debugging is an integral part of a software development life cycle that assures quality results. 
Picture this - The codebase is big, You are new to the project, You do not have much details of the project/functionality. But you are supposed to fix a bug. Where do we start from? We start by analyzing the code step by step to understand what is done and where things are going wrong. That, my friends, is Debugging. Debugging is an art that can get better with practice and experience.

How to debug your PHP code

Okay so here is a case that I have come across in my development career. There is a commerce site built on Wordpress in which the checkout process was taking around 5-8 minutes and I was asked to solve it. In this case, I don’t have much knowledge on how things work with Wordpress. So I started with checking off the options from the list one by one such as, (a) Is it because of some plugin? (b) Is it Theme related? (c) Is it any custom code base? etc. 

The tool that helped me in php debugging and solving this case is Blackfire. This gives you a more user-readable option of the stack trace of all the functions, the time taken for each function in the whole process. By using this, I found the function that is eating up the checkout process. All you need is some setup to add the key to your code base and you are all set to analyse any functionality using the documentation.  
So, you can solve the bugs if you have knowledge on multiple methods of php debugging.

Code Debugging Techniques

Let me talk about a few techniques that I have used for debugging PHP.
A simple and most common way to check if the function or the method you have written is being called up, write an exit. There wouldn’t be any developer who hasn’t used this!
To check the value of some variable, print_r(), var_dump(), var_export(). Okay, let’s see the difference.

Example:

Assume an array 
$a = array( 1, array( "a", "b") );

print_r($a);
Array
(
    [0] => 1
    [1] => Array
        (
            [0] => 'a'
            [1] => 'b'
        )
)
 
Array
(
    [0] => 1
    [1] => Array
        (
            [0] => 'a'
            [1] => 'b'
        )
)

This gives a human-readable format and information about the variable. Also, we can store it to a variable with print_r($var, true).

var_dump( $a );
array(3) {
  [0]=>
  int(1)
  [1]=>
  array(2) {
    [0]=>
    string(1) "a"
    [1]=>
    string(1) "b"
  }
}

This prints along with type, length of each value. And this is faster comparatively to print_r()
 var_export( $a );

array (
  0 => 1,
  1 => 
  array (
    0 => 'a',
    1 => 'b',
  ),
)
 

This prints along with type, length of each value. And this is faster comparatively to print_r()
 

var_export( $a );

This returns valid php, if variable exists, else returns false. Which means, the output of var_export can be used directly in a php file.

Have you ever made use of debug($var, NULL, TRUE) provided by Drupal core? This uses print_r() or var_export based on the arguments passed to the php debug function.

What about the warnings like below, which you don’t have a clue on which line of code is causing such a warning.

warning: Invalid argument supplied for foreach() in /modules/node/node.module on line 485.

We know that there are so many places that the node module will be called. So, how do you resolve this? One faster way without using any other external resources is using PHP function debug_backtrace(). Go to “drupal_set_message”, because you know, this is the method that is printing the warning. Put the below line, in that function

debug_backtrace();

Output:

Array
(
    [0] => Array
        (
            [file] => /includes/common.inc
            [line] => 552
            [function] => drupal_set_message
            [args] => Array
                (
                    [0] => warning: Invalid argument
supplied for foreach() in /modules/node/node.module on line 504.
                    [1] => error
                )

        )

    [1] => Array
        (
            [file] => /modules/node/node.module
            [line] => 504
            [function] => error_handler
            [args] => Array
                (
                    [0] => 2
                    [1] => Invalid argument supplied for foreach()
                    [2] => /modules/node/node.module
                    [3] => 504
                    [4] => Array
                        (
                            [param] => 
                            [revision] => 
                            [reset] => 
                            ...
                        )

                )

        )

    [2] => Array
        (
            [file] => /sites/all/modules/custom/custom_module/
custom_module.module
            [line] => 10
            [function] => node_load
            [args] => Array
                (
                    [0] => 
                )

        )

    [3] => Array
        (
            [file] => /includes/form.inc
            [line] => 365
            [function] => custom_module_form_alter
            [args] => Array
                (
                ...
 

This function shows the stack of all the functions that are called in the process of causing the warning. Make sure you restrict the limit, otherwise PHP shows a “memory exhausted” message if the stack takes too long to be displayed.

Debugging through CLI:

Heard of phpdbg! Yes, there is a php extension that is available from PHP 5.6+ which is used to debug a php file from command line.
Open you terminal, enter “phpdbg”. This starts  an interactive php debugger shell. You can also use breakpoints! Just try it out - the hidden way of debugging PHP. 
The only problem is: you will have to get used to the commands of phpdbg to make better use of it.

Debugging through Drupal:

Devel Kint:

Drupal developers use this pretty often. Kint is a submodule of the Devel module that can be used to debug Drupal 8 twig templates together with dump(); 

DB Log: 

Who is not aware of this Drupal module?! In D7 it is watchdog() and D8 it is logger service.

\Drupal::logger('my_module')->debug($message);

But the only reason why we don’t encourage the use of this module even though we are in love with this is that the log message is written into the database every time!

And imagine if it is a huge database, this would be even worse and will affect the performance. That’s the reason, it is not recommended to use DBLOG module on Production sites.


Do you still want to use DBLog, module and reduce the performance impacts? There is a solution for that as well - DBlog Filter. This is a contributed module which helps in restricting the type of logs to be written into the database. For example, if you want to store only logs of severity “error”, you can configure them with this module. So you don’t have to completely get rid of Dblog module. Oh yes, and this module is contributed by me ;) 

Web profiler

Web profiler is a contributed module provided by Devel again. Once you have the module enabled, you will see a report at the bottom of the window. Whenever a page is loaded, this report gives us the page load time, number of queries running in the page, number of forms, number of js/css files, etc. in that page.

web profiler

Yes, This even offers details of each section by clicking on them. For example, the following image shows the queries in the home page.

Xdebug

XDebug - Debugging through IDE:

The best and more user-friendly way of debugging most of the people prefer if they are using an IDE for coding is using XDebug. XDebug is a PHP extension that helps in the development and debugging and provides a single step debugger that you can use with an IDE like PHPStorm. Of course to get the best results, you have to put more effort to install and configure the extension with the IDE you are using.

Sep 03 2019
Sep 03

The ADCI team keeps the tradition of organizing Drupal Cafe. It’s a great opportunity for networking, learning new information and improving competence. Drupal Cafe celebrated its round anniversary! We organized the 20th event, where we kept sticking to our high standards of sessions' quality.  

5 speakers told us about:

  1. Data science. The influence of mathematical, philosophical phycological problems during constructing Artificial Intelligence models.

  2. Drupal components. How a component approach to front-end developing helps to improve relationships between front- and back-end developers.

  3. React/Redux apps unit tests - effective approaches and cases.

  4. How to solve the tasks that suck: tips which help to save work time and be effective.

  5. How not to burn out. How to keep a healthy attitude to the work and refill your resources.

Many Q&A after each lection tell us about what smart and engaged audiences attend our events.

Sep 03 2019
Sep 03

Drupal 

The Drupal CMS is one of the most secure CMSs.

Advantage: the Drupal security team constantly tests the performance of new modules and helps developers to fix errors in the code.

Note: Drupal is used to host government websites such as a website of the Prime Minister of Canada or a website of the French government.

System update

Wordpress

A WP system update can be done in a few clicks from the WordPress control panels. 

Advantage: the massive WP community will help to resolve any issue.

Drupal 

An update of this system can be difficult if you are not a website developer. 

Note: You will not be able to update Drupal from the user interface, you will have to find a professional specialist for help.

What kind of websites can be made on each platform

Wordpress

Personal branding websites, websites for freelancers and bloggers, small businesses, consulting services (finance, marketing, advertisement), etc. 

Drupal 

Digital service providers, travel and tourism websites, websites for creative agencies, educational websites and e-learning platforms, governmental websites, news and entertainment websites, healthcare websites.  

Here is a tip! Make sure you know the exact goals of your business website, learn essential information about platforms under consideration, and then make a decision which platform to use.

Conclusion

Drupal is a multifunctional and secure CMS. It is translated into 110 languages ​​and allows you to implement any project you may think of. E-commerce websites, social networks, large corporate sites have been successfully created on Drupal. Drupal was created by professionals for professionals. You can create large projects with a unique set of functions, but you will have to spend time learning or finding a web developer for help. 

If you don’t want to waste time learning, WordPress will be the best choice for building your first website. The WordPress platform is available for users with any level of knowledge. Just find the right combination of plugins, choose a theme and high-quality hosting, then you can create large and customizable websites, but do not forget about security, especially if you plan to create a website for your business.

To learn more about Drupal, we recommend you to read Why you should migrate your site to Drupal

 

Liked the article? Twit @adcisolutions and let us know what you think about this article on Twitter.  

Sep 03 2019
Sep 03

I’ll admit to having watched a few episodes of Marie Kondo’s show on Netflix. She has definitely inspired some of the downsizing my wife and I done over the last few years. I even applied her thought process to my personal website. When I moved it to a new host I thought about how much of the content on it was not sparking joy.  If I didn't really care about stuff did my readers?

This thought process is probably even more valuable for a large business-focused Drupal site than it was for my goofy personal website.

Kondo's six principles for tidying up your house are:

  1. Commit yourself to tidying up.
  2. Imagine your ideal lifestyle.
  3. Finish discarding first.
  4. Tidy by category, not location.
  5. Follow the right order.
  6. Find joy.

Commit yourself to tidying up

This one is pretty obvious. Make a plan or create a schedule with a hard due date for a wide, sweeping content audit. Require every department to provide a list of their content that needs to stay. Question why stuff needs to stay on the site. "Because it's always been there" is not an acceptable answer.

Image your ideal lifestyle

If we substitute website for lifestyle this one starts to be helpful. What websites do you love? How can you apply inspiration from those websites  to your site?

Finish discarding first

This one is important. Migrating content to a new CMS or new website is expensive. Don't pay to move content that doesn't need to be there. Make sure the timeline requires the content audit to be done first, prior to migrating to the new site.

Tidy by category, not location

Don't worry about whether or not press releases deserve a place in the top-level navigation. Worry about whether or not press releases need to be on the site at all. When is the last time somebody other than a Googlebot visited the 2005 press release archive? If regulatory or other pressures force you to keep them around, do they need to actually be on the site? Consider options, such as keeping the last two years of press releases on the site, and drop everything else into a public Dropbox folder.

Then repeat the above process for every other category of content on your site.

Follow the right order

With houses, Kondo recommends clothes, books, papers, miscellany, and finally sentimental items. In our house, we still haven't gotten through eight boxes of loose photos because every time I start, I waste three hours looking at old pictures, without making any decisions. This is why sentimental stuff needs to come last. For your website, maybe you want to follow the 80 / 20 rule. First, clean out 80 percent of the content that gets no action. As you are doing so, be mindful of SEO and any decisions that might undermine strategies for how search engines treat your site. 

Find joy

OK, does any website really spark joy? Well, maybe XKCD does. The annual blog post recapping the company retreat may not spark any real business value, but it may spark a smile when you remember it. That's okay. You can keep those posts.

Finally, remember to greet your website and thank the content that you are removing, like Marie does when she enters a house or determines an old sweater can go.  

Not exactly sure how this relates, but I needed an ending.

If you need help wrangling your content or migrating to a new site, get in touch. We can help!

Sep 02 2019
Sep 02

In previous posts we introduced the concept of defining migrations as configuration entities. These types of migrations can be executed from a user interface provided by the Migrate Tools module. In today’s article, we will present the workflow to import configuration entities and execute migrations from the user interface. Let’s get started.

Important: User interfaces tend to change. In fact, Migrate Tools recently launched a redesign of the user interface. Screenshots and referenced on-screen text might change over time. Some exposed settings might work, but give no feedback indicating a successful outcome. Some forms might only work with specific versions of modules. The goal is to demonstrate what is possible and what are the limitations of doing so. In general, executing migrations from the command line offers a better experience.

Getting the example code

You can get the full code example for today’s example at https://github.com/dinarcon/ud_migrations The module to use is `UD configuration group migration (JSON source)` whose machine name is `ud_migrations_config_group_json_source`.  It comes with three migrations: `udm_config_group_json_source_paragraph`, `udm_config_group_json_source_image`, and  `udm_config_group_json_source_node`. Additionally, the demo module provides the `udm_config_group_json_source` group.

You could install the module as we have done with every other example in the series. Instructions can be found in this article. When the module is installed, you could execute the migrations using Drush commands as explained in this article. But, we are going to use the user interface provided by Migrate Plus instead.

Importing configuration entities from the user interface

The first step is getting the configuration entities into Drupal’s active configuration. One way to do this is by using the "Single item" import from the "Configuration synchronization" interface. It can be found at `/admin/config/development/configuration/single/import`. Four configuration items will be imported in the following order:

  1. The `udm_config_group_json_source` using "Migration Group" as the configuration type.
  2. The `udm_config_group_json_source_image` using "Migration" as the configuration type.
  3. The `udm_config_group_json_source_paragraph` using "Migration" as the configuration type.
  4. The `udm_config_group_json_source_node` using "Migration" as the configuration type.

When importing configuration this way, you need to select the proper "Configuration type" from the dropdown. Otherwise, the system will make its best effort to produce a valid configuration entity from the YAML code you paste in the box. This can happen without a visual indication that you imported the wrong configuration type which can lead to hard to debug errors.

Image removed.

Note: If you do not see the "Migration" and "Migration group" configuration types, you need to enable the Migrate Plus module.

Another thing to pay close attention is changes in formatting when pasting code from a different source. Be it GitHub, your IDE, or an online tutorial, verify that your YAML syntax is valid and whitespaces are preserved. A single extraneous whitespace can break the whole migration. For invalid syntax, the best case scenario is the system rejecting the YAML definition. Otherwise, you might encounter hard to debug errors.

In today’s example, we are going to copy the YAML definitions from GitHub. You can find the source files to copy here. When viewing a file, it is recommended to click the "Raw" button to get the content of the file in plain text. Then, copy and paste the whole file in the designated box of the "Single item" import interface. Make sure to import the four configuration entities in the order listed above using the proper type.

Image removed.

To verify that this worked, you can use the "Single item" export interface located at `/admin/config/development/configuration/single/export`. Select the "Configuration type" and the "Configuration name" for each element that was imported. You might see some extra keys in the export. As long as the ones you manually imported are properly set, you should be good to continue.

Note that we included `uuid` keys in all the example migrations. As explained in this article, that is not required. Drupal would automatically create a `uuid` when the configuration is imported. But defining one simplifies the update process. If you needed to update any of those configurations, you can directly visit the "Single item" import interface and paste the new configuration. Otherwise, you would have to export it first, copy the `uuid` value, and add it to the code to import.

Executing configuration entities from the user interface

With the migration related configuration entities in Drupal’s active configuration, you should be able to execute them from the user interface provided by Migrate Tools. It is available in  "Manage > Structure > Migration" at `/admin/structure/migrate`. You should see the `UD Config Group (JSON source)` that was imported in the previous step.

Image removed.

Note: If you do not see the "Migration" link in "Manage > Structure" interface, you need to enable the Migrate Tools module.

This user interface will list all the migration groups in the system. From there, you can get to the individual migrations. You can even inspect the migration definition from this interface. It is important to note that only migrations defined as configuration entities will appear in this interface. Migrations defined as code will not be listed.

Image removed.

For the `udm_config_group_json_source` group, click the "List migrations" button to display all the migrations in the group. Next, click the "Execute" button on the `udm_config_group_json_source_image` migration. Then, make sure "Import" is selected as the operation and click the "Execute" button. Drupal will perform the import operation for the image migration. A success status message will appear if things work as expected. You can also verify that images where imported by visiting the files listing page at `/admin/content/files`.

Repeat the same process for the `udm_config_group_json_source_paragraph` and `udm_config_group_json_source_node`migrations. The final result will be similar to the one from the JSON source example. For import operations, the system will check for migration dependencies and execute them advance if defined. That means that in this example, you could run the import operation directly on the node migration. Drupal will automatically execute the images and paragraphs migrations. Note that migration dependencies are only executed automatically for import operations. Dependent migrations will not be rolled back automatically if the main migration is rolled back individually.

This example includes a paragraph migrations. As explained in this article, if you rollback the node migration, any paragraph associated with the nodes will be deleted. The Migrate API will not be aware of this. To fix the issue and recover the paragraphs, you need to rollback the paragraph migration as well. Then you re-import the paragraph and node migrations again. Doing this from the user interface involves more manual steps compared to running a single Drush command in the terminal.

Limitations of the user interface

Although you can import and execute migrations from the user interface, this workflow comes with many limitations.The following is a list of some of the things that you should consider:

  • Updating configuration in production environments is not recommended. This can be enforced using the Configuration Read-only mode module.
  • If the imported configuration entity did not contain a `uuid`, you need to export that configuration to get the auto generated value. This should be used in subsequent configuration import operations if updates to the YAML definition files are needed. Otherwise, you will get an error like "An entity with this machine name already exists but the import did not specify a UUID."
  • The following operations to not provide any user interface feedback if they succeeded: "Rollback", "Stop", and "Reset". See this issue for more context.
  • As of this writing, most operations for CSV sources fail if using the 8.x-3.x branch of the Migrate Source CSV module. See this issue for more context.
  • As of this writing, the user interface for renaming columns in CSV sources produces a fatal error if using the 8.x-3.x branch of the Migrate Source CSV module. See this issue for more context.
  • As of this writing, it is not possible to execute all migrations in a group from the user interface in one operation. See this issue for more context.
  • The Migrate source UI module can be used to upload a file to be used as source in CSV migrations. As of this writing, a similar feature for JSON and XML files is not working. See this issue for more context.

To reiterate, it is not recommended to use the user interface to add configuration related to migrations and execute them. The extra layer of abstractions can make it harder to debug problems with migrations if they arise. If possible, execute your migrations using the commands provided by Migrate Tools. Finally, it is recommended to read this article to learn more about the difference between managing migrations as code or configuration.

What did you learn in today’s blog post? Did you know you can import migration related configuration entities from the user interface? Did you know that Migrate Tools provides a user interface for running migrations? Share your answers in the comments. Also, I would be grateful if you shared this blog post with others.

This blog post series, cross-posted at UnderstandDrupal.com as well as here on Agaric.coop, is made possible thanks to these generous sponsors. Contact Understand Drupal if your organization would like to support this documentation project, whether it is the migration series or other topics.

Sep 02 2019
Sep 02

The Drupal 8 Allowed Formats module allows you to configure what text formats are available for each field. By default, all the text formats a user has permission to use are available for every field that uses text formats. Sometimes you want a field to have html, but have a more limited set of html tags. This can easily be accomplished by creating a new text format and using the Allowed Formats module to limit the field to using that text format.

Download the Drupal 8 Allowed Formats module.

composer require drupal/allowed_formats

Install the Drupal 8 Allowed Formats module.

Go to Admin > Structure > Content Types and select Manage Fields. If you edit the Body field you will see an Allowed formats section that allows you to specify what formats you can use on this

Allowed formats checkboxes

This means you could easily create a new field on a content type and set it to only allow the Restricted HTML text format. You could also create a new text format that could be used on specific text fields.

Sep 02 2019
Sep 02

Drupal 8.7.7 expected later this week is the first Drupal release to support extensions compatible with multiple major versions of Drupal. This is huge!

Drupal 9 is planned for June 3, 2020 and we are aiming to make the transition as smooth as possible. In fact we build Drupal 9 in Drupal 8 with API deprecations and optional support for new dependencies (Symfony 4.4 is getting very close, while Drupal 8.7.0 was already Twig 2 compatible). Extensions following these deprecations and making sure they are compatible with the updated dependencies could have codebases that are both compatible with Drupal 8 and 9 at the same time, meaning less support burden and earlier Drupal 9 compatibility. In March 48% of contributed projects on Drupal.org were already "Drupal 9 compatible" (as we could detect at the time), and that increased 54% by July (highfive!). These projects will now have one more thing to do, a one line info.yml file addition, to allow their existing codebase to also run on Drupal 9.

✋Drupal contrib maintainers, thank you! You are already contributing a lot to a successful Drupal 9. Projects that are "compatible with Drupal 9" (as much as we know now) are up to 54% from 48% since March. Deprecated API use is decreasing overall.

You are awesome, keep it up! pic.twitter.com/mHpw4ET0P4

— Gábor Hojtsy (@gaborhojtsy) August 2, 2019

The core: 8.x key did not cut it anymore

Drupal 8 looks at extension .info.yml files and checks for the core: 8.x key to check if the extension can be used with Drupal 8. Unfortunately this was not adequate already due to API additions in Drupal 8 minor releases. You could not specify an extension was only compatible with Drupal 8.4+. People devised clever tricks with dependency on certain versions of the system module, but that was still limiting due to inability to depend on specific patch releases. In case your extension depended on a bugfix being present, you cannot set a dependency on Drupal 8.4.1+ in any way.

Introducing the core_version_requirement key

While solving this issue it became apparent that solving it with the existing core: 8.x key is going to cause backwards compatibility problems with existing Drupal 8 sites. The format of the value could not be changed without causing issues, so a new core_version_requirement key was introduced. This now allows to depend on major and minor versions of core as well as specify multiple version requirements even between multiple minor Drupal versions. For example if you would need a bugfix that is to be included in both Drupal 8.7.23 and 8.8.3 (imaginary future versions) but you wouldn't care for the minor version, then you would use the following, making your module incompatible with versions before the particular bugfix you need on both minor branches, as well as incompatible with all older Drupal 8 branches:

name: My Module
type: module
core_version_requirement: ~8.7.23 || ~8.8.3

Such precision was never possible before!

The new feature is made available in 8.7.7 to help prepare for Drupal 9, as this makes it possible to also declare Drupal 9 compatibility with the existing codebase you already have. Drupal 8.7.x will get security support up until the planned release of Drupal 9 on June 3, 2020. For extensions that only support Drupal 8.7.7 and later you can now exclusively use the core_version_requirement key. If the extension is also Drupal 9 compatible:

name: My Module
type: module
core_version_requirement: ^8.7.7 || ^9

For extensions that also support older versions, you should keep the core: key as well. The core_version_requirement key will be ignored by older Drupal versions, and new versions will validate that you specified non-conflicting requirements in the two keys (with regards to Drupal 8 support) so for extensions supporting older core versions, core_version_requirement also needs to be permissive, but could also allow compatibility with Drupal 9 too:

name: My Module
type: module
core: 8.x
core_version_requirement: ^8 || ^9

Read more about this change in the change notice. There is also work ongoing to support dependency metadata from composer.json to drive Drupal's dependency resolution as well. That will coexist with this simpler approach and will provide a more composer-native solution for those who already adopted composer for their extensions. In the meantime at least core_version_requirement will limit what Drupal would install while composer.json requirements will limit what composer will download. Because both Composer and Drupal use the term install, but those don't mean the same thing, here is a comparison chart:

  core: 8.x system module dependency core_version_requirement composer.json dependencies Can be used from Drupal 8.0.0+ Drupal 8.0.0+ Drupal 8.7.7+ Drupal 8.0.0+ Allows minor version precision No Yes Yes Yes Allows patch version precision No No Yes Yes Allows multiple constraints No No Yes Yes Limits composer install (download) No No No Yes Limits Drupal 8 install Yes Yes Yes No, unless explicit support is added. Allows Drupal 8 and 9 install with same codebase No No Yes No, unless explicit support is added.

What happens to Drupal.org project version numbers then?

So a 8.x-1.3 version of an extension on drupal.org may only be compatible with a subset of core, but that was already the case earlier. Now an 8.x-1.3 version of an extension on drupal.org may also be compatible with Drupal 9. How will this work? Drupal's composer integration already ignores the 8.x prefix from version numbers and only cares about the project specific version. Drupal core already only installs extensions where the core compatibility requirements are met regardless of which version number was the package you used to download (8.x modules may be only compatible with 8.4+ already). So the ultimate plan is to do away with the 8.x prefix in extension numbers entirely on drupal.org and support semantic versions for contributed extensions instead. In the short term, the Drupal.org project browser also needs to be updated to take the dependency metadata and use that to power compatibility filters, instead of merely using the version number prefix.

Sep 02 2019
Sep 02

With a successful API monetization strategy, enterprises can expand their business capabilities to new customers through the rapid consumption of business assets.

However, with APIs offering dozens of ways to monetizing data, content and technology, it can become overwhelming for enterprises to deal with the entire process.

In this blog post, we’ll take you through the technical knowledge needed to build a robust API monetization platform for Globe Telecom, which seamlessly drove new opportunities and broadened their marketplace.

Understanding Globe’s Concerns and Expectations

Globe Telecom, part of the Singtel Group, is a telecommunication giant in the Philippines with an estimated market capitalization of 3.8 billion USD and a subscriber base of almost 67 million.

It has a programme running on Apigee aimed at expanding the ecosystem and effective productization for increasingly complex APIs. Globe was seeking out to create a prototype for API monetization.

We helped them achieved the following key goals:

  • A unified and well-architected API programme to allow Globe to expand into other avenues faster than before
  • An organized API product strategy with an at least 6-18 months outlook, that allows for better-planned release cycles and innovative business models
  • Standardized infrastructure and ops for resilient architecture, platform security, and cost savings
  • Empowered API teams that can work in an efficient and optimized manner and help migrate selected APIs to the Apigee platform.

Read how Srijan helped Globe Telecom drive its API Monetization Strategy

Take Me Through
Building a Developer Portal on Apigee

A platform was built which could help the client to ideate, develop, and take feedback within planned timelines, with the ability to create new revenue models with an offering for both service providers and end-customers while vastly cutting down development time and costs.

Srijan teams built a unified developer portal which made APIs available to developers to communicate with the actual data in microservices through an Apigee API platform.

The Apigee platform ensured secured use of APIs and acted as the intermediate between developers and the microservices.

The Apigee platform ensured secured use of APIs and acted as the intermediate between developers and the microservices.

Architectural diagram showing communication between developers/admin and microservices

Now, let’s understand the features of the project and the various related terminologies.

  • GlobeLabs APIs

The developer portal renders several APIs which can be public, private and internal. These are then implemented on Apigee. The screenshot attached below shows a comprehensive list of Public APIs available to an anonymous end user.

GlobeLabs APIs

Developer portal exposing various APIs for developer use

  • Globe Labs ReDoc

ReDoc offers a customizable and incredibly nice theme. It is actively maintained by its developer team to offer a better user experience. It has a custom script written for better readability of a developer.

Here’s the sample doc rendered for:

1. Request

Request

2. Response

Response

  • GlobeLabs SmartDocs for an API

SmartDocs comes as a part of the Drupal-based Apigee dev portal. It provides smart documentation for an endpoint along with a tryout feature so the developer can tryout the endpoint on the page itself.

GlobeLabs SmartDocs for an API

  • Developer Dashboard

A logged-in developer on the developer portal dashboard can choose to create a new app, go to the apps transactions page or see the wallet balance.

Developer Dashboard

1. Developer App

7-3

Screenshot of creating new app interface

A developer can create an app by giving it a unique name, with a particular API product(s) and a callback URL. He/she can select different API types (which are basically API products on APIGEE which gets synced to dev portal) by simply selecting the check boxes.

In case of Consent App, a 'Consent' is a prompt when a subscriber sees while opening an app. The app accesses the list of permissions marked selected by the subscriber.

2. Developer Wallet

Developer can add balance to their wallet via online/offline transfers. The wallet is categorised into two types: prepaid and postpaid.

A developer can have any wallet (prepaid or postpaid) and can even be switched from one to another upon request. The developer will have SMS MO balance attached (see the image below), show the credit/balance history of the transactions done.

3. Navigate Transaction page

The transaction page displays the transaction types and the related balance details.

8-3

Screenshot of Transaction page interface

Admin Operations

Admin does the configurations to communicate between different layers in the entire system. Micro services implement the automated processes across the system wherever needed.

Micro services consists of all the APIs which does any internal operation in the system, and the response is brought back to APIGEE and then to portal/developer App.

Srijan is working with leading enterprises across the US, Europe and APAC regions, assisting them with their API lifecycle management with Apigee - creating and exposing APIs and building custom developer portals. Contact us to get started with your requirements.

Sep 02 2019
Sep 02

Software solutions come in all shapes and sizes. Perhaps you’re looking for software that will help you build valuable links back to your company. Or maybe, you need a custom CRM to manage all of your valuable patrons. Either way, it’s vital to find a reliable technical partner to make your software solution dreams a reality.

At Vardot, we understand that all web development is not one-size-fits-all. We know exactly how can help your organization transform its website to meet the demands on the digital landscape. Our solutions help increase and refine distinguished companies’ digital presence through Drupal, a powerful open-source CMS.

In acknowledgment of our efforts, we’ve been recognized by Clutch, as one of the top developers in Jordan! We’d like to thank our valued customers for participating in brief client interviews on our behalf. We’ve been awarded a 4.9-star rating (Out of a possible 5 stars). We’re excited to keep this momentum going and maintain ourselves as a top provider in our field! Check out a recent review below!

Clutch Reviews of Vardot

“We are honored and pleased to see our team's innovation and hard work recognized.” – Mohammed Razem - CEO, Vardot.

Clutch is an objective resource for business-to-business services. The platform lauds a unique rating methodology that objectively reviews similar companies. The Manifest’s directory also features us a top Drupal development company. For those unfamiliar, The Manifest is a sister site of Clutch that specializes in business news. Another great resource and Clutch sister site is Visual Objects. Each Visual Objects profile features a catalog of businesses’ visual work.

If you’re interested in learning more about how we can help maximize your Drupal success, drop us a line today!

Sep 02 2019
Sep 02

The first step is to download the Drupal 8 Scheduler module and install it. Downloading the module is easy with composer:

composer require drupal/scheduler

In this example, we are only going to cover the Scheduler module. The module comes with a Scheduler Rules Integration module that can be used to integrate Scheduling conditions, actions, and events with the Drupal 8 rules modules.

Drupal Scheduler Module module page

If you navigate to the User permissions page, you can see there are three permissions for the Scheduler module. Typically, you will allow your content editors to schedule content to be published and possible see the list of all content that is scheduled.

Drupal Scheduler Module permissions page

In the Admin menu, navigate to Configuration > Content authoring > Scheduler to get to the Scheduler settings page. Here you can set it up so a content administrator only has to enter the date and the content will be published at a default time. This is useful if you always want content to be published at the same time of day. For now, leave everything at the default.

Drupal Scheduler Module settings page

Click on the Lightweight cron menu item from the Scheduler settings page. If you are only scheduling content to be published occasionally and don’t care if it’s published at exactly the correct time, then you will not need to worry about this admin page. If you need more fine grained control and would like up to the minute publishing, this page provides useful information.

By default, the scheduler actions happen on the default Drupal cron run. Typically you will set up cron to run every hour or possibly once a day, depending on your site needs. The Scheduler module provides a more lightweight cron process available at a callback URL that only runs the scheduler instead of all the default Drupal cron hooks. This makes it more efficient for up to the minute publishing.

Drupal Scheduler Module lightweight cron page

Navigate to Admin > Structure > Content Types. Select Edit on one of the content types you would like to allow scheduling on. In this example, we will use the Article content type.

Content Type Edit

Click on the Scheduler section. Here you can turn on the ability to publish or unpublish this type of content using the Scheduler module. You can specify that creation time should match the publishing time, require that the content be scheduled, and even make sure a new revision is created when the content is published. You can also change how the scheduler options appear on the node edit page (when creating or editing content). For now, just check to turn on Publishing and to change the content creation time to match the scheduled publish time. Then click the Save content type button.

Drupal Scheduler content type options

Now create a new Article and set the Scheduling date and time. Make sure the Article is unpublished and save it. Once that date and time passes and the Drupal cron process runs, this new Article will now be published! Keep in mind, the date/time is based on your site’s timezone settings.

Drupal Scheduler options

You can go to the Content admin page and click the Scheduled menu tab to view all the scheduled content on your site.

As you can see, it’s incredibly easy to set up and start using the Scheduler module. You should now be able to empower your content editors to schedule their content to be

Aug 31 2019
Aug 31

Make sure to download the Quicklink module using composer.

composer require drupal/quicklink

Enable the module just like you enable any other module.

Head on over to the configuration page at Admin > Configuration > Development > Performance > Quicklink.

In the Prefetch Ignore Settings section, you can configure what Quicklink should not prefetch. You can specify URL patterns on this page that should be ignored.

Quicklink Settings

In the Optional Overrides section, you can configure some various override options such as the parent CSS selector for the prefetch links, the allowed domains, and prefetch paths.

Quicklink Settings

In the When to Load Library section, you can control when QuickLink will be loaded on the page. You can even specify for it not to load on specific content type pages.

Quicklink Settings

The Extended Browser Support section allows you to load the Intersection Observer polyfill which allows quicklink to work in IE11 and some older browsers.

Quicklink Settings

The last section allows you to enable debug mode. For the most part, the defaults work well so leave everything at the default.

Quicklink Settings

To test this out, you will want to make sure you have a webpage with multiple links on it. A blog listing page works well. In my example, I used the Devel Generate module to generate a bunch of Article content to fill up my homepage.

Next make sure you are logged out. I recommend using an incognito or private browsing window. Open up your developer tools and go to the Network tab. Now refresh the page, wait for everything to load and start scrolling. You will notice that the network tab shows additional activity as the links are pre-fetched.

Aug 31 2019
Aug 31

I’ll admit to having watched a few episodes of Marie Kondo’s show on Netflix. She has definitely inspired some of the downsizing my wife and I done over the last few years. I even applied her thought process to my personal website. When I moved it to a new host I thought about how much of the content on it was not sparking joy.  If I didn't really care about stuff did my readers?

This thought process is probably even more valuable for a large business-focused Drupal site than it was for my goofy personal website.

Kondo's six principles for tidying up your house are:

  1. Commit yourself to tidying up.
  2. Imagine your ideal lifestyle.
  3. Finish discarding first.
  4. Tidy by category, not location.
  5. Follow the right order.
  6. Find joy.

Commit yourself to tidying up

This one is pretty obvious. Make a plan or create a schedule with a hard due date for a wide, sweeping content audit. Require every department to provide a list of their content that needs to stay. Question why stuff needs to stay on the site. "Because its always been there" is not an acceptable answer.

Image your ideal lifestyle

If we substitute website for lifestyle this one starts to be helpful. What websites do you love? How can you apply inspiration from those websites  to your site?

Finish discarding first

This one is important. Migrating content to a new CMS or new website is expensive. Don't pay to move content that doesn't need to be there. Make sure the timeline requires the content audit to be done first, prior to migrating to the new site.

Tidy by category, not location

Don't worry about whether or not press releases deserve a place in the top-level navigation. Worry about whether or not press releases need to be on the site at all. When is the last time somebody other than a Googlebot visited the 2005 press release archive? If regulatory or other pressures force you to keep them around, do they need to actually be on the site? Consider options, such as keeping the last two years of press releases on the site, and drop everything else into a public Dropbox folder.

Then repeat the above process for every other category of content on your site.

Follow the right order

With houses, Condo recommends clothes, books, papers, miscellany, and finally sentimental items. In our house, we still haven't got through the eight boxes of loose photos because every time I start, I just waste three hours looking at old pictures, without making any decisions. This is why sentimental stuff needs to come last. For your website maybe you want to follow the 80 / 20 rule. First, clean out 80 percent of the content that gets no action. As you are doing so, be mindful of SEO and any decisions that might undermine strategies for how search engines treat your site. 

Find joy

OK, does any website really spark joy? Well, maybe XKCD does. The annual blog post recapping the company retreat may not spark any real business value, but it may spark a smile when you remember it. That's okay. You can keep those posts.

Finally, remember to greet your website and thank the content that you are removing, like Marie does when she enters a house or determines an old sweater can go.  

I have no idea what that means, but I needed an ending.

If you need help wrangling your content or migrating to a new site, get in touch. We can help!

Aug 30 2019
Aug 30

In this 5-part series, take a deep dive into universal design concepts in the context of creating component-based systems for dynamic web content. Get a birds-eye view of the inner workings of user experience (UX) architecture. Brand strategy, user psychology, objective methodology, and data-driven decisions come together, guided by timeless fundamental ideas, to construct today’s digital journeys.

a dancer mid-split

The Art of Setting Type for Dynamic Systems

It is the typographer’s task to divide up, organize, and interpret this matter in such a way that the reader will have a good chance of finding what is of interest to him.

- Emil Ruder

In the 1950s, Swiss typographer and graphic designer Emil Ruder was involved in developing the International Typographic Style. Cleanliness, objectivity, and the use of “the grid” are key features of this approach which still plays a major role in design today.

In 2006, Oliver Reichenstein said,

Web Design is 95% Typography.

And while faster connection speeds have allowed us to provide more media-rich experiences, text-based information is still vital - and the only thing that devices like Google, Alexa, and assistive technologies for the differently-enabled “see.”

Today, the timeless challenge of how to visually present text-based information is as formidable as it’s ever been. Contemporary design decisions take into account the experiences of billions of potential users, located anywhere in the world, in front of screens of all sizes, with a wide range of backgrounds, situations, and abilities. 

Fortunately, standards such as those for Heuristic Evaluation, the W3C’s Web Content Accessibility Guidelines and user testing tools such as the System Usability Scale and the Single Ease Question have provided an objective structure to inform the creative works of designers today.

Fast, Scalable, Legible Type Styling

Guiding principles for font selection and implementation 

Limit the number of fonts 

In the name of consistency, efficiency, and optimized load times, consider combining two harmonious fonts that create a visual hierarchy. Two is considered an ideal number for fonts. Choose a font with enough members in its family to allow design options, however. A font with light and black versions, as seen on some of Google’s best fonts, will provide a versatile UI toolkit.

Most brand standards contain definitions for print and well as web fonts. In the absence of such standards, a review of mission and vision statements can guide you to a font that reflects the brand identity.

Use a responsive type scale

Responsive modular typography scales, when designed and implemented, are an easy way to preserve visual hierarchy across the various screen widths of devices. A modular type scale is a series of type sizes that relate to each other because they increase by the same ratio. 

Mediacurrent Rain typography example shows Raleway and Merriweather fonts

Example of how responsive typography looks across various breakpoints on Mediacurrent’s Rain demo site.

 

Avoid All Caps for headings and paragraph text

Not only have studies shown text formatted in All Caps decreases reading speed by 10-20%, but this styling presents substantial barriers for users with dyslexia. According to the latest estimates, that is 15-20% of the population.

When headings are less than around 25 characters, all caps is still considered readable for everyone. All caps can also be a valid choice for short navigation titles and concise button copy.

Avoid Italics for headings and paragraph text

A first-time user may spend seconds on your website, not minutes, and as reading speed is dependant on legibility, styling is of paramount importance for all users. In terms of accessibility, italicized letters are nearly illegible to some with reading issues.

Addressing accessibility concerns is a great investment that provides an opportunity to bring in objective best practices to increase usability, readability, and visual impact for all users, opening up your website to a larger audience.

Modern, Readable, Accessible Type Styling 

Guiding principles for line and paragraph spacing

Look to the gold standard for accessibility

Because Section 508 compliance is currently attuned to the A and AA Level WCAG 2.0 guidelines, the AAA Guidelines are sometimes left out of the conversation. The guidelines around line and paragraph spacing, however, are especially easy to incorporate. Because they improve the experience for all users, they are well worth considering. 

a diverse group of people laughing

Avoid justified text

People with certain cognitive disabilities have problems reading text that is both left and right justified. The uneven spacing between words in fully justified text can cause "rivers of white" space to run down the page making reading difficult and in some cases impossible. Text justification can also cause words to be spaced closely together so that it is difficult for them to locate word boundaries.

Implement a maximum width for containers of heading and paragraph text

For people with some reading or vision disabilities, long lines of text can become a significant barrier. They have trouble keeping their place and following the flow of text. Having a narrow block of text makes it easier for them to continue on to the next line in a block. Text blocks must be no wider than 80 characters. 

When determining how to limit the width of a responsive text block, it can be helpful to use a character counting tool. Or try advanced math! The Golden Ratio Typography Calculator generates suggestions for your entire type hierarchy based on the Golden Ratio: a pattern found in nature that is inherently pleasing to the human eye.

Provide ample line spacing for paragraph text

People with some cognitive disabilities find it difficult to track text where the lines are close together. Providing extra space between lines and paragraphs allows them to better track the next line and to recognize when they have reached the end of a paragraph. Provide line spacing that is at least 1.5 (a space and a half) in text blocks and spaces between paragraphs are at least 1.5x line spacing.

In the first post of this series, we discussed the advantages of generously-sized type comfortably line-spaced within a width-restricted column. Not only does this approach align with that of today’s best-in-class websites and provide a comfortable, welcoming reading experience, it is universal design that is accessible and all-inclusive.

Preparing to Reach a Global Audience

Scratching the surface of localization

Designing type for Right To Left (RTL) languages

Arabic is the 4th most popular language globally and 60% of Arabic speakers prefer browsing internet content in Arabic. Aligning text to the right side is key, and so is upsizing the font to preserve text readability. Factoring in the shorter length of words as most Arabic words. Read more about web design for RTL languages.

Dubai.ae screenshot

Example of RTL language typography on dubai.ae.

Accommodating translated text

Character counts expand or contract according to language. Expect a 15 - 30% expansion when translating English to Spanish or Portuguese, for example. When planning to translate English to Chinese or Japanese, however, expect variation. Read more about typography for translated text here.

Planning for character-based languages

Written Japanese, for example, consists of thousands of characters across four character sets: hiragana, katakana, kanji and the Latin alphabet. Japanese users perceive carelessly designed websites as reflective of brand quality. They describe products as “unnatural”, “foreign”, and “suspicious.” The work to get from unnatural to perfect is not hard. Read more about standards for presenting Japanese text on the screen.

Applying and Iterating Type Systems

Continuous improvement based on user feedback

After carefully selecting type styles representative of the brand experience, applying them with accessibility in mind, defining parameters within responsive components, and perhaps including specifications for translated type, what comes next?

We take these specs and build a living style guide to catalog the site’s elements and components. Having the building blocks all in one place not only ensures consistency but allows developers to rapidly adjust or efficiently leverage the existing pieces to create more complex components.

A living style guide makes it easier to add new patterns to meet your needs and the needs of your users that arise as “the rubber hits the road” when content editors begin using the site and feedback is collected from users, ideally through methodical tests.

Technology has evolved rapidly since pioneers like Emil Ruder developed the Swiss style, and is always offering new challenges for designers. But happily, this evolution has allowed us to collect data to objectively guide our practice and to create, share, and continuously improve standards for accessibility and usability, allowing us to meet the challenge of designing with confidence for the global audience. What a great time to be a designer!

In the next installment, we’ll cover pattern libraries/ living style guides in greater detail. We’ll discuss how style libraries ensure a consistent experience and make ongoing enhancements much easier. Learn about the steps it takes to build an emotion-rich, brand-true user journey within the restricted structure of a website built to last for years displaying dynamic, user-entered content.

Aug 30 2019
Aug 30

 

The quantum leap in technology and the ubiquitous demand for delivering personalized content has made it pivotal for companies to embrace the web content management system for all the right reasons. It begins from engaging customers, lead generation, to snowballing overall revenue from various platforms.

However, it can be daunting and tricky sometimes for enterprises to choose the right one as per their requirements on the basis of the varied features and potential that these CMS offers. 

One of the most cited reports by Gartner, Web Content Management Magic Quadrant report, has proclaimed that Acquia Drupal, Adobe Experience Manager, and Sitecore are the three most prominent WCM Managers. 

A square divided into 4 with text and dots insideThese three were at the forefront in Gartner’s report based on the two factors majorly, “ability to execute”, and “completeness of vision”. They undoubtedly outperformed on both these parameters and hence it goes without saying that all three are proficient in fulfilling enterprises’ WCM needs.

However, as one-size does not fit all and there can be multiple parameters for comparing these, it’s better to largely group them into different stakeholder perspectives- the business decision-makers’, the content and marketing teams, and the IT teams. Each of these teams play a vital role in the process. 

Source: Gartner

The content, marketing, and IT team because they’ll be the ones directly working with the CMS they choose. The business decision-makers, CIO, CTO, and the freshly-coined Chief Data Officer (CDO) are the ones who will be held accountable for their choices and showcasing adequate ROI.

This blog will deal with the comparison of AEM and Drupal from the perspective of business decision-makers. Here we’ll primarily focus on factors like cost of implementation, scalability, security, and maintenance to see how Drupal and AEM fare against each other.

Pick What’s Best For Your Organization

Rectangular box with logo and text of Drupal and AEM

Identifying the company’s particular requirement should be the first task on your to-do list. This will only help you out as a decision-maker to draw the conclusion.

Cost of Implementation

"A high price may be a part of its charisma in selling difficult art”, quoted by Robert Genn, a renowned Canadian artist. 

You should get the desired output for the price you pay for a CMS. 

Setting up any large technology solution is always an eye-catching question as it involves the cost associated with it for implementation. Though it is justified as CMS forms a framework for the enterprise technology architecture, and further paves way for digital transformation; the expenditure made on this part is yet always under analysis.

“Being expensive doesn’t make CMS equipped or competent enough for the enterprises”

Furthermore, migrating to new CMS is also a cumbersome task for any enterprise IT team. So, this crucial decision of investing in any particular CMS is made after several rounds of deliberation. And once deployed, organizations become extremely perceptive of acclimating to a change.

The objective behind all such discussions is to get this done right in the very first time & the investment and ROI of any particular enterprise CMS is one of the biggest factors to consider. 

Licensing Fees

The first and foremost difference between AEM and Drupal is their nature of availability- AEM is proprietary while Drupal is open-source. AEM’s licensing fee starts from somewhere 40,000 USD, with additional cost implications based on organizations’ size and expected usage. And this is not a one-time investment. It is a recurring expenditure every year.

Contrarily, Drupal is an open-source platform and hence discards any licensing fee completely. 

Build vs. Buy

The way current market trends are soaring up does not allow enterprises to consider the deployment of CMS a good idea as it will consume a considerable amount of time. Their expectations lie in finding out an unconventional and innovative solution which is readily available with the quick installation process and some training for content, marketing, and larger digital experience teams to run full-fledged campaigns. 

The general perception that surfaces with Drupal being an open-source, developer-driven solution, is the requirement of complete expert teams to deploy it. There is a definite apprehension around the fact that enterprises have to build from scratch to set up a Drupal CMS, and that without second thoughts, consumes ample amount of time, resources, as well as cost. 

AEM is perceived as a ready-to-roll product requiring minimal expert set up.

“In contrast to the assumption, Drupal does have over 20,000 modules and distributions that provide on-the-go functionalities and features”

However, it’s paramount to apprehend that build vs. buy debate is not as straightforward as it appears. Because:

  • In contrast to the assumption, Drupal does have over 20,000 modules and distributions that provide on-the-go functionalities and features like multisite, multilingual, dynamic content, personalization, and more. With distributions like Acquia Lightning, Drupal caters to highly targeted, easy-to-implement enterprise-level content management solutions, unlike AEM.
  • The other noteworthy point is that AEM does need specialized teams for design, hosting and maintaining an efficient digital platform. They demand an almost similar degree of the build like that of Drupal. But even here, the total cost of implementation for Drupal would be around 250,000 USD to 350,000 USD on an average, and around 500,000 USD if you compute hosting too. On the other hand, typical AEM implementation budget starts exceeding the limit of 500, 000 USD and can go as high as 1 million USD.

Support & Maintenance

Both Drupal and AEM demand substantial maintenance post-deployment.

In regards to the maintenance, Drupal will safeguard your content but to lay the foundation for modern architecture it won't hesitate from breaking some components to ensure that the platform is up-to-date and relevant. To achieve the same, It will eliminate unnecessary bloatware associated with rote adherence to backward compatibility.

 

Licensing 

Build or Buy

Support & Maintenance

Drupal

No licensing fees

Considerable build. Cost approx 250,000-350,000 USD

Support costs can be tailored to fit different enterprises

AEM

Licensing fee applicable

Needs specialized teams for build. Costs approx 500,000 - 1 million USD

Dedicated support teams by Adobe

Security

AEM is certainly a secure platform with predefined functionalities to ensure security and administration. User identification and access can be easily managed. There are tried-and-tested techniques by which risk of inter-site request forgery, can be alleviated, and third party data storage, and role-based authentication and access to data objects can be successfully secured.

A bar graph with 11 bars of different height in peach color on white background

Source: Sucuri

As per the stats, Drupal performs substantially better than other leading CMS platforms in terms of protecting websites from any external attacks.

Sucuri, security platform for websites, compiled the Hacked Website report, analyzed more than 34,000 infected websites. Among the statistics that it shared, one of the factors for comparison was affected open-source CMS applications.

The infection crippled other CMS due to improper deployment, configuration, and the poor maintenance.

With Drupal being an open-source platform, it is generally presumed less secure in comparison to a proprietary platform like AEM. However, that’s not the case! 

Drupal has almost similar security and governance features embedded within it similar to AEM. Drupal has dedicated modules for identification, authentication, and access-based controls.

“Drupal’s security standards are set by the Open Web Security Project, making it secure by design”

The database encryption at various levels vouches for data security so that no unauthenticated user can breach the security. Also, there is built-in security reporting feature to let teams highlight and raise the security concerns within the community. 

It is to take heed that AEM’s security initiative is led solely by one team, with Adobe extending support whenever necessary. 

But Drupal has a different story to narrate! The security advisory not only works on to safeguard the platform but also ensure that there are multiple touchpoints to resolve the issue.

Security documentation, helps developers write secure code, and maintain modules for added security - all this creates a larger system that continuously safeguards Drupal. It’s security standards are set by the Open Web Security Project, making it secure by design.

Scalability and Future Proofing

CMS lays the foundation for providing the unique digital experience to users so it ought to be scalable and customizable. It should be capable of integrating seamlessly with other technologies and simultaneously support new solutions so that its ready to serve the growing needs of the organizations shortly. 

So how are Drupal and AEM different in this regard?

The Adobe ecosystem of products offers all-powerful solutions to amplify the enterprise digital experience. However, its features and full potential can only be realized when organizations are using a combination of several different Adobe solutions. While they continuously come up with new capabilities, the chance to leverage these is often dependent on having up-to-date versions of other Adobe products. AEM is a part of the Adobe Marketing Cloud and makes a pertinent case for buying all the other products to create an efficient digital platform.

For instance, Adobe’s  Smart Layout was a new AI feature rolled out in 2018. However, to make use of this feature, enterprises will need the most recent versions of AEM sites, AEM Assets, Target Analytics, and Audience Manager. And that just adds up to the overall budget by several thousand dollars.

While large enterprises might think of implementing it, the vendor lock-in associated with Adobe does not bode well for scalability.

That's because most enterprises today opt for those solutions which are best-of-breed and best-of-need philosophy. The complete enterprise technology stack gets build in an agile manner, where every new piece appended is the best possible solution for the enterprise with given current requirements and constraints. But in case you decide to choose products from Adobe ecosystem, the need to stick to Adobe becomes crucial. And if you want to leverage any of its products to its full capacity, you may lose out on your flexibility of opting for other solutions that might be more suitable to your needs.

In a nutshell, once you have decided to go with Adobe or even with just AEM, getting out of it becomes difficult even if you keep on adding new moving parts to your digital experience stack.

“Drupal empowers enterprises with the flexibility of choosing any technology solution that works best as per their respective requirements and integrates with them hassle-free”

Four circles with text written over them

However, with Drupal, scalability, expansion, and flexibility have never been a cause of concern. Since Drupal is co-created by a whole community of developers, its feature of integrating seamlessly with various other technology solutions is inculcated in its DNA.

  • The Drupal CMS integrates effortlessly with multiple enterprise systems, even Adobe, and does not rely on the existence of other drupal based solutions to work effectively
  • The potential of decoupled Drupal applications has proven it as best content manager-while letting other technologies to build atop to deliver augmented user-facing functionalities.
  • The open-source community also takes care that new modules and functionalities built on any project get contributed and made readily available for others to use and worked upon.

In essence, Drupal empowers enterprises with the flexibility of choosing any technology solution that works best as per their respective requirements and integrates with them hassle-free. 

The Drupal community also ensures to keep the core up-to-date and the platform is always up to speed to work with other enterprise technologies.

The question that arises here is that whether you want to completely switch to Adobe solutions or want to keep that option with you where you have the flexibility to choose the best solutions for your company.

For uninterrupted flexibility and extensibility, it’s suggested to avoid vendor lock-in and choose Drupal.

Have a look at this video to get more understanding of different web content management systems and their capabilities-

[embedded content]

 

Drupal or AEM

Here is a compiled list of factors arranged in tabular form to carry out the comparison between Drupal and AEM to help you reach the final decision-

Attributes Drupal  AEM

Major Differentiation

A web content management system built by the largest community of developers. A web content management system with implicit personalization and analytics feature.   Agility, cost, and open-source availability are its USPs. Proprietary and licenses are require Flexibility

Being an open-source platform, it does not require any roadmap to implement change.

It is innovation-friendly!

Since it is proprietary and requires a license, it has to wait for rolling out a roadmap to implement changes. Development Speed Easy prototyping leads to faster implementations

Requires considerable time to execute the process

Responsiveness

Highly responsive! It helps in building interactive websites for the enhanced digital experience of users

User Experience and building responsive interfaces are available Integration Capabilities

Rest APIs in the core is easy to integrate

Integratable-Relies on partners for integration

Enterprise Fit

Meets all the criteria of the enterprises

Meets all the criteria of the enterprises Security

Dedicated teams to ensure the security of the platform.

Has a more transparent and open process to communicate the issues within the community

Security directed as by proprietary team Scalable

Highly scalable

Scalable Maintenance

Sign up with any Drupal shop. Vendor Agnostic approach is possible.

Proprietary Cost

Source code is free but organizations have to pay more for adding up functionalities

License costs are high

Final Words

The final choice between Drupal and AEM will be made by the decision-makers based on the array of questions around the cost of building, hosting, and maintenance. This also involves considering the associated ROI with both Drupal and AEM to ensure easy workflow. 

The trade-off between making Adobe products work together well and the freedom to choose the best technology solutions as per your requirements needs to be carefully evaluated.

And even though both Drupal and AEM ensure top-notch security, your enterprise internal security and compliance requirements will also need to be taken into account before choosing one over the other.

Aug 30 2019
Aug 30

For over a decade* the Drupal community has gathered in volunteer-led “camps”, based on the BarCamp model, to follow in that camp’s initial goals:

  • Introduce web developers to the Drupal platform.
  • Skill sharing among established Drupal developers
  • Give back to the Drupal project (e.g. fix bugs, documentation, lesson materials)

The scope of Drupal Camps has expanded as our community has grown and matured, and camps now serve everyone in the community, not just developers. They serve as an on-ramp for new developers, a networking opportunity for clients and agencies, a marketing opportunity for service providers, and much more.

The Drupal Event Organizers have documentation of over 50 volunteer-led events with over 10,000 attendees worldwide in the past year, and we know there are almost double this number that we don’t have good data for. These events have evolved organically, with little central organization, and are estimated to comprise more than one million dollars in sponsorship and ticket sales worldwide, yearly.

The Event Organizers have organized in various forms over that time… from various documentation efforts to our current monthly meeting format. With Kaleem’s instigation, the group started toward a more formal organization in late 2018, and that process is almost a reality. 

We’ve established a formation board composed of organizers from across the globe and have been collaborating on a charter for the Event Organizers Working Group over the past few months. We’re looking forward to presenting it soon and beginning the next chapter of the Drupal Event Organizers.

Thanks to the following folks who have contributed to the effort thus far.

Our Formation Board members:

And our trusted advisers:

* Possibly starting at Drupal Camp Toronto, 2006? If you know of an earlier camp, please let us know in the comments.

Aug 30 2019
Aug 30

The first step is to install Drupal Console. You may have already watched the last episode that covers this, however, if not, you can install with composer using:

composer require drupal/console

This will install Drupal console in your project in the ./vendor/bin/ directory. This means you can run Drupal console using:

./vendor/bin/drupal [command]

Note, in my examples I am using Lando for my local development environment. I have it set up to allow me to run Drupal console commands on my site by running lando drupal. You can decide to install Drupal Console globally and add it to your path. Depending on the development environment your setup might be slightly different.

You can get a list of all the Drupal console commands by running Drupal Console command with no command argument:

drupal

To generate a boilerplate module with Drupal console run:

drupal generate:module

Fill out the questions asked by Drupal console. Make sure to enter a module name and description. In this example, I added a package name, didn’t include a composer.json file, and didn’t include a themable template:

Drupal Console Generate Module

At the end of the questions Drupal console will ask you if it should proceed with creating the module for you. Hit enter to default this to yes.

Drupal Console Generate Module

The next step is to create our custom entity. We want our entity to be a content entity, not a config entity. This can be accomplished with the following Drupal console command:

drupal generate:entity:content

Make sure to select the module you just created. In this case, I will call the entity Statistic and accept everything else at its defaults.

Drupal Console Generate Entity

When you get through all the questions, you will see all the files that were created:

Drupal Console Generate Entity

Now before you go turn this module on, we are going to take a quick look at the code. At the time of this guide, there is a bug that will cause you some headaches if you don’t fix it prior to enabling the module!

Take a look through all the files generated to create the entity. Don’t worry if you are a bit confused at this point, there are a lot of files and a lot of things going on here!

Open up the Statistic.php file (located in the src/Entity folder). If you called your entity something else, it will be the name of the Entity class.

At the top of the file you might notice that the line of code importing EditorialContentEntityBase is missing a semicolon. This is a bug in the code generation tool, make sure to add a semicolon there!

Fix Content Entity Error

This file is doing a lot, but the core of what it is doing is create the structure for your entity. This structure will be created in the database when you install the module. Go ahead and install the module to see how it works. You will notice that once you install the module you are given some menu options under the Admin > Structure menu.

The Statistics setting page is a placeholder where you could eventually add additional configuration settings. This file is controlled by the src/Entity/StatisticSettingsForm.php file.

You will notice you can manage field and display field just like you can with a content type. At this point, we could be done and just use the UI to configure the entity from here. However, in this case we want to add one more field to our entity before we call it finished.

Uninstall the module and open back up the Statistic.php file. Go down to the baseFieldDefinitions method and add the following code after the $field[‘name’] variable is set.

$fields['value'] = BaseFieldDefinition::create('string')
  ->setLabel(t('Value'))
  ->setDescription(t('The value of the Statistics entity.'))
  ->setRevisionable(TRUE)
  ->setSettings([
    'max_length' => 50,
    'text_processing' => 0,
  ])
  ->setDefaultValue('')
  ->setDisplayOptions('view', [
    'label' => 'above',
    'type' => 'string',
    'weight' => -4,
  ])
  ->setDisplayOptions('form', [
    'type' => 'string_textfield',
    'weight' => -4,
  ])
  ->setDisplayConfigurable('form', TRUE)
  ->setDisplayConfigurable('view', TRUE)
  ->setRequired(TRUE);

What this will do is add a new field called value. In this case we are making it a string field and the form will be displayed as a textfield. We could have made this an integer field or a decimal field, but for simplicity we will just make it a string.

If you re-install the module, you will now notice your value field is available. Go ahead and create some Statistics now!

There is a lot more you can do with it. You could spend an hour looking through all the code that was generated as there is a lot to learn! This is a good stopping point for now, as we were able to quickly create our own custom entity using Drupal console!

Aug 29 2019
Aug 29

Masonry is a very popular JavaScript library, that stacks items in columns and rows, like a masonry brick wall.

The items reorder themselves according to their size as the viewport size changes with a nice animation effect. For some examples, take a look at the official Masonry site.

It is possible to create a view in Drupal with this style of layout. Keep reading to learn how!

Example of the Masonry layout

Step #1. Install the required modules

  • Open the Terminal application of your PC and type:

composer require drupal/masonry

Type the composer installation command

composer require drupal/masonry_views

Type this command

This will download the required modules. Masonry API and Masonry Views. The API provides integration between the Masonry JavaScript libraries and Drupal. Masonry Views defines the style of the view (its layout).

There are two more libraries to install for the proper functioning of the modules:

  • Create the /libraries folder in the root of your site
  • Inside this folder create two more folders called /masonry and imagesloaded
  • Right-click on the masonry library page and select Save As
  • Place this file (masonry.pkgd.min.js) inside the /masonry folder
  • Do the same with the imagesloaded.pkgd.min.js file.

Create the folders and move the files

  • Click Extend
  • Select Masonry API and Masonry Views
  • Click Install.

Click Install

The system will prompt you to enable also the Libraries module.

  • Click Continue.

Step #2. Create the View

For this tutorial, I’ve generated some dummy content with the Devel Generate module.

Some dummy content

Some more dummy content

Use this module only on development stages. I generated 50 articles with their images. These images have different width and height values.

  • Click Structure > Views > Add View
  • Select Create a block
  • Show Content of type Article
  • Display format: Masonry of fields
  • Items per block: 12
  • Click Save and edit

Click Save and edit

  • In the Fields section click Add

Click Add

  • In the Category Content, select the fields Body and Image
  • Click Add and configure fields

Click <i>Add and configure fields

  • Change the Formatter and set a character limit for the text
  • Click Apply and continue

Click Apply and continue

  • Leave the default image style
  • Link the image to the content
  • Click Apply.

Click Apply

  • In the Fields section click the dropdown and select Rearrange
  • Put the image between title and body
  • Click Apply.

Click Apply

  • Save the view

Step #3. Place the Block

  • Click Structure > Block Layout
  • Scroll down to the Content section
  • Click Place block.

Click Place block

  • Search for the block you created in the last step
  • Click Place block.

Click Place block

  • Hide the title
  • Click Save block.

Click Save block

  • Rearrange the block above the Main page content
  • Scroll down and click Save blocks.

Scroll down and click Save blocks

If you used the Devel module to generate content like I did, you will notice that the body text is not trimmed. Apart from that, you will see the content inside the block neatly organized in a mason grid.

You will see the content inside the block neatly organized in a mason grid

Step #4. Theming the Grid

There are two classes you can target in your stylesheet to change the appearance of the container and the items inside it:

  • .masonry-layout
  • .masonry-item

The two CSS classes to target

More on Drupal theming at OSTraining here. I hope you liked this tutorial. Thanks for reading!


About the author

Jorge lived in Ecuador and Germany. Now he is back to his homeland Colombia. He spends his time translating from English and German to Spanish. He enjoys playing with Drupal and other Open Source Content Management Systems and technologies.
Aug 29 2019
Aug 29

In my opinion, there’s nothing in the world quite like learning a new skill. It’s a huge rush figuring out how to do something you didn’t know how to do before. You start with the basics, and then once you’ve got the gist of it, you begin to improve. Over time you’ll get better at it, and you’ll get faster at it. Aside from just improving your abilities, your confidence level might change too. This process can go a few different ways. One is imposter syndrome, where you feel like a fraud that doesn’t know what they’re doing. The other is overconfidence, where you think that your skills are better than they are. Be it due to imposter syndrome, overconfidence, or just plain ol’ inexperience; you’re bound to make some mistakes. And we don’t wanna make mistakes, do we?

Chef at workLike everything else in the world, managing Drupal modules takes time and effort to learn. There’s so much going on under-the-hood that it’s all too easy to make a mistake accidentally. In this article, I’ll point out a couple of common mistakes that new Drupal users make, and how you can avoid them. This is all going down while I do my best to make everything fit my metaphor that compares Drupal to a professional kitchen. Let’s get right into it!

Too Many Modules

Have you ever watched the Too Many Cooks video by Adult Swim? No? Well, here it is. Watch the whole thing; it’s worth it. Trust me. Okay, done with that? Cool. Where were we… Oh yeah, too many modules!

[embedded content]

Having too many cooks (or modules) working in one kitchen (your Drupal site) is a disaster waiting to happen for a whole schwack of reasons. Each module you have installed needs to be downloaded and loaded on the user’s device. More modules mean longer load times. Did you know that 53% of mobile users will abandon a page if it takes over 3 seconds to load? Yeah, so I’d say your load times are pretty important. By keeping your number of modules to a minimum, you’ll reduce your load times, sometimes drastically.

Another problem that can be caused by having too many modules is compatibility. For example, let’s say that you installed a contact form module that enables a user to send you an email along with an attachment. For some strange reason though, the blog comments module you’ve installed is broken now! Something somewhere in the new module is causing compatibility issues. Going back to our kitchen metaphor, it’s like the head chef is cooking a great Italian meal, but the sous chef is preparing Chinese food. That’s just not gonna work out for anyone. 

Outdated or Unsupported Modules

If your site has been around for a few years, first of all, great job! Secondly, you should check to see if your modules are all up to date. Not only that, but you should be checking to see if they’re even still supported. Why? Because as time goes on, the nature of the web changes. The nature of web tools, applications, systems, and services all change with it. Sometimes those changes mean that there are additions, alterations, or subtractions to a piece of code that your website relies on to run. When that happens, it could break the functionality of one of your modules. Since this is all happening behind the scenes, deep in code-world, it can be tough to spot the source of your problem. 

Let’s think about it as a restaurant again. In this scenario, our restaurant and kitchen are Drupal, the cooks are our modules, and the food we’re serving is our site content. Our modules work together using features built into Drupal to put all the code, copy, images, and other assets together into one big tasty meal. I mean website.

Alrighty, so, you’ve closed your restaurant this weekend for some remodelling, but forgot to tell some cooks. Fortunately, most of the kitchen floorplan is still familiar. However, it looks like some of the tongs, several knives, and a couple of pans got moved around. Oh, and the salad station has been completely removed. Gone. Vanished. Poof! This is sort of what can happen to a website and its modules when there’s a Drupal update.

Chef at workThe unprepared staff are like outdated modules. Since they don’t know where everything in the kitchen is anymore, their job performance has dropped drastically. Until they get a new tour of the remodelled kitchen, they won’t perform to their fullest, and might not be able to perform at all. In a Drupal update, there might only be tiny changes that barely impact performance, but because your module wasn’t updated to run on this new version, it’s stopped working or slowed down. It’s critical always to ensure your modules are running on the latest version for whichever version of Drupal you’re on.

Your salad tender is another story. That guy’s an unsupported module. For some strange reason, you still offer salads on the menu, but you’ve removed the station for it, and your salad tender wants to get paid under the table from now on. He’s still coming in to work every day even though there he’s got no station, recipes, or even acknowledgement from management. Occasionally though, he still gets salads out to the guests. Sometimes they look great, and other times, your guests might get food poisoning. For the health and safety of your guests, you should look at getting someone who actually has their Food Safe certification and the proper tools to make the salads. In Drupal terms, an unsupported module is a module that’s been abandoned by the team, retired for security reasons, or has been rendered obsolete in some other way. While an unsupported module might function properly and give your site the feature you want it to have, they can also present significant security risks. Unsupported modules don’t get regular updates, so hackers and other black-hats have all the time in the world to leisurely look for exploits in the module’s code. Since their code isn’t being updated along with Drupal’s, their functionality and performance suffer, too. When you use unsupported modules, you’re opening your site up to any number of security risks and performance issues. Just don’t do it!

What Can I Do?

Well, first of all, be sure only to install modules that are still supported and being actively developed. They should be vetted by the community so that you know what you’re installing is high-quality code that’s both functional and secure. Make sure to read the documentation that comes with your modules so that you can make sure you don’t have any compatibility issues with other modules. Keep the number of installed modules to a minimum to improve load times and performance. Look for modules that have overlapping or similar features and decide, “Do I really need both of these?” To put it plainly: carefully research each module, make sure it’s what you need, make sure it works with your site, and make sure the developers and community are still supporting it.

A great way to get a detailed look at your site is to perform a site audit. With a site audit, you’ll see what’s working, what’s not working, where your problems are, and tons of other information. It's kinda like when the health inspector walks through a kitchen and points out the things that need to be improved on. At Cheeky Monkey Media, when our expert team of Drupal developers perform a site audit, they collect all the information that you need to know about your site into one simple, concise, and easy to read the document. Get in touch with one of the monkeys today to get started. We know how hard it can be to try and manage a site on your own, so reach out! We’d be happy to help.

Cooks working
Aug 29 2019
Aug 29

Drupal 8 has a wonderful migration system that generally boils migrations into a particular entity type down into a single YAML file. This file specifies the data source, the output entity type, and how to process input fields and where in the entity they get stored.  

However, there can be a number of complications. Two, in particular, are bad or unexpected input data values, and exactly what form the input data - or even, the partially processed data - is in (eg, is it a scalar, an array, a nested array, etc.). Because the migration system doesn’t provide a way to look at what’s going on inside the process pipeline, it can be difficult and frustrating to debug these kinds of issues.

One way to quickly see what’s going on without having to get into xdebug and grope around in the code for the various plugins provided by the migrate, drupal_migrate, migrate_plus, and migrate_tools modules, is to create a debug plugin and place it wherever you need in the process pipeline.

Usually, the custom migration module code will be structured like this:

migration/
├── config
│   └── install
│       ...
│       ├── migrate_plus.migration.node_article.yml
│       ...
├── migration.info.yml
├── README.txt
└── src
    └── Plugin
        └── migrate
            ├── destination
            ├── process
            │   ...
            │   ├── Debug.php
            │   ...
            └── source

We’re going to look at the node_article migration pass for an example. The YAML file could look something like this:

id: node_article
label: Node - Article
migration_group: migration
migration_tags:
  - Drupal 6
source:
  plugin: node
  node_type: blog
  constants:
    type: article
process:
  nid: tnid
  type: constants/type
  langcode:
    plugin: default_value
    source: language
    default_value: "und"
  title: title
  uid: node_uid
  status: status
  created: created
  changed: changed
  promote: promote
  sticky: sticky
  'body/format':
    -
      plugin: static_map
      source: format
      map:
        2: 'filtered_text'      # Filtered HTML "no links"
        3: 'html_text'          # HTML
        5: 'plain_text'         # PHP code
        6: 'filtered_text'      # Filtered HTML
        7: 'plain_text'         # Email Filter
    -
      plugin: default_value
      default_value: 'html_text'
  'body/value': body
  'body/summary': teaser
  revision_uid: revision_uid
  revision_log: log
  revision_timestamp: timestamp
destination:
  plugin: entity:node

But say that it turns out that the body/format is not getting translated correctly when the node_article migration pass is run. How can this be debugged to understand if the YAML structure is wrong, or the data values are wrong?

Let’s have a look at migration/src/Plugin/migrate/process/Debug.php:

<?php
namespace Drupal\migration\Plugin\migrate\process;

use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;

/**
 * Debug process pipeline
 *
 * @MigrateProcessPlugin(
 *   id = "debug"
 * )
 */
class Debug extends ProcessPluginBase {

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    echo "DEBUG: " . $this->configuration['message'] . "\n";
    print_r(['value' => $value]);
    if (!empty($this->configuration['row']) &&
        $this->configuration['row']) {
      print_r(['row' => $row]);
    }
    return $value;
  }

}

Debug.php provides a process plugin that can be placed “invisibly” into a process pipeline and gives details about what’s happening inside there. The transform method for all process plugins receives the $value being processed and the $row of input values, among other things. It should return a value that is the result of processing that the plugin does.

The ProcessPluginBase object also contains a configuration object, where named parameters that appear in the process pipeline YAML code are stored. For example, the static_map plugin can find the source value in $this->configuration[‘source’].

In this case, the debug plugin returns exactly the value it receives, so it doesn’t change anything. At base, it prints a message parameter and dumps the $value so it can show what actual data is being passed and what format it is in. It has been useful to also be able to look at the $row values. To see them, simply add the parameter row: 1.

For example, to see what the result of the body/format mapping is before passing it along to the default_value plugin:

  'body/format':
    -
      plugin: static_map
      source: format
      map:
        2: 'filtered_text'      # Filtered HTML "no links"
        3: 'html_text'          # HTML
        5: 'plain_text'         # PHP code
        6: 'filtered_text'      # Filtered HTML
        7: 'plain_text'         # Email Filter
    -
      plugin: debug
    -
      plugin: default_value
      default_value: 'html_text'

If it would also be useful to see what the input row values looked like:

  'body/format':
    -
      plugin: static_map
      source: format
      map:
        2: 'filtered_text'      # Filtered HTML "no links"
        3: 'html_text'          # HTML
        5: 'plain_text'         # PHP code
        6: 'filtered_text'      # Filtered HTML
        7: 'plain_text'         # Email Filter
    -
      plugin: debug
      row: 1
    -
      plugin: default_value
      default_value: 'html_text'

This produces output for each row processed, which can get quite large. If you know what rows are causing problems, the migration can be run with the --idlist=”<source keys>” parameter. If not, simply redirect the output into a file and use an editor like vim to hunt through it for the cases that are problematic.

This idea can be expanded: if there is some logic to the problem, this can be added so that output is only created for rows that create an issue. It’s possible to create more than one debug plugin (with different names, of course) if there are multiple special purpose needs.

Aug 29 2019
Aug 29

The first step is to install Drupal Console. You can do that with composer using:

composer require drupal/console

This will install Drupal console in your project in the ./vendor/bin/ directory. This means you can run Drupal console using:

./vendor/bin/drupal [command]

Note, in my examples I am using Lando for my local development environment. I have it set up to allow me to run Drupal console commands on my site by running lando drupal. You can decide to install Drupal Console globally and add it to your path. Depending on the development environment your setup might be slightly different.

You can get a list of all the Drupal console commands by running Drupal Console command with no command argument:

drupal

To generate a boilerplate module with Drupal console run:

drupal generate:module

Fill out the questions asked by Drupal console. Make sure to enter a module name and description. The rest of the options can be left at their defaults (in the example below I also added a Package name):

Drupal Console Generate Module

At the end of the questions Drupal console will ask you if it should proceed with creating the module for you. Hit enter to default this to yes.

Drupal Console Generate Module

You can now see that this has generated a boilerplate module for you. You can now look at this generated code and even install this module on your Drupal site.

We will now use Drupal console to generate and administrative form. This can be started by running the following command:

drupal generate:form:config

The first step is to enter your module name. This should autocomplete as you type. After that you need to add a Form Classname. In the example below, I used SettingsForm. The next four questions can be left at their defaults:

Drupal Console Generate Form Config

When you tell Drupal console you want to generate a form structure, it will provide you a list of form elements and walk you through a form builder process. In this example, I just created a textfield called My Textfield. Go ahead and generate some form fields.

Drupal Console Generate Form Config

When you are finished, just leave the New field type question blank and press the Enter key. It will then ask you some questions regarding the path and menu links.

Drupal Console Generate Form Config

After this it will generate the code for you.

Drupal Console Generate Form Config

Now all you need to do is enable your module, find the link in your admin menu, and you now have an Admin settings form!

Custom Drupal Admin Form

There is so much more you can do with this. As the module currently sits, it doesn’t do much, however, it provides a solid base for you to start developing your own custom module. Spend some time looking through the generated code and feel free to make modifications to the custom module you built.

Aug 29 2019
Aug 29

In a recent press release, TopDevelopers.co declared Agiledrop one of 2019’s best Drupal development firms in the world. With over 10 years of extensive Drupal expertise and several Acquia certified developers, we see this recognition as a true testament to the quality of our work, both with clients and within the Drupal community.

We’re proud to announce that Agiledrop has been chosen as one of the Best Drupal Development companies of 2019! 

For those of you who don't know us - Agiledrop is a web development company specializing in the Drupal CMS. We're based in Central Europe in Slovenia, with headquarters in the capital Ljubljana and offices in several other cities in Slovenia.

Since our beginnings in 2008, our team has grown to over 50 members and we've distinguished ourselves as one of the country's top development companies as well as prolific contributors in the Drupal community, reserving a prestigious position on TopDevelopers.co's list of top Drupal development companies.

As a proud member of the Drupal Association, we’re constantly giving back to the community through code contributions, as well as with frequently organized meetups and free Drupal courses where we train new generations of Drupal enthusiasts. Our specialty, however, lies in helping digital agencies scale up their businesses and take on more work.

Thanks to our 300+ successfully completed projects for a wide range of clients and our 40+ skillful developers, we’re naturally attuned to the needs of particular clients and are able to provide them with the right people for their project in just a few days. Agility is literally in our name! 

Our developers are well-versed in working with Drupal-related services such as Thunder, Drupal Console, Acquia Lightning, Drupal VM, Drush and Open Social. Along with Drupal development, we provide enterprise WordPress development and front-end solutions with modern JavaScript frameworks, e.g. Angular and React. 

We’ve worked with a varied set of clients which includes names such as Ogilvy, UNESCO, Wunderkraut (now Appnovation) and T-Systems - to name just a few. If you’d like to learn about other clients we’ve worked with and what their experience of working with Agiledrop was like, check out our portfolio of references and case studies

And if you're interested in more specific details about our work, such as service and industry focus? Then our profile page on TopDevelopers.co is the place to go; their analysts were super friendly and helped us in building a top-notch profile on their website. 

Of course, we were also very curious to learn how we got chosen among all the amazing and proficient Drupal development companies. When we approached the spokesperson at TopDevelopers.co and asked him about the reasons for choosing us, he was happy to provide us with quite an extensive list:

  • Agiledrop gives its clients only proven Drupal developers who have previously worked on enterprise-level projects, which eliminates the possibility of a bad hire. 
  • Our developers are ready to work on clients’ projects quickly, with individual developers being able to start in only a few days and entire teams being able to start in less than a week, which significantly speeds up the work.
  • We make it a priority to communicate clearly and frequently with clients, no matter the time difference, at least a few times a day, keeping all stakeholders up-to-date on the project’s progress.
  • Our developers adhere to strict coding and security standards, saving costly overruns in the later stages of the project.
  • A lot of Agiledrop’s clients are repeat clients who were so satisfied with our reliability and the quality of our services that they opted for a long-term partnership with us; see our portfolio for their immensely positive reviews.
  • Owing to their comprehensive skillsets, our developers have an excellent grasp of what technologies are most suited to a particular project and are thus able to always choose the most adequate solution to realize the client’s goals and needs.

Who is TopDevelopers.co?

TopDevelopers.co is a directory and review platform for IT service providers. They offer unbiased service to service seekers, by providing them with a listing of genuine and highly professional IT firms, which can help the service seekers in achieving their goals by providing high-quality technical services.  

The research team of TopDevelopers.co chooses the best firms by filtering a vast list of companies and introduces only the competitive names to the businesses, enterprises, and entrepreneurs to partner with. 

The company has a friendly team of researchers and a hassle-free communication system. They provide the listing service for various technologies and services, which makes their platform a one-stop destination to find the perfect technology partner for any kind of project.

Are you just now considering taking on that big project, but lack the development capacity? Contact us at Agiledrop - our A-team will be happy to help you out!

Aug 29 2019
Aug 29

In the previous posts we talked about option to manage migrations as configuration entities and some of the benefits this brings. Today, we are going to learn another useful feature provided by the Migrate Plus module: migration groups. We are going to see how they can be used to execute migrations together and share configuration among them. Let’s get started.

Example definition of a migration group.

Understanding migration groups

The Migrate Plus module defines a new configuration entity called migration group. When the module is enabled, each migration can define one group they belong to. This serves two purposes:

  1. It is possible to execute operations per group. For example, you can import or rollback all migrations in the same group with one Drush command provided by the Migrate Tools module.
  2. It is is possible to declare shared configuration for all the migrations within a group. For example, if they use the same source file, the value can be set in a single place: the migration group.

To demonstrate how to leverage migration groups, we will convert the CSV source example to use migrations defined as configuration and groups. You can get the full code example at https://github.com/dinarcon/ud_migrations The module to enable is UD configuration group migration (CSV source) whose machine name is ud_migrations_config_group_csv_source. It comes with three migrations: udm_config_group_csv_source_paragraph, udm_config_group_csv_source_image, and  udm_config_group_csv_source_node. Additionally, the demo module provides the udm_config_group_csv_source group.

Note: The Migrate Tools module provides a user interface for managing migrations defined as configuration. It is available under “Structure > Migrations” at /admin/structure/migrate. This user interface will be explained in a future entry. For today’s example, it is assumed that migrations are executed using the Drush commands provided by Migrate Plus. In the past we have used the Migrate Run module to execute migrations, but this module does not offer the ability to import or rollback migrations per group.

Creating a migration group

The migration groups are defined in YAML files using the following naming convention: migrate_plus.migration_group.[migration_group_id].yml. Because they are configuration entities, they need to be placed in the config/install directory of your module. Files placed in that directory following that pattern will be synced into Drupal’s active configuration when the module is installed for the first time (only). If you need to update the migration groups, you make the modifications to the files and then sync the configuration again. More details on this workflow can be found in this article. The following snippet shows an example migration group:

uuid: e88e28cc-94e4-4039-ae37-c1e3217fc0c4
id: udm_config_group_csv_source
label: 'UD Config Group (CSV source)'
description: 'A container for migrations about individuals and their favorite books. Learn more at https://understanddrupal.com/migrations.'
source_type: 'CSV resource'
shared_configuration: null

The uuid key is optional. If not set, the configuration management system will create one automatically and assign it to the migration group. Setting one simplifies the workflow for updating configuration entities as explained in this article. The id key is required. Its value is used to associate individual migrations to this particular group.

The label, description, and source_type keys are used to give details about the migration. Their value appear in the user interface provided by Migrate Tools. label is required and serves as the name of the group. description is optional and provides more information about the group. source_type is optional and gives context about the type of source you are migrating from. For example, "Drupal 7", "WordPress", "CSV file", etc.

To associate a migration to a group, set the migration_group key in the migration definition file: For example:

uuid: 97179435-ca90-434b-abe0-57188a73a0bf
id: udm_config_group_csv_source_node
label: 'UD configuration host node migration for migration group example (CSV source)'
migration_group: udm_config_group_csv_source
source: ...
process: ...
destination: ...
migration_dependencies: ...

Note that if you omit the migration_group key, it will default to a null value meaning the migration is not associated with any group. You will still be able to execute the migration from the command line, but it will not appear in the user interface provided by Migrate Tools. If you want the migration to be available in the user interface without creating a new group, you can set the migration_group key to default. This group is automatically created by Migrate Plus and can be used as a generic container for migrations.

Organizing and executing migrations

Migration groups are used to organize migrations. Migration projects usually involve several types of elements to import. For example, book reports, events, subscriptions, user accounts, etc. Each of them might require multiple migrations to be completed. Let’s consider a news articles migration. The "book report" content type has many entity reference fields: book cover (image), support documents (file), tags (taxonomy term), author (user), citations (paragraphs). In this case, you will have one primary node migration that depends on five migrations of multiple types. You can put all of them in the same group and execute them together.

It is very important not to confuse migration groups with migration dependencies. In the previous example, the primary book report node migration should still list all its dependencies in the migration_dependencies section of its definition file. Otherwise, there is no guarantee that the five migrations it depends on will be executed in advance. This could cause problems if the primary node migration is executed before images, files, taxonomy terms, users, or paragraphs have already been imported into the system.

It is possible to execute all migrations in a group by issuing a single Drush with the --group flag. This is supported by the import and rollback commands exposed by Migrate Tools. For example, drush migrate:import --group='udm_config_group_csv_source'. Note that as of this writing, there is no way to run all migrations in a group in a single operation from the user interface. You could import the main migration and the system will make sure that if any explicit dependency is set, they will be run in advance. If the group contained more migrations than the ones listed as dependencies, those will not be imported. Moreover, migration dependencies are only executed automatically for import operations. Dependent migrations will not be rolled back automatically if the main migration is rolled back individually.

Note: This example assumes you are using Drush to execute the migrations. At the time of this writing, it is not possible to rollback a CSV migration from the user interface. See this issue in the Migrate Source CSV for more context.

Sharing configuration with migration groups

Arguably, the major benefit of migration groups is the ability to share configuration among migrations. In the example, there are three migrations all reading from CSV files. Some configurations like the source plugin and header_offset can be shared. The following snippet shows an example of declaring shared configuration in the migration group for the CSV example:

uuid: e88e28cc-94e4-4039-ae37-c1e3217fc0c4
id: udm_config_group_csv_source
label: 'UD Config Group (CSV source)'
description: 'A container for migrations about individuals and their favorite books. Learn more at https://understanddrupal.com/migrations.'
source_type: 'CSV resource'
shared_configuration:
  dependencies:
    enforced:
      module:
        - ud_migrations_config_group_csv_source
  migration_tags:
    - UD Config Group (CSV Source)
    - UD Example
  source:
    plugin: csv
    # It is assumed that CSV files do not contain a headers row. This can be
    # overridden for migrations where that is not the case.
    header_offset: null

Any configuration that can be set in a regular migration definition file can be set under the shared_configuration key. When the migrate system loads the migration, it will read the migration group it belongs to, and pull any shared configuration that is defined. If both the migration and the group provide a value for the same key, the one defined in the migration definition file will override the one set in the migration group. If a key only exists in the group, it will be added to the migration when the definition file is loaded.

In the example, dependencies, migration_tag, and source options are being set. They will apply to all migrations that belong to the udm_config_group_csv_source group. If you updated any of these values, the changes would propagate to every migration in the group. Remember that you would need to sync the migration group configuration for the update to take effect. You can do that with partial configuration imports as explained in this article.

Any configuration set in the group can be overridden in specific migrations. In the example, the header_offset is set to null which means the CSV files do not contain a header row. The node migration uses a CSV file that contains a header row so that configuration needs to be redeclared. The following snippet shows how to do it:

uuid: 97179435-ca90-434b-abe0-57188a73a0bf
id: udm_config_group_csv_source_node
label: 'UD configuration host node migration for migration group example (CSV source)'
# Any configuration defined in the migration group can be overridden here
# by re-declaring the configuration and assigning a value.
# dependencies inherited from migration group.
# migration_tags inherited from migration group.
migration_group: udm_config_group_csv_source
source:
  # plugin inherited from migration group.
  path: modules/custom/ud_migrations/ud_migrations_csv_source/sources/udm_people.csv
  ids: [unique_id]
  # This overrides the header_offset defined in the group. The referenced CSV
  # file includes headers in the first row. Thus, a value of 0 is used.
  header_offset: 0
process: ...
destination: ...
migration_dependencies: ...

Another example would be multiple migrations reading from a remote JSON. Let’s say that instead of fetching a remote file, you want to read a local file. The only file you would have to update is the migration group. Change the data_fetcher_plugin key to file and the urls array to the path to the local file. You can try this with the ud_migrations_config_group_json_source module from the demo repository.

What did you learn in today’s blog post? Did the know that migration groups can be used to share configuration among different migrations? Share your answers in the comments. Also, I would be grateful if you shared this blog post with others.

This blog post series, cross-posted at UnderstandDrupal.com as well as here on Agaric.coop, is made possible thanks to these generous sponsors. Contact Understand Drupal if your organization would like to support this documentation project, whether it is the migration series or other topics.

Aug 29 2019
Aug 29

In the previous post we talked about migration groups provided by the Migrate Plus module. Today, we are going to compare them to migration tags. Along the way, we are going to dive deeper into how they work and provide tips to avoid problems when working with them. Let’s get started.

Example migration group definition containing migration tags.

What is the difference between migration tags and migration groups?

In the article on declaring migration dependencies we briefly touched on the topic of tags. Here is a summary of migration tags:

  • They are a feature provided by the core Migrate API.
  • Multiple tags can be assigned to a single migration.
  • They are defined in the migration definition file alone and do not require creating a separate file.
  • Both Migrate Tools and Migrate Run provide a flag to execute operations by tag.
  • They do not allow you to share configuration among migrations tagged with the same value.

Here is a summary of migration groups:

  • You need to install the Migrate Plus module to take advantage of them.
  • Only one group can be assigned to any migration.
  • You need to create a separate file to declare group. This affects the readability of migrations as their configuration will be spread over two files.
  • Only the Migrate Tools provides a flag to execute operations by group.
  • They offer the possibility to share configuration among members of the same group.
  • Any shared configuration could be overridden in the individual migration definition files.

What do migration tags and groups have in common?

The ability to put together multiple migrations under a single name. This name can be used to import or rollback all the associated migrations in one operation. This is true for the migrate:import and migrate:rollback Drush commands provided by Migrate Plus. What you have to do is use the --group or --tag flags, respectively. The following snipped shows an example of importing and rolling back the migrations by group and tag:

$ drush migrate:import --tag='UD Config Group (JSON Source)'
$ drush migrate:rollback --tag='UD Config Group (JSON Source)'

$ drush migrate:import --group='udm_config_group_json_source'
$ drush migrate:rollback --group='udm_config_group_json_source'

Note: You might get errors indicating that the "--tag" or "--group" options do not accept a value. See this issue if you experience that problem.

Neither migration tags nor groups replace migration dependencies. If there are explicit migration dependencies among the members of a tag or group, the Migrate API will determine the order in which the migrations need to be executed. But if no dependencies are explicitly set, there is no guarantee the migrations will be executed in any particular order. Keep this in mind if you have separate migrations for entities that you later use to populate entity reference fields. Also note that migration dependencies are only executed automatically for import operations. Dependent migrations will not be rolled back automatically if the main migration is rolled back individually.

Can groups only be used for migrations defined as configuration entities?

Technically speaking, no. It is possible to use groups for migrations defined as code. Notwithstanding, migration groups can only be created as configuration entities. You would have to rebuild caches and sync configuration for changes in the migrations and groups to take effect, respectively. This is error prone and can lead to hard to debug issues.

Also, things might get confusing when executing migrations. The user interface provided by Migrate Plus works exclusively with migrations defined as configuration entities. The Drush commands provided by the same module work for both types of migrations: code and configuration. The default and null values for the migration_group key are handled a bit different between the user interface and the Drush commands. Moreover, the ability to execute operations per group using Drush commands is provided only by the Migrate Tools module. The Migrate Run module lacks this functionality.

Managing migrations as code or configuration should be a decision to take at the start of the project. If you want to use migration groups, or some of the other benefits provided by migrations defined as configuration, stick to them since the very beginning. It is possible to change at any point and the transition is straightforward. But it should be avoided if possible. In any case, try not to mix both workflows in a single project.

Tip: It is recommended to read this article to learn more about the difference between managing migrations as code or configuration.

Setting migration tags inside migration groups

As seen in this article, it is possible to use set migration tags as part of the shared configuration of a group. If you do this, it is not recommended to override the migration_tags key in individual migrations. The end result might not be what you expect. Consider the following snippets as example:

# Migration group configuration entity definition.
# File: migrate_plus.migration_group.udm_config_group_json_source.yml
uuid: 78925705-a799-4749-99c9-a1725fb54def
id: udm_config_group_json_source
label: 'UD Config Group (JSON source)'
description: 'A container for migrations about individuals and their favorite books. Learn more at https://understanddrupal.com/migrations.'
source_type: 'JSON resource'
  migration_tags:
    - UD Config Group (JSON Source)
    - UD Example
# Migration configuration entity definition.
# File: migrate_plus.migration.udm_config_group_json_source_node.yml
uuid: def749e5-3ad7-480f-ba4d-9c7e17e3d789
id: udm_config_group_json_source_node
label: 'UD configuration host node migration for migration group example (JSON source)'
migration_tags:
  - UD Lorem Ipsum
migration_group: udm_config_group_json_source
source: ...
process: ...
destination: ...
migration_dependencies: ...

The group configuration declares two tags: UD Config Group (JSON Source) and UD Example. The migration configuration overrides the tags to a single value UD Lorem Ipsum. What would you expect the final value for the migration_tags key be? Is it a combination of the three tags? Is it only the one key defined in the migration configuration?

The answer in this case is not very intuitive. The final migration will have two tags: UD Lorem Ipsum and UD Example. This has to do with how Migrate Plus merges the configuration from the group into the individual migrations. It uses the array_replace_recursive() PHP function which performs the merge operation based on array keys. In this example, UD Config Group (JSON Source) and UD Lorem Ipsum have the same index in the migration_tags array. Therefore, only one value is preserved in the final result.

The examples uses the migration_tags key as it is the subject of this article, but the same applies to any nested structure. Some configurations are more critical to a migration than a tag or group. Debugging a problem like this can be tricky. But the same applies to any configuration that has a nested structure. If the end result might be ambiguous, it is preferred to avoid the situation in the first place. In general, nested structures should only be set in either the group or the migration definition file, but not both. Additionally, all the recommendations for writing migrations presented in this article also apply here.

What did you learn in today’s blog post? Did you know the difference between migration tags and groups? Share your answers in the comments. Also, I would be grateful if you shared this blog post with others.

This blog post series, cross-posted at UnderstandDrupal.com as well as here on Agaric.coop, is made possible thanks to these generous sponsors. Contact Understand Drupal if your organization would like to support this documentation project, whether it is the migration series or other topics.

Aug 29 2019
Aug 29

Make sure you have downloaded and installed the ECK module. Once installed, click on the Configure link or go to Structure > ECK Entity Types.

ECK Module Install

The ECK module allows you to define different entity types. These are similar to the way you define content types, but at a slightly higher level. When you create a content type, you are technically creating a bundle within the node entity type. In the case of ECK, you are defining your own Entity type that may or may not have bundles within it.

Click on the Add entity type button.

ECK Add Entity Type

In this example, we will be creating a new entity to keep track of important statistics. We will use the label Statistic and check all the available Base Fields. You can use whatever Label you would like and the base fields are all optional. I would highly recommend adding a Title field though.

Once finished, click the Create entity type button.

ECK Add Stat Entity Type

Your new Entity will now be displayed in the Entity Types list.

ECK Entity Type List

Click the Add bundle button to add a new bundle to this entity type. In our example, we will only create one bundle. The bundle will be called Number Stat and we will use it to track numeric statistics. Once you have your bundle information filled out, click the Save bundle button.

ECK Add Entity Bundle

The new bundle is now listed on the Statistic bundles listing page.

ECK Bundles List

We could create additional bundles if we had different types of statistics. Similar to how you can have different content types in Drupal 8. In this case, we will stick with just the one bundle and click on the Manage fields button.

Here you can add fields just like you add fields to a content type. In this case, just add a decimal number field called Statistic.

ECK Add Field

You can now go back to the ECK Entity Types admin page and click the Add content button on your Statistic entity type. Go ahead and fill out the form to add a few stats. Once you create some stats, you can go to the ECK Entity Types admin page and select the Content list option from the dropdown button. This will list all the entities for that entity type.

ECK Content

Now that you have the data stored on your site you can use Views or entity reference fields to display or reference this content throughout your site.

The ECK Module has a number of permissions available. These allow you to decide which roles can administer your ECK entities, bundles, and types. Typically you will give all of these roles to only your administrative users. However, the module provides flexibility if you have more complicated use cases.

ECK Permissions

You now know how to create custom entity types using the ECK module. Now go out and build all your entity data structures!

Aug 29 2019
Aug 29

usability testing and great government UX webinar

Crafting UX - for the people, by the people 

Mass.gov takes a data-informed approach to site decisions. An open ear to constituent feedback ensures a "wicked awesome" user experience. So it's no surprise that when the site’s navigation needed improvement, user testing became a guiding light.

In our upcoming webinar, hear how Mediacurrent teams with Mass.gov on a user testing strategy leveraging Drupal 8 and Google Optimize. 

Join our webinar

Watch how to deliver a constituent experience that is discoverable, accessible, and truly “for the people, by the people.” Join us on September 18, 2019, at 2:00 EDT to follow along with our process. Learn tips to user test your way to better website UX. 

Register for the webinar.

You'll learn

  • Our approach to testing and gathering user feedback
  • The A/B testing variants we used to steer site navigation and layout
  • Deep dive into testing with Google Optimize 

Presenters

  • Clair Smith, Senior Front End Developer, Mediacurrent
  • Becky Cierpich, UX/UI Designer, Mediacurrent

We hope to see you there!

Aug 28 2019
Aug 28

Join Hook 42 for Another Exciting BADCamp

Some of our team will be at BADCamp this year with a combination of to-do's and goals. Our team is not only going to be on-site for training, sessions, booth-sitting, and attending sessions, we're also behind the scenes helping organize and plan for this year's event. Our sponsorship, and those of many other amazing donors, is going towards putting together another BADCamp you don't want to miss!

We're excited to be so hands-on for this event and would like to send a special thank you to those involved in the planning and coordination that have embraced Hook 42's participation thus far. The variety of ways we can contribute to this event and make an impact is extensive, and our team is happy to be giving back to an amazing community. We can't wait for October!

Hook 42 Trainings at BADCamp

We're excited to have four of our team members teaming up to give two trainings this year. The first, Adam Bergstein and Ryan Bateman will be talking about GatsbyJS and Drupal 8. In this training you'll learn how to take a brand new Drupal 8 site running the Umami Demonstration Install Profile and build a recipe blog front-end using GatsbyJS and React, with no React experience required! 

We'll also have Aimee Hannaford and Lindsey Gemmill giving training on web accessibility, covering a beginning to end high-level dive into how to be inclusive on the web. For more information about each training, visit the respective training page BADCamp website linked below.

Hook 42's Adam Bergstein and Ryan Bateman deliver a full day Drupal 8 and GatsbyJS training at BADCamp 2019

Hook 42's Aimee Hannaford and Lindsey Gemmill deliver a full day web accessibility training at BADCamp 2019

Registration For Training Sessions Is Now Open!

There is limited availability for training sessions, so sign up soon. Each room holds approximately 30 people. If you're interested in one of our training sessions, or any other training at BADCamp this year, please be sure to register to reserve your spot. See the training detail page on the BADCamp website for more information.

Sessions

Beyond full-day training, our team will also be giving a few sessions at BADCamp. We're passionate about the topics we submit to camps and conferences and are excited to be sharing our ideas and expertise with all of you.

Hook 42's Adam Bergstein and Ryan Bateman deliver a session at BADCamp

Hook 42's Aimee Hannaford and Ryan Bateman deliver a session at BADCamp

Hook 42's Lindsey Gemmill delivers a session at BADCamp

Hook 42's John QT Nguyen and Pantheon's David Needham deliver a session at BADCamp

We Hope To See You There

If we aren't behind the computer talking, you can find us out and about. Our team will be fully immersed in BADCamp 2019, so we're just as excited to attend the other amazing presentations selected for this year's event as we hope you are.

Hook 42 will also have a booth at the event this year. We're always looking to make new connections with people at these events and can't wait to talk about the amazing things our team has to offer. Whether you're a new face or an old face, come stop by and say hello!

Aug 28 2019
Aug 28

To always work smoothly and be up-to-date, your Drupal website needs support and maintenance. It’s nice to know you can rely on experts for things like Drupal updates, website performance audit, bug fixes, or anything else. However, you need to choose them carefully. 

First of all, there are plenty of reasons to choose a support company over a freelancer. But there are also the must-have characteristics of a good Drupal support agency. Let them help you with your choice. 

Good Drupal support agency’s features 

  • Decent time on the market

All companies were once startups. However, if a Drupal support agency popped up a week ago, it might be risky to immediately entrust it with major website tasks. After a little while, the agency is able to prove its stability on the market. 

Drudesk support agency has celebrated its 4th birthday and its parent company InternetDevels is preparing to have its 12th anniversary. They have gained a lot of solid experience in challenging Drupal support projects and complex cases.

  • Positive customer feedback

No one says that 100% trust in online feedback is a panacea. Still, it’s important to know what experiences other people have had with a Drupal support agency, so it definitely should have positive reviews.

Drudesk’s customers speak warmly about the agency, call it a forward-thinking and conscientious team, communicative and organized, quick to respond to queries, a reliable partner, and more. Drudesk reviews on Clutch, testimonials on the company’s main page, and other feedback will give you a better picture. 


positive customer feedback

  • A wide range of support services

Website support embraces a wealth of various aspects. It’s convenient and effective to have the same agency working with all of them. So your ideal Drupal supporting partner needs to have broad expertise. 

Drudesk offers all kinds of support and related services. Among them:

and many more.

But this is not all — Drudesk has a strong web development background that allows it to develop websites from scratch. 

In addition, the agency employs quality assurance engineers, DevOps experts, SEO specialists, and others whose expertise may be needed for your case. 

a wide range of support services

  • Warranty for the work performed

Drupal support services, like any others, need to have a warranty. This means that the agency is responsible for their work. 

It should be noted that website support services have their peculiarities. Websites often have old bugs and legacy code that may interfere with the website’s work, making it harder to give a warranty for particular tasks. 

Still, Drudesk cares about customers and offers a warranty for the tasks performed. The standard acceptance period lasts 31 calendar days. During this time, you can check the results. If you find any bugs, everything is fixed free of charge.

  • Transparent task tracking

A good Drupal support agency will give you full control over the tasks performed. Its workflows will be transparent and open to you.

With Drudesk, all customers can see the working progress in real-time. All tasks are managed in Drudesk’s CRM. You can leave your comments on tasks and approve the results. You can also be notified about the team’s new comments in any way convenient to you. 

Since Drudesk relies on the Agile methodology, it has an iterative approach to projects. Large ones are broken into sprints and your feedback is considered at every stage in order to make the result more suited to your needs.

transparent task tracking

  • Openness to communication

When working with a decent Drupal support agency, you should feel they are ready to answer your questions and hear your feedback.

Effective communication is one of Drudesk’s priorities. The agency has English-speaking customer service managers and project managers. 

They make sure your ideas are brought to the developers in the right ways, and they are always open to communication and ready to schedule a Skype call with you or reply by email.  

  • Drupal.org profile & community engagement

Every agency working with the Drupal open-source CMS is part of the Drupal community. Its engagement into Drupal life is directly connected to its attitude and expertise. 

Drudesk is listed on drupal.org and its developers make their contribution to various Drupal projects. They help newbies understand Drupal through discussion forums and willingly mentor new talents. Drudesk developers also actively participate in Drupal events like code sprints, Drupal Camps, etc.

Drupal community engagement

Your Drupal support agency is here

When all these characteristics are met, this means you have found a perfect Drupal support services partner. Contact our Drupal support agency and let’s discuss how we can make your website’s work better. This is where good website support starts!

Aug 27 2019
Aug 27

Carole Bernard's Drupal.org user profile photoThe Drupal Association (DA) is pleased to announce the recent hire of Carole Bernard as the Director of Marketing and Outreach. She and her team will focus on increasing visibility for the Drupal Association and opportunities for Drupal adoption through marketing, community engagement, volunteer management and public relations activities.

With extensive nonprofit and public sector experience, Bernard has served in senior leadership roles for more than 15 years at local, regional and national organizations.  

Bernard, a Boston native, began her career as a speechwriter for the Mayor of Boston. She then worked as the Director of Public Information for the largest human service agency in New England, Action for Boston Community Development, Inc. She started her own consulting business in 2015, providing strategic communications, fundraising and executive management services to nonprofit organizations in the Washington, DC area. She recently served as the Director of Communications and Marketing for Sickle Cell Disease Association of America, Inc. She also has worked for Paralyzed Veterans of America, National Center for Women and Children and the National Minority AIDS Council as their Director of Communication.

“I am so excited to be a part of the dynamic team at the Drupal Association,” says Bernard. “I am blown away by the passion and commitment of the Drupal community, and I look forward to working with everyone to tell the DA story, to showcase the Drupal project, to broaden the organization’s reach to new audiences and to increase opportunities for Drupal adoption around the world through strategic communications and outreach efforts.”

“We want to continue to position Drupal as the leading open-source CMS for ambitious digital experiences that reach audiences across multiple channels around the world,” says Heather Rocker, DA Executive Director. “We also want to expand our efforts to bring new entities and individuals to the table to participate in our global community. We are excited to have Carole join us and to help us lay out and execute a plan that leverages all of the DA assets for growth, inclusion, awareness and participation.”

Bernard received her bachelor’s degree in Political Science from Framingham State College and her master’s degree in Journalism from Boston University.

Aug 27 2019
Aug 27

So you want to turn those plain URL’s into something a little more fancy? Well, you have come to the right place. First make sure you have downloaded and installed the Drupal 8 URL Embed module. It’s recommended to download and install this module using composer so it will download the Embed module and the PHP Embed library automatically. You can do that with

composer require drupal/url_embed

The next step is to customize the embed button, if you want to. To do this, go to Configuration > Content Authoring > Text editor embed buttons.

Essentially, you can change the icon and add additional embed buttons. These buttons will be able to be used within your Text formats. It’s fine to leave these at the defaults for now. By clicking on the Settings link you can change where the button icon files should be stored.

Leave these settings at their defaults as well. Next, navigate to Configuration > Content Authoring > Text formats and editors. Here you will see a list of all the text formats on your website. Click the Configure button on the Basic HTML text format.

This will bring you to a page that will allow you to edit the Toolbar Configuration. Drag the URL Embed button into the Toolbar Configuration. You can place this wherever you want, but it likely makes the most sense in the Media section.

We now need to enable and configure two additional filters. Check the boxes next to Display embedded URLs and Convert URLs to URL embeds.

In the Filter Processing order section, make sure to rearrange the filters so Convert URLs to URL embeds comes before Display embedded URLs. This kind of makes sense as you need to first convert the URL before you can display it! You may also want to drag the Align images below both of these filters if you want to be able to align the embed codes. To use the Align images you will need to make sure you have the alignment buttons added to your toolbar configuration.

Under Filter settings, you now need to allow in the Limit allowed HTML tags and correct faulty HTML section.

Still in the Filter settings section, you can specify an optional prefix which can be used to indicate what URLs to accept. This could be useful if you only wanted Twitter links to be used for example. If you don’t specify anything here, then all of the embed urls from any provider will work.

Click the Save configuration button and now create some content on your site. You can go to Content > Add content > Article and go to the Body field to see your new Embed button in action. Make sure you add some content then click the URL Embed button and paste in a link (the example below used a Twitter link).

Now when you save the page, it will show up exactly like you would expect an embedded Tweet to show up.

Feel free to try out different types of links, the next example uses a Youtube link.

That’s all there is to it! As you can see, it’s incredibly easy to use the Drupal 8 URL Embed module to embed Twitter, Youtube, Instagram, Spotify, and many more types of links directly in your Drupal content. Now go out and start sharing those links on your Drupal site!

Aug 27 2019
Aug 27

Congrats, Drupal 9 release is planned for June 2020! In the meantime, you should ensure that your platform is ready for the upgrade. Although it should arrive easily and smoothly, your website still needs a plan.

The team at WishDesk explains how to get ready and plan for Drupal 9.

What should I know about Drupal 9?

Dries Buytaert, the Drupal creator, announced the planned release of D9 for June 3, 2020. This new version is developed in the same codebase as D8, which means that migration from Drupal 8 to Drupal 9 will be painless. What about D7 and D8? They will reach their end-of-life in November 2021. This means that there will be no official support and no more updates for these versions.

plan for Drupal 9

We recommend upgrading to Drupal 9 by November 2021.

How to plan for Drupal 9 if you are using Drupal 8

If you are using D8 and keep it updated, the migration will be no harder than a minor release. When planning for Drupal 9, make sure that all your modules are updated and deprecated code is removed from the codebase.

Why will migration from Drupal 8 to Drupal 9 be effortless?

  • there will be no need to rewrite the whole code for D9
  • regular D8 updates will keep your platform up-to-date and ready for migration
  • D8 modules will be compatible with D9

How to prepare for Drupal 9 if you are on Drupal 7

Things are more difficult for those whose website is still built on D7. We strongly recommend starting the upgrade process now if you want to have fewer problems when planning for Drupal 9. There are numerous reasons to upgrade to D8:

  • better development experience
  • powerful layout building
  • easy upgrades
  • improved media management
  • improved theming experience
  • decoupled content delivery
  • improved performance
  • and more!

Although the best option for D7 website owners is to migrate to Drupal 8, you can contact a web development company for support of your Drupal 7 website even after the official end-of-life.  

Plan for Drupal 9 with WishDesk!

Get ready for Drupal 9 with the web development specialists at the WishDesk team! No matter what version of this CMS you are using now, we will help you plan for Drupal 9, as well as perform the migration process effortlessly. Just contact our experts!

Aug 27 2019
Aug 27

Want an easy way to extend your market reach and ultimately your sales? Do you feel you need to personalize your website to every user no matter which country they belong to or what language they speak? Getting yourself a multilingual website is your best bet. Not only is it a more cost-effective marketing strategy, it also helps in increasing your website traffic and overall SEO. Drupal CMS has particularly taken up this challenge of providing not only users but also developers with the ability to access Drupal in a language that they prefer. And with Drupal 8 being multilingual out-of-the-box, it has become an ideal choice for businesses and developers. Powerful Drupal translation modules offer developers with granular configuration capabilities where every content entity can be translated.

What are Multilingual Websites?

Multilingual basically means written or available in different languages. Multilingual websites connect better with users from different countries as it immediately adds an element of familiarity. Drupal 8 provides an easy and a great experience of building a multilingual website. Currently Drupal 8 supports 100 different languages for translation.

Drupal 8 has a multilingual feature which comes along with the installation interface. As soon as you install Drupal, based on the browser preference, it provides a language for your Drupal website. Based on the option selected the site is installed in that particular language. Drupal 8 basically provides 4 different modules for language and content translation. We can enable the required Drupal modules in our site and use according to our needs in the website. 

Drupal-8-migration

The four core modules provided by drupal are

  1. Language module
  2. Content translation module
  3. Interface translation module
  4. Configuration translation module

Let’s catch up with what each module does, its configurations and how each module can be used in our Drupal website.

Firstly, you need to enable all the 4 core modules in your drupal site. All the translation modules can be configured at path /admin/config/regional

Drupal Language Module

This Drupal 8 language module is one of the core modules located at core/modules/language. It provides a feature of adding and choosing a new language to your Drupal website. Under /admin/config/regional/language/ you can simply add a new language to your site by clicking on the “Add Language” button. It provides a list of different languages from which you can choose the language you need for the development.

drupal-8-migrationdrupal language module

Choose the preferred language from the list and add it

Once the language is added the interface will look similar to this. In the above picture, the default language of the interface is set as English and spanish is the additional language installed. The 9172/9340(98.2%) under Interface translation indicates that 9172 words out of 9340 words available for translation are translated i.e 98.2% of the words in the interface are translated.

It also provides a block( Language switcher) to switch the language from one to another which can be placed at  any region of your Drupal website. Under /admin/structure/block we can place the language switcher block with which we can switch the default language of our website.

Drupal Language Switcher                                                                                Language Switcher

Once the block is placed in the region we will be able to switch to the different languages in the web page itself.

Content Translation Module

The Drupal Content Translation module allows you to translate content entities such as comments, custom block, contents, taxonomy terms, users etc. In order to translate the content entities, the website should have at least two languages installed. The content translation can be configured at path admin/config/regional/content-language . It provides a list of entity types which can be translated. 

For example, click on the content configuration option that appears for each content type.

Let us consider that the content translation is being enabled for the article content type. It provides an option to decide if each subtype entity to be translatable or not. We can also change the default language for a particular content type. Each field has an option to translate its content or not. 

Content Translation Module - Choosing the content                                            Content Translation Module - Choosing the content

It also provides an option to input the content in the language which is suitable for the user while adding content from the backend interface. Once the above configuration is set up and when we try to add content to the Article content type we can see a Select option with the languages installed in our site. We can select any language and add content in the particular language selected.

Content Translation Module - Select the language                                       Content Translation Module - Select the language


Once the contents are saved, users with translate permissions will see links to Translate its content. It provides an additional tab called “Translate” along with the  "Edit" links, and you'll be able to add translations for each configured language.

Content Translation Module - Select the language                                                           
                                                         Content Translation Module - Select the language

Interface translation Module

 The Drupal Interface translation module is also a part of core module and can be easily enabled like any other drupal module. Once this module is enabled it is possible to replace any string in the interface with string which has been customized. Whenever this module encounters any string it tries to translate the particular string to the current language of the interface. If a particular translation is not available it is remembered and we can lookup into the untranslated string in the table.   

Interface translation Module                                                                Interface translation Module


In the above example, the strings which are both translated and untranslated are displayed and we are able to modify the strings for the language that is installed as well.
The translations for the strings are put up in a single place called http://localize.drupal.org and the Localization Update module will automatically import the updated translation strings for your selected language. In Drupal 7 and previous versions, this was a contributed module. In Drupal 8 it is a part of a core module.

Configuration translation Module

The Drupal 8 Configuration Translation module allows configuration to be translated into different languages. The site name, views name, and other configurations can be translated easily using the configuration translation.

Configuration translation Module                                                                    Configuration translation Module

It also provides an option to input the content in the language which is suitable for the user while adding content from the backend interface. Once the above configuration is set up and when we try to add content to the Article content type we can see a Select option with the languages installed in our site. We can select any language and add content in the particular language selected.

Aug 26 2019
Aug 26

August 26th is a special day for the owners of Hook 42. As a woman-owned company, we are very familiar with the adversity women face in the workplace. We’re even more familiar with how intense that can get depending on the industry you’re in.

Our inspiration for starting Hook 42 was a culmination of many different things, but one of those things was creating our own voice outside of a male-dominated workforce. The signs were clear that everywhere we looked we found areas of improvement, so our owners took things into their own hands and built a business to solve those problems. 

Hook 42 strives to be a fully inclusive workplace, and we encourage our team to voice their opinions and work towards a better version of themselves, no matter what it takes. 

But what does this philosophy have to do with today specifically?

National Women’s Equality Day and National WebMistress Day fall on August 26th. Both of these topics are influenced by a history of inequality and strive to create an inclusive space that gives everyone an equal opportunity. We’d like to take time to recognize the fights that were won and those we’re still fighting today with the celebration of these two holidays.

A Little Bit of History

The United States Congress passed the 19th Amendment to the Constitution granting women full and equal voting rights on this day in 1920. [ source ]

“Later, On July 30, 1971, Rep. Bella Abzug (D-NY) presented a bill designating August 26th as Women’s Equality Day. That year, rallies, celebrations and political debate filled the country on August 26th. By 1973, Congress passed a joint resolution declaring the day to be observed on August 26th of each year. Every year since each president declares this day as Women’s Equality Day commemorating the certification of the 19th Amendment to the United States Constitution.” [ source ]

We’re predicting that it is no coincidence Kat Valentine founded National WebMistress Day on this very same day quite some years later. In only its third year, National WebMistress Day is putting a more granular focus on supporting equal rights for women and recognizing the adversity women face in the technology industry.

As members of that industry, we want to share our support for every woman in tech that is fiercely making an effort to leave their mark and find their place in a chaotic environment. We’re 100% behind supporting the wave-making, change-inducing women of tech and cultivating that same culture right within our company.

We talked to the ladies within Hook 42 to gather some insights into their journey within tech so far, and what the future holds. Let’s continue to drive change, and support those who are advocating these rights.

The Women of Hook 42

Aimee

What would you tell your younger woman-self if you had the chance to give her advice based on what you know now about the tech industry?

Don’t dress down. You don’t need to compromise your personal appearance to fit into the “hoodie and t-shirt crew”. If you want to rock your comfort wear then embrace it!

Believe in yourself. You are the only one that can affect change around you. Make goals, strive to reach them, and calibrate when you need to. You are the only one that can improve yourself and your life.

And enjoy the journey. 

How can people be an ally to women in tech?

Be supportive in all aspects of a woman’s life. The tech industry has long days, off-hours, and overtime baked into its core. This combined with the added mental and physical workload we may experience outside of work thrives on a supportive culture.

What helps you push boundaries in tech?

Technology is one of the fastest platforms to implement and execute change. I love bringing peace to chaos and to create new “things” that help improve our lives. Being able to leverage technology for good is a big driver for me.

Is there a woman in tech you look up to, maybe a mentor? (Can be someone you've never talked to but are just inspired by)
Gerri Sinclair. She balances a loving family and a wonderful extended group of friends while bringing bold technology changes through the years. Thank you for all of your energy and impact on technology Madame Modem!

What are you looking to accomplish with your career in tech?

I like to have a place where people can feel they can work safely where they can grow in their personal and professional lives. I like to build cool things. My goal is to have more people be able to have positive interactions which said cool things. :) I’m working to extending the tech environment beyond the tech to include the human side of things, like growth, authenticity, inclusion, and accessibility.

Were there struggles in your journey? Do you still face them? How did you push past it?

There are and have been many struggles in my journey. Some struggles have changed over time, some are still the same. Struggles include breaking through glass ceilings, having to work harder / smarter / stronger / faster than men, and being criticized for having the courage to lead the charge and search out brave new worlds.

Mentors, friends, professional guidance, education, and grit got me through the struggles. Once again, a person (me) is fully responsible for my own actions, regardless if I’m advised in one way or another.

Kristen

What would you tell your younger woman-self if you had the chance to give her advice based on what you know now about the tech industry?

Even though you hear a lot about bad things about being a woman in tech, you can find nice communities who will welcome you and be supportive. If you are in a bad environment in tech (no matter what gender), try to talk to other people in tech who are in healthy environments and consider switching before leaving.

How can people be an ally to women in tech?

Be a good person and call out bad behavior. Try to show that you welcome others in your groups with your words and actions (e.g. the "Pac-Man Rule"). Be open to differing opinions when offered respectfully.

What helps you push boundaries in tech?

Having a supportive community helps us stand on the shoulders of giants and continue to innovate.

What fuels your passion to keep doing what you do every day?

Seeing something I helped build used by real people, in real life.

Is there a woman in tech you look up to, maybe a mentor? (Can be someone you've never talked to but are just inspired by)

Although there are a lot of great people in the Drupal community, there are 3 people who are amazing role models for all genders who immediately pop into my head: Angie Byron, Amanda Gonser, and Gábor Hojtsy.

What are you looking to accomplish with your career in tech?

Using the skills I have for giving back to the greater good and improving humanity.

Were there struggles in your journey? Do you still face them? How did you push past it?

Yes, often. Some things that may help: stay away from toxic people, give yourself permission to fail, give yourself permission to say "no" without guilt, be kind to yourself, and talk to people who have gone through similar things so you know you aren't alone.

Alona

What would you tell your younger woman-self if you had the chance to give her advice based on what you know now about the tech industry?

Keep learning and never give up.

How can people be an ally to women in tech?

Support, mentor, and encourage.

What fuels your passion to keep doing what you do every day?

I like working in tech. I’m passionate about what I do and am looking forward to learning new things and grow professionally. I have a dream to become a successful woman, and this dream keeps me going.

Ellen

How can people be an ally to women in tech?

Start nurturing curiosity at a young age. Encourage the girls and young women in your life to have bold dreams, because that’s the age where kids start conceptualizing what is “possible” and “impossible.” When I was little, I wanted to be an actress or a ballet dancer, but I never dreamed of being a scientist, astronaut, engineer, or inventor. Young people need to hear and see that women totally belong in every sector of public life.

What fuels your passion to keep doing what you do every day?

I’m lucky to have a strong network of family and friends who are my cheerleaders. My community has supported me every step of the way, and so far I’ve had a diverse, and storied career. I’m a career-changer, and my background is primarily in education, so I didn’t find my way into the tech world until recently. My passion comes from knowing who I am, where I come from, and the community that’s helped me along the way.

What are you looking to accomplish with your career in tech?

Build amazing websites and web applications! Make the digital universe a little more accessible with every project I touch. Along the way, I hope to encourage other underrepresented folks in the tech industry to keep chasing their curiosity.

Kris

What would you tell your younger woman-self if you had the chance to give her advice based on what you know now about the tech industry?

Do more research. It’s amazing to see how many companies flourish in the tech industry. I didn't know how well rounded it was until I got into it myself.

How can people be an ally to women in tech?

I feel there is a stigma around women in the tech industry that they aren't as smart or as innovative as a lot of men. I feel that if women were given the chance to prove themselves, that they are willing to improve their skills and show they want to learn and progress, there would be a lot more women in the industry and a lot more women-owned companies.

What fuels your passion to keep doing what you do every day?

My passion to do what I do every day comes from the great people I work with. Not only do they support me and encourage me to expand my knowledge, but they give me opportunities every day. My coworkers, leaders, and bosses all work hard to make this company run smoothly, and I strive to work like them. I want to prove that I am capable of taking on challenges and exceeding expectations. I want to be a better me everyday.

Lindsey

What would you tell your younger woman-self if you had the chance to give her advice based on what you know now about the tech industry?

Confidence from a woman might seem to be threatening, but continue to show your value and stand tall. Make sure the words you use are thoughtfully crafted before raising concerns and contradictions. The strong voice of a woman is often mistaken, so delivery is important. Take the time to think before you react in conflicting situations. 

How can people be an ally to women in tech?

When you see something awry, say something. If a woman confides in you, listen with the intent to help. See us based on our level of experience, not based on our gender. Fight our fights with us, and support our equality in the workplace.

What fuels your passion to keep doing what you do every day?

There are two parts of this for me, the first being the people around me. If it wasn’t for the support system I have inside and outside of the office, it would be much harder to hold my head high in the moments of struggle. 

I also thoroughly enjoy what I do and had the luxury of choice in deciding where my career would take me. Every career path comes with struggles, and being able to work through them and come out with something to show for is very rewarding for me and makes the work even more enjoyable.

Were there struggles in your journey? Do you still face them? How did you push past it?

There have always been struggles. My confidence is quite frequently confused with attitude. Things men often receive praise for, like telling it like it is and not backing down, are things women get reprimanded for. Not letting that defeat me, and keeping my head held high is what helps push past the discrimination. It’s not just men that take offense to it either, other women are often threatened by frequent requests to do better, and be better for all of us. There is a fine line between intimidation and confidence when conversing with women, and its a struggle I face daily and work to eliminate. It's in part learning how receptive people are to certain words, and others being open to strong opinions coming from a variety of people.

Knowing who I am and keeping sight of my worth, not letting other people’s opinions of me think any differently of myself, and knowing that my experiences and education are just as valid and just as those around me are how I stay my course. That confidence that gets "in the way" is also what keeps me going every day.

What About You?

Do you want to share your support for the women around you? It's imperative that we cultivate an environment of acceptance and one where everyone feels welcome. Take a moment to give a special shout-out to a woman in tech, or any woman you know that deserves some recognition.
 

Aug 26 2019
Aug 26

Promet Source is humbled to announce that this summer, two websites that we designed and developed for our clients have won three prestigious awards. 

2019 is the 25th year in which the widely recognized Communicator Awards have recognized “work that transcends innovation and craft” -- work that stands to make a “lasting impact.” The Communicator Awards receive more 6,000 entries and is sanctioned and judged by the Academy of Interactive & Visual Arts, an invitation-only group consisting of industry-leading professionals from media, communications, advertising, creative and marketing firms. AIVA also judges the W3 Awards, and the Davey Awards.  

The American Association of School Librarians’ 2019 Best Websites for Teaching & Learning rankings are peer reviewed and awarded based on the following criteria: innovation, creativity, active participation, collaboration, free to use, user friendliness, and encouraging for a community of learners to explore and discover. 

Awarding Endeavors

At Promet Source, the satisfaction of a job well done and a client whose expectations have been exceeded is the award we seek and the primary driver of creative solutions, collaborative passion, and constant dedication to staying on top of our game. 

Occasionally, though, there’s another level of achievement and recognition -- prestigious awards in which third parties evaluate our work and judge it to be at the leading edge of the rapidly evolving marketing and media landscape.

Both of these award-winning websites represented a labor of love for both Promet Source and our clients. Ready to Code was sponsored by Google and stemmed from a longstanding collaborative effort between the American Library Association and Google. The depth and breadth of resources available on the site are designed to empower librarians to advance computational thinking among children and teens of all backgrounds as an essential component of 21st Century literacy.

The Martin County Florida website served as an opportunity to optimize a utilitarian user experience that streamlined access to the full range of county services, updates, news, and social media connections, while strengthening civic pride with a visually engaging site that leveraged images of the county’s spectacular natural beauty and stunning infrastructural achievements.   

For Martin County, knowledge that their website has received recognition and attention on an international scale has compounded the impact of key objectives: heightened civic pride and greater awareness of a centralized location for conducting all county business.

For the American Library Association Ready to Code site, the recent ranking from the American Association of School Librarians represents a stamp of approval that has served to advance the mission of the site by increasing its credibility and magnifying its objectives, according to Marijke Visser, associate director and senior policy advocate for the American Library Association.

Why Awards Matter

In the rapidly evolving digital landscape, pushing the bounds of possibilities is an essential success factor. Leaning on what passed for innovation last year is the path toward tired solutions that don’t resonate with clients and constituents. That’s why we at Promet Source take awards such as these seriously and are honored to be in the company of agencies that share our dedication.

Ultimately, websites win awards because they work. They are built upon a deep level of inquiry that leads to extreme empathy for what users need and what they are hoping to accomplish when they visit a site. 

Users are bombarded every day with messages, media, and technologies that confuse and get in the way. The websites that win awards offer a surprisingly delightful experience in which extra effort and expertise on the part of designers and developers translates into streamlined simplicity -- a breath of fresh air within a cluttered and complex world.

Interested in the calibre of design and web development that wins awards while driving big-picture goals? Contact us today.

Aug 26 2019
Aug 26

In order to achieve a consistent user experience and interface design, Atomic Design is a great approach.

Atomic Design is not only a budget saver, but also your best friend for future requirements and allows you to fulfill customers wishes quickly and easily. 

The first step is to define the elements that are most in use. This would be, for example, colors, fonts, buttons and images. Starting with these simple elements, different components can be assembled, such as cards or sliders.

Example: Image + Text + Link = Card

Example: Image + Text + Link = Card


The analogy for atomic design is that it is organized along chemical notation, ranging from atoms to molecules to organisms to templates to pages. On each level the components are assembled from smaller components of the lower levels.
 

Chemical notation in 'Atomic Design'

Chemical notation in `Atomic Design`


When we design user experiences (UX) at 1xINTERNET we try to build the best possible user interfaces with the fewest amount of components.

The focus is to create efficiency in the project and to potentially save budget. When fewer components are designed in UX, fewer components need to be programmed and tested. 
 

This approach not only reduces initial efforts considerably but also reduces the cost of the project and its maintenance.


Imagine the following example: You have three different interaction pages and you create a great but different UX for each of those. Then, the users have three different systems to learn. If you instead create an equally good UX by reusing as many components as possible, the user has to learn much less and can interact much faster with your application.

Conclusion

A strict design process and the right integration with the website technology certainly offers efficiency benefits. We plan to write more blog posts on the topic in the next few weeks and are looking forward to your feedback.

Aug 26 2019
Aug 26

Our lead community developer, Alona Oneill, has been sitting in on the latest Drupal Core Initiative meetings and putting together meeting recaps outlining key talking points from each discussion. This article breaks down highlights from meetings this past week. You'll find that the meetings, while also providing updates of completed tasks, are also conversations looking for community member involvement. There are many moving pieces as things are getting ramped up for Drupal 9, so if you see something you think you can provide insights on, we encourage you to get involved.

We've had some gaps in August with limited meetings, so we're happy to be back in the swing of things and reporting a lot of great updates.

Drupal 9 Readiness (08/19/19)

Meetings are for core and contributed project developers as well as people who have integrations and services related to core. Site developers who want to stay in the know to keep up-to-date for the easiest Drupal 9 upgrade of their sites are also welcome.

  • It usually happens every other Monday at 18:00 UTC.
  • It is done over chat.
  • Happens in threads, which you can follow to be notified of new replies even if you don’t comment in the thread. You may also join the meeting later and participate asynchronously!
  • Has a public Drupal 9 Readiness Agenda anyone can add to.
  • The transcript will be exported and posted to the agenda issue.

Symfony development updates

Composer initiative issues affecting D8 and D9

Simpletest deprecation process

The active issue [meta] How to deprecate Simpletest with minimal disruption is one of the biggest deprecations in Drupal 8 while being one of the least trivial to update for, however, work on it is still a priority. 

Composer in Core meeting 08/21/19

  • It usually happens every other Wednesday at 15:30 UTC.
  • It is for contributors to the composer initiative in core who are working on improving drupal's relationship with composer.
  • It is done over chat.
  • Happens in threads, which you can follow to be notified of new replies even if you don’t comment in the thread. You may also join the meeting later and participate asynchronously!
  • Has a public migration meeting agenda anyone can add to.
  • The transcript will be exported and posted to the agenda issue.
  • For anonymous comments, start with a bust in silhouette emoji. To take a comment or thread off the record, start with a no entry sign emoji.

Scaffold files in core

The issue Add core scaffold assets to drupal/core's composer.json extra field is currently waiting on committer attention.

File security component

The issue Add drupal/core-filesecurity component for writing htaccess files has been fixed.

Relocate the scaffold plugin

The issue Relocate Scaffold plugin outside of 'core' directory has also been fixed.

Vendor Hardening Plugin

The issue Add Composer vendor/ hardening plugin to core is ready to be reviewed.

Template files

We have the current template files but still needed are the scaffold files as well as the vendor hardening plugin. Then we will be able to make a template that can be used to make a tarball.

Drupal.org changes to support this

  • Change packaging so that it can package 8.7.x the old way and 8.8.x the new way using composer to create a project.
  • Add a variant of the tool that Webflow uses to generate the drupal/core-pinned-dependencies and drupal/core-development-dependencies into the drupal.org jenkins workflow that publishes those 'somewhere'.

Optionally supporting composer.json for extensions

The issue [PP-3] Provide optional support for using composer.json for dependency metadata still needs work done on it.

Core cross-initiative meeting 8/22/2019

Migrate

Status

  • On 8/21 we discussed the best course of action to resolve.
  • We hoped to deprecate the Drupal 6 migrations and move them to contrib, but we do not have a way to validate how to make deprecations.
  • V Spagnolo has been working on several issues and they are all advancing well.
  • Nathaniel Catchpole shared some criteria for getting into 9.0-beta1.
  • Good progress has been made on multilingual (biggest blocker right now).
  • Multilingual components must land before 9.0-beta1, thankfully the initiative as a whole is pretty stable.

Blockers (Drupal 6 Deprecations)

  • Needs release manager sign-off on the plan to get deprecation made.
  • Plan for moving those elements deprecated into contrib projects.

Next Steps

  • Need release manager criteria for making the multilingual migration stable.
  • Need release manager review on deprecation plan.
    • Need to document it, our target this week.
    • Need sign off on this and what we’ll do next, the target being next week. 
    • Need a way to get deprecated items into contrib. 
      • Are there any dependencies to deprecate items? Do we have to have them in contrib first?

Auto Updates

Status

  • Contrib Alpha-1 was released this week, it includes:
    • Notifying site owners when a public safety announcement has been released by the security team.
      • Optionally this can be done via email, or in a set message on the page (similar to existing alerts).
    • 8 or so readiness checks to determine if your site can be automatically updated.
    • The above features are available in drupal 7 and 8.
    • Signature signed package now on packagist (dev-master), credit to MWDS folks.
      • This will ensure that MITM attacks are not possible because files are known.
      • This is a base that actual automated updates will rely on.
      • Timelines in the initiative update are still accurate.
      • No impact on 8.8, if added they will be new features on the update module.
      • More user-testing is needed for the PSA. We would like it to be in 8, but it could be in contrib in the meantime. The module is future-proofed enough to disable in contrib when it comes time to enable in core.

Blockers

There are currently no blockers.

Next Steps

  • Following the PSA there will be the beta release and user testing.
  • The core release is targetting 8.9?

CMI2

Status

  • The API patch was committed since the last call, it’s in an experimental module.
  • By the 8.8 feature freeze, the UI portion of the module will not yet be ready.
  • This means we can’t release it in core until 9.1.

Blockers

  • Resources are limited, the patch is large, and more people are needed to help with other aspects of the tool (maybe at Drupalcon Amsterdam).
  • The plan requires the release manager review & discussion.

Next Steps

  • Requires sign off for accessibility on WYSIWYG.
  • Two views issues fixed for content moderation.

Drupal 9

Status

Blockers

There are currently no blockers.

Next Steps

Continue working on Symfony4, Drupal 8 not using deprecated API’s and multi-version compatibility Symfony3 requirements to open the Drupal9 branch.

Claro

Status

  • We have made progress to the critical global issues, mini pager, messages, and others are not completed but are looking likely to land. Some specific one-off pages are most at risk.
  • Targeting 8.8 release, but hoping to descope some things to meet this goal.
  • Authoring components still need designs, hoping to get that work done to get into beta for 8.8
  • Roadmap to stabilize Claro.

Blockers

There are two issues the release manager needs to review.

Next Steps

Composer (Much of the information here was covered in the Composer meeting on 8/21)

Status 

  • Moving well, major patches are in which are focused on bells and whistles that will make the experience better.
    • One major patch changed core development workflow there have been no complaints so far (requires composer 1.9 if you’re working w/ 8.8 repo).
  • Scaffolding plan today requires some duplication of some files. It still needs to be confirmed with the core team.
  • Vendor core clean up plugin now strips out all the testing files from the vendor directory and makes sure there is an htaccess file, this is now a vendor hardening plugin. Waiting to be committed.
  • After the scaffolding and vendor hardening plugin are complete we can create a template that will generate a tarball that is composer ready.

Blockers

There are two patches waiting to be committed. 

Next Steps

Demo

Status

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