Drupal Planet

Subscribe to canal de noticias Drupal Planet
Drupal.org - aggregated feeds in category Planet Drupal
Actualizado: hace 1 hora 21 mins

Lullabot: Diving Into The Deep End: Tips for UX Designers When Joining an Ongoing Project

Mié, 12/05/2018 - 19:18

It's never too late to start thinking about user experience design when working on a project. To help ensure the project is a success, it's best to have a UX designer involved in the project as early as possible. However, circumstances may not always be ideal, and User Experience may become an afterthought. Sometimes it isn't until the project is already well on its way when questions around user experience start popping up, and a decision is made to bring in a professional to help craft the necessary solutions. 

What’s the best way for a UX designer to join a project that is well on its way? In this article, we will discuss some actions that UX designers can take to help create a smooth process when joining a project already in progress.

General Onboarding

Planning and implementing an onboarding process can help set the tone for the remainder of the project. If it’s disorganized and not well planned out, you can feel underprepared for the first task, which can lead to a longer design process. It’s helpful to designate a project team member to help with on-boarding. It should be someone who knows the project well and can help answer questions about the project and process. This is usually a product owner or a project manager but isn’t limited to either. If you haven’t been assigned someone to help you with the on-boarding process, reach out to help identify which team member would be best for this role. During the on-boarding process, discuss what user experience issues the team is hoping to solve, and also review the background of significant decisions that were made. This will help you to evaluate the current state of the project as well as the history of the decision-making process. You should also make sure you understand the project goals and the intended audience. Ask for any documentation around usability testing, acceptance criteria, competitive reviews, or notes for meetings that discuss essential features. Don’t be afraid ask questions to help you fully grasp the project itself. And don’t forget to ask why. Sometimes entertaining the mindset of a five-year-old when trying to understand will help you find the answers you’re seeking.

Process Evaluation How you climb a mountain is more important than reaching the top. - Yvon Chouinard

Processes help ensure that the project goes smoothly, is on time, and on budget. They can also be a checkpoint for all those involved.  If a process doesn't already exist that includes UX Design, work together with the team to establish a process to discuss, track and review work. If you feel that a process step is missing or a current system isn't working, speak up and work with the team to revise it. Make sure to include any critical process that the team may be lacking. You also may want to make sure that discussions around any important features include a UX Designer. Ask if there are any product meetings that you should be joining to help give input as early as possible.

Schedule Weekly Design Reviews

One example of improving the process to include UX Design is scheduling weekly meetings to review design work that’s in progress. This also gives project members an opportunity to ask questions and discuss upcoming features and acceptance criteria.

Incorporate Usability Testing

Another suggestion is to include usability tests on a few completed important features before moving ahead. The results of the usability tests may help give direction or answer questions the product team has been struggling with. It can also help prioritize upcoming features or feature changes. The most important thing to remember is that usability testing can help improve the product, so it’s tailored to your specific users, and this should be communicated to the project team.

Collect General User Feedback

Establishing early on the best way to collect and give feedback on a design or feature can help streamline the design process. Should it be written feedback? Or would a meeting work better where everyone can speak up? Sometimes, when multiple people are reviewing and giving feedback, it’s best to appoint one person to collect and aggregate the input before it filters down to you.

Track Project Progress

You also want to discuss the best way to track work in progress. If your team is using an agile process, one idea is to include design tickets in the same software that you’re using to keep track of sprints such as Jira [link] or Trello [link]. Discuss the best way for summarizing features, adding acceptance criteria and tracking input in whatever system you decide to use.

Prioritization of Work Efficiency is doing things right; effectiveness is doing the right things. - Peter Drucker

The team should be clear on priorities when it comes to work, features, and feedback. Joining a team that’s in progress can be very overwhelming to both the designers and stakeholders and creating clear priorities can help set expectations and make it clear to both sides on what the team should focus on first. If a list of priorities doesn't already exist, create one. It doesn't have to be fancy. A simple excel sheet or Google Sheets will do. You can create separate priority lists for things like upcoming features that need design, QA, or user feedback. You can also combine everything into a single list if that works better for your team. Just make sure that it links to or includes as much detail as possible. In the example below, a feature that has completed acceptance criteria is linked to a ticket in Jira that explains all of the details.

undefined

It’s also helpful to group related features together, even though they may have different priorities. This will help you think about how to approach a feature without needing to reworking it later down the line. Be proactive. Ask questions around the priority of items if something doesn't make sense to you. If needed, volunteer to help prioritize features based on what makes sense for a holistic finished product or feature. Creating diagrams and flowcharts can help get everyone to understand how separate features can be connected and what makes the most sense to tackle first. Make sure that QA and user feedback is also part of the priority process.

undefined Summary

Having any team member join a project mid-process can be intimidating for all parties involved, but it’s important to be open and understanding. Improving the process and the end result is in everyone's interest, and giving and accepting feedback with an open mind can play an important role in ensuring that the project runs smoothly for everyone involved.

For User Experience Designers, it’s important to respect what’s already been accomplished and established with the idea that you should tread lightly to make small improvements at first. This will help gain confidence from the team, while also giving you time to learn about the project and understand the decisions that lead up to where it’s at today. For stakeholders involved, it’s important to listen with an open mind and take a small step back to reevaluate the best way to include UX in the process moving forward. The above suggestions can help both parties understand what actions they can take to help make the onboarding process for a UX Designer a smooth transition.

myDropWizard.com: Drupal 6 security update for Password Policy module

Mié, 12/05/2018 - 17:59

As you may know, Drupal 6 has reached End-of-Life (EOL) which means the Drupal Security Team is no longer doing Security Advisories or working on security patches for Drupal 6 core or contrib modules - but the Drupal 6 LTS vendors are and we're one of them!

Today, there is a Less Critical security release for the Password Policy  module to fix a Denial of Service (DoS) vulnerability.

The Password Policy module makes it possible to set constraints on user passwords.

The "digit placement" constraint is vulnerable to Denial of Service attacks if an attacker submits specially crafted passwords.

See the security advisory for Drupal 7 for more information.

Here you can download the Drupal 6 patch.

If you have a Drupal 6 site using the Password Policy module, we recommend you update immediately! We have already deployed the patch for all of our Drupal 6 Long-Term Support clients. :-)

If you'd like all your Drupal 6 modules to receive security updates and have the fixes deployed the same day they're released, please check out our D6LTS plans.

Note: if you use the myDropWizard module (totally free!), you'll be alerted to these and any future security updates, and will be able to use drush to install them (even though they won't necessarily have a release on Drupal.org).

Drupal blog: Drupal's commitment to accessibility

Mié, 12/05/2018 - 17:58

This blog has been re-posted and edited with permission from Dries Buytaert's blog. Please leave your comments on the original post.

Last week, WordPress Tavern picked up my blog post about Drupal 8's upcoming Layout Builder.

While I'm grateful that WordPress Tavern covered Drupal's Layout Builder, it is not surprising that the majority of WordPress Tavern's blog post alludes to the potential challenges with accessibility. After all, Gutenberg's lack of accessibility has been a big topic of debate, and a point of frustration in the WordPress community.

I understand why organizations might be tempted to de-prioritize accessibility. Making a complex web application accessible can be a lot of work, and the pressure to ship early can be high.

In the past, I've been tempted to skip accessibility features myself. I believed that because accessibility features benefited a small group of people only, they could come in a follow-up release.

Today, I've come to believe that accessibility is not something you do for a small group of people. Accessibility is about promoting inclusion. When the product you use daily is accessible, it means that we all get to work with a greater number and a greater variety of colleagues. Accessibility benefits everyone.

As you can see in Drupal's Values and Principles, we are committed to building software that everyone can use. Accessibility should always be a priority. Making capabilities like the Layout Builder accessible is core to Drupal's DNA.

Drupal's Values and Principles translate into our development process, as what we call an accessibility gate, where we set a clearly defined "must-have bar." Prioritizing accessibility also means that we commit to trying to iteratively improve accessibility beyond that minimum over time.

Together with the accessibility maintainers, we jointly agreed that:

  1. Our first priority is WCAG 2.0 AA conformance. This means that in order to be released as a stable system, the Layout Builder must reach Level AA conformance with WCAG. Without WCAG 2.0 AA conformance, we won't release a stable version of Layout Builder.
  2. Our next priority is WCAG 2.1 AA conformance. We're thrilled at the greater inclusion provided by these new guidelines, and will strive to achieve as much of it as we can before release. Because these guidelines are still new (formally approved in June 2018), we won't hold up releasing the stable version of Layout Builder on them, but are committed to implementing them as quickly as we're able to, even if some of the items are after initial release.
  3. While WCAG AAA conformance is not something currently being pursued, there are aspects of AAA that we are discussing adopting in the future. For example, the new 2.1 AAA "Animations from Interactions", which can be framed as an achievable design constraint: anywhere an animation is used, we must ensure designs are understandable/operable for those who cannot or choose not to use animations.

Drupal's commitment to accessibility is one of the things that makes Drupal's upcoming Layout Builder special: it will not only bring tremendous and new capabilities to Drupal, it will also do so without excluding a large portion of current and potential users. We all benefit from that!

Drupal blog: Pilot Program: Help us improve reliability of minor updates

Mié, 12/05/2018 - 16:50

The Drupal Association seeks volunteer organizations from Agency and Drupal site owners running production Drupal 8 sites for the creation of an official minor-release beta-testers program.

Since Drupal 8.0's release in November 2015, the Drupal community has successfully transitioned to a scheduled release process whereby two minor releases are made every year.

The most recent of these releases was Drupal 8.6, released in September 2018.

In a significant change from Drupal 7, these minor releases may contain new features and maintain backwards compatibility. This means that every six months there are new features in Drupal core, instead of waiting for the next major release.

This rapid acceleration in feature development has resulted in the need for greater real-world testing of upgrade paths and backwards compatibility. Drupal core has a vast automated test-suite comprising almost 25,000 tests—however, these can be greatly complemented by real-world testing of production sites. There are an infinite number of ways to put Drupal together that cannot always be handled in automated tests.

In order to improve the reliability of the minor-releases, the Drupal community—in conjunction with the Drupal Association—aims to develop a minor-release beta testers panel comprised of agencies and site-owners who maintain complex Drupal 8 production sites.

Many companies and Drupal users are looking to help with core development but aren't always sure where to start. Membership in this panel presents a new way to help the development of software that powers their website.

Who should apply?

Agencies and site owners who maintain large and complex Drupal 8 production sites. In particular, sites that use a wide range of contributed and custom modules or have large volumes of content.

What is involved?

When the beta release becomes available, the Drupal core committers will work in conjunction with the Drupal Association to contact the members of the beta-testing panel to advise that the next minor release is ready for testing.

Members of the panel will be asked to attempt updating to the beta using a staging version of their site (not straight-on production) and report back any issues found. New issues will be opened to track and resolve reported issues. If a predetermined percentage of the program participants have not yet reported back their results, a decision may be made to delay releasing subsequent beta versions or a release-candidate. Participants whose participation lapses may be removed from the program.

At the moment, testing of the new release occurs in a largely ad-hoc fashion, but once the program is established, this will become more structured and maintainers will have access to statistics regarding the breadth of testing. This will then inform release management decisions in regards to release preparedness.

What's in it for participants?
  • Updating early helps find issues beforehand, rather than after the release is out.

  • Reporting issues encountered lets you tap the wealth of experience of the Drupal core contributors that you'd not have the same level of access to if you update on your own after the release.

  • All organizations and individuals taking part in the testing will receive issue credits for both testing the update and fixing any issues that arise.

  • Satisfaction in the knowledge that you helped shape the next minor release of Drupal core.

  • Advanced preview of upcoming features in Drupal core.

Apply to participate in the program

Community: Values & Principles Committee Update - November 2018

Mié, 12/05/2018 - 10:00

The Values & Principles Committee has formed and has started its work. It has started by looking at Principle 8.

Why are we doing this?

As Dries said, when announcing the first iteration of the Drupal Values & Principles, the Drupal project has had a set of Values & Principles for a very long time. Historically, they were mostly communicated by word of mouth and this meant that some in our community were more aware of them than others.

Writing down the Values & Principles was a great first step. What we need to do now is continually refine the common understanding of these Values & Principles across our whole community and ensure that they are built-in to everything we do.

How will we work?

The Values & Principles are held very closely to the heart of the members of our community and we absolutely recognise that any work on them must be inclusive, clear, structured and accountable.

We are, therefore, going to be open about the work we are doing. While there are members of a committee that will focus on this task, it is not the committee’s job to make decisions “behind closed doors”. Instead, the committee is responsible for enabling the whole community to refine and communicate our common Values & Principles.

We will record actions and progress in the Drupal Governance Project so that all in our community will be able to have the necessary input.

How will we communicate?

We will continue to post updates on the Drupal Community Blog and, as already mentioned, you will always be able to see and, most importantly, participate in issues in the Governance Project. We even have a board on ContribKanban!

Who is on the committee?

Hussain Abbas (hussainweb) works as an Engineering Manager at Axelerant. He started writing programs in 1997 for school competitions and never stopped. His work focus is helping people architect solutions using Drupal and enforcing best practices. He also participates in the local developer community meetup for PHP in general and Drupal in particular. He often speaks at these events and camps in other cities.

Alex Burrows (aburrows), from UK, is the Technical Director of Digidrop and has over 10 years working in Drupal, as well as an avid contributor and a member of the Drupal Community Working Group. As well as this he is a DrupalCamp London Director and Organizer and the author of Drupal 8 Blueprints book.

Jordana Fung (jordana) is a freelance, full-stack Drupal developer from Suriname, a culturally diverse country where the main language is Dutch. She has been steadily increasing her participation in the Drupal community over the past few years and currently has a role on the Drupal Community Working Group. She loves to spend her time learning new things, meeting new people and sharing knowledge and ideas.

Suchi Garg (gargsuchi), living in Melbourne Australia is a Tech Lead at Salsa Digital. She has been a part of the Drupal community for more than 12 years as a site builder, developer, contributor, mentor, speaker and trainer. She had been a part of the Indian community before moving to Australia and is now an active Drupal community down under.

John Kennedy (johnkennedy), lives in Boston, works as a Product Manager for AWS. Over 10 years in Drupal as a site-builder, developer, speaker and on the business side. Co-organiser of Drupal Camp London 2012-2015. PM for Acquia Lightning and the Drupal 8 Module Acceleration Program.

Rachel Lawson (rachel_norfolk), UK and the Community Liaison at the Drupal Association will finally be providing logistical support to the committee and helping wherever she can. Having been in the Drupal community for 11 years as a site builder, a contributor and a mentor, she has had opportunity to experience how the community understands its collective Values & Principles.

In order to be as transparent and forthcoming as possible we wanted to address the fact that there are currently 2 CWG members on the committee. The initial call for people to join the Values & Principles committee happened at the same time as the Community Working Group was calling for new members and, as luck would have it, Alex Burrows applied for both.

In October 2018 a current member of the CWG, Jordana Fung joined the Values & Principles committee and at same time he was being vetted for potential membership to the CWG, Alex joined the Values & Principles committee as well. After the vetting process, Alex officially became a member of the CWG in November. So as it stands now, there are 2 CWG members on the V&P committee.

There are a few possible options going forward, some are:

  • Both CWG members continue for now (whilst the V&P committee is in the very early formation stages) and then possibly:
    • One member drops off
    • They act as a team and only one member (whichever is available) participates in meetings
  • The CWG decides which member is on the VP committee
    • We may need to add another member to the VP committee to take the place of the member that will no longer attend.
So, what’s next?

We have started by compiling a summary of feedback from the community so far that relates to the project’s Values & Principles from such places as the Whitney Hess Interviews, community-led conversations around governance and some anonymized feedback from the Governance Taskforce. We will be adding this summary to an issue in the project.

Call to action

We recognize, though, that what we really want to understand is how you understand what we already have written in Principle 8. THis is how we intend to do that…

The members of the committee have each written stories from their own memories of the Drupal community that demonstrate Principle 8 in action.

We invite you all to write your own stories, from your memories of the Drupal community, other tech communities or indeed any other aspect of life, that demonstrate Principle 8 to you. You should add your story to this issue we have created:

Add my story about Principle 8

One thing we do ask, though, is that you only add your own stories (as many as you like!) and NOT comment or question others’ stories. All stories are valid.

By the end of the year, we hope to have a rich set of stories that show how we, as a global community, interpret Principle 8 and we can then look to see if any changes need to be made to the words or, maybe, it is more a case of linking the Principle to the stories or providing other statements supporting Principle 8.

Kristof De Jaeger: Send me a webmention with Drupal!

Mié, 12/05/2018 - 09:07

After months of reading, experimenting and a lot of coding, I'm happy that the first release candidate of the Drupal IndieWeb module is out. I guess this makes the perfect time to try it out for yourself, no? There are a lot of concepts within the IndieWeb universe, and many are supported by the module. In fact, there are 8 submodules, so it might be daunting to start figuring out which ones to enable and what they exactly allow you to do. To kick start anyone interested, I'll publish a couple of articles detailing how to set up several concepts using the Drupal module. The first one will explain in a few steps how you can send a webmention to this page. Can you mention me?

Step 1: enabling modules

After you downloaded the module and installed the required composer packages, enable following modules: IndieWeb, Webmention and Microformats2. In case you are not authenticated as user 1, also toggle the following permissions: 'Administer IndieWeb configuration' and 'Send webmention'.

Step 2: expose author information

To discover the author of a website after receiving a webmention, your homepage, or the canonical url of a post needs author information. The module comes with an Author block so you can quickly expose a block where you can configure your name. Your real name or nickname is fine, as long as there's something. The minimal markup should look like something like this:

Your name


Note: this can be anywhere in your HTML, even hidden. Step 3: configure webmention module

All configuration exposed by the modules lives under 'Web services' > 'IndieWeb' at /admin/config/services/indieweb. To configure sending webmentions go to /admin/config/services/indieweb/webmention/send. Ignore the ' Syndication targets' fieldset and scroll down to ' Custom URL's for content' and toggle the 'Expose textfield' checkbox.

Scroll down a bit more and configure how you want to send webmentions, either by cron or drush (webmentions are stored in a queue first for performance reasons)

Step 4: configure Microformats module

When sending a webmention to me, it would be nice to be able to figure out what exactly your post is. To achieve this, we need to add markup to the HTML by using CSS classes. Let's configure the minimal markup at /admin/config/services/indieweb/microformats by toggling following checkboxes:

  • h-entry on node wrappers
  • e-content on standard body fields. In case your node type does not use the standard body field, enter the field name in the 'e-content on other textarea fields' textarea.
  • dt-published, p-name, u-author and u-url in a hidden span element on nodes.
Now create a post!

Create a post with a title and body. Your body needs to contain a link with a class so that when I receive your webmention, I know that this page is valid. As an example, we're going to write a reply:

Hi swentel! I just read your article and it's awesome!

Save the post and verify the markup more or less looks like underneath. Make sure you see following classes: h-entry, u-url, p-name, dt-published, e-content, u-author.


 
    
       
          Published on Tue, 04/12/2018 - 22:39
       
       
         
            Test send!
            2018-12-04T22:39:57+01:00
         

         
       
     
     
 
  Hi swentel! I just read your article and it's awesome!
 

If everything looks fine, go to the node form again. Open the 'Publish to' fieldset where you can enter 'https://realize.be/blog/send-me-webmention-drupal' in the custom URL textfield. Save again and check the send list at /admin/content/webmention/send-list. It should tell that there is one item in the queue. As a final step, run cron or the 'indieweb-send-webmentions' drush command. After that the queue should be empty and one entry will be in the send list and I should have received your webmention!

Note: You can vary between the 'u-in-reply-to', 'u-like-of' or 'u-repost-of' class. Basically, the class determines your response type. The first class will create a comment on this post. The other two classes will be a mention in the sidebar.

What's next?

Well, a lot of course. But the next step should be receiving webmentions no? If you go to /admin/config/services/indieweb/webmention, you can enable receiving webmentions by using the built-in endpoint. Make sure you expose the link tag so I know where to mention you!

I tried it, and it didn't work!

Maybe I missed something in the tutorial. Or you have found a bug :) Feel free to ping me on irc.freenode.net on #indieweb-dev or #drupal-contribute. You may also open an issue at https://github.com/swentel/indieweb

Dries Buytaert: Drupal's commitment to accessibility

Mié, 12/05/2018 - 08:56

Last week, WordPress Tavern picked up my blog post about Drupal 8's upcoming Layout Builder.

While I'm grateful that WordPress Tavern covered Drupal's Layout Builder, it is not surprising that the majority of WordPress Tavern's blog post alludes to the potential challenges with accessibility. After all, Gutenberg's lack of accessibility has been a big topic of debate, and a point of frustration in the WordPress community.

I understand why organizations might be tempted to de-prioritize accessibility. Making a complex web application accessible can be a lot of work, and the pressure to ship early can be high.

In the past, I've been tempted to skip accessibility features myself. I believed that because accessibility features benefited a small group of people only, they could come in a follow-up release.

Today, I've come to believe that accessibility is not something you do for a small group of people. Accessibility is about promoting inclusion. When the product you use daily is accessible, it means that we all get to work with a greater number and a greater variety of colleagues. Accessibility benefits everyone.

As you can see in Drupal's Values and Principles, we are committed to building software that everyone can use. Accessibility should always be a priority. Making capabilities like the Layout Builder accessible is core to Drupal's DNA.

Drupal's Values and Principles translate into our development process, as what we call an accessibility gate, where we set a clearly defined "must-have bar". Prioritizing accessibility also means that we commit to trying to iteratively improve accessibility beyond that minimum over time.

Together with the accessibility maintainers, we jointly agreed that:

  1. Our first priority is WCAG 2.0 AA conformance. This means that in order to be released as a stable system, the Layout Builder must reach Level AA conformance with WCAG. Without WCAG 2.0 AA conformance, we won't release a stable version of Layout Builder.
  2. Our next priority is WCAG 2.1 AA conformance. We're thrilled at the greater inclusion provided by these new guidelines, and will strive to achieve as much of it as we can before release. Because these guidelines are still new (formally approved in June 2018), we won't hold up releasing the stable version of Layout Builder on them, but are committed to implementing them as quickly as we're able to, even if some of the items are after initial release.
  3. While WCAG AAA conformance is not something currently being pursued, there are aspects of AAA that we are discussing adopting in the future. For example, the new 2.1 AAA "Animations from Interactions", which can be framed as an achievable design constraint: anywhere an animation is used, we must ensure designs are understandable/operable for those who cannot or choose not to use animations.

Drupal's commitment to accessibility is one of the things that makes Drupal's upcoming Layout Builder special: it will not only bring tremendous and new capabilities to Drupal, it will also do so without excluding a large portion of current and potential users. We all benefit from that!

Kanopi Studios: Kanopi 2019 DrupalCon Seattle Sessions

Mar, 12/04/2018 - 18:29

We are thrilled to have had three of our sessions chosen for DrupalCon Seattle in April 2019. You’ll find us at the booth, in the hallway, and out and about in Seattle, but make sure to visit us in our three Builder Track sessions:

Keep Living the Dream! How to work remotely AND foster a happy, balanced life

Virtual. Remote. Distributed. Pick your label. This style of organization is becoming wildly more in demand and popular among many Drupal shops. While many folks have gone remote, some people find the experience quite isolating and disconnected.

In this session we will talk about how to be the best remote employee, as well as provide ideas if you are a leader of a remote team. We will talk about key tactics to keep you (and all other staff) inspired, creative, productive and most importantly, happy!

Presenter: Anne Stefanyk

Beyond the Screen Reader: Humanizing Accessibility

We talk a lot about the basics of accessibility. But what does it really mean to be accessible? How do we ensure we are including everyone and empowering every user in every scenario to use our sites, products, and devices? We think about deaf and blind users, we check contrast for colorblind users. We consider the elderly and sometimes those with dyslexia. Are we including trans folks? Parents? The chronically ill? People with limited literacy? The injured? People in a major emergency? Who are we designing for? What should we be considering?

If you’re wondering how these folks might be affected by accessibility and you want your website to be inclusive for everyone, this is the session for you.

Presenter: Alanna Burke

Deep Cleaning: Creating franchise model efficiencies with Drupal 8

COIT offers cleaning and 24/7 emergency restoration services. Their 100+ locations serve more than 12 million homes & businesses across the United States and Canada.

It had been years since the COIT site had been updated, and it posed a host of technical challenges. Franchise content optimizations resulted in redundant updates for the SEO team. The mobile experience wasn’t optimized for conversions. There was a mountain of custom technical debt. And despite the current content administrative challenges, the localized experience lacked the level of context-awareness that consumers have come to expect. It was time for COIT to clean up its own mess.

In this case study we will cover the more technical parts of this Drupal 8 implementation: how we kept a multinational but distinctly separate brand presence with geolocative features, maintained custom promotions tailored to each franchise location, and kept the existing hard-won SEO and SEM business drivers intact.

Presenters: Anne Stefanyk and Katherine White

The post Kanopi 2019 DrupalCon Seattle Sessions appeared first on Kanopi Studios.

ComputerMinds.co.uk: Open links in popups with Foundation

Mar, 12/04/2018 - 09:16

Let me take you on a journey. We'll pass by Drupal content renderer services, AJAX commands, javascript libraries and a popular front-end framework. If you've only heard of one or two of those things, come lean on the experience I took diving deep into Drupal. I'm pleased with where my adventure took me to, and maybe what I learned will be useful to you too.

Here's the end result: a contact form, launched from a button link in the site header, with the page beneath obscured by an overlay. The form allows site visitors to get in touch from any page, without leaving what they were looking at.

Drupal has its own API for making links launch dialogs (leveraging jQuery UI Dialogs). But our front-end of the site was built with Foundation, the super-popular theming framework, which provides components of its own that are much better for styling. We often base our bespoke themes on Foundation, and manipulate Drupal to fit.

We had already done some styling of Foundation's Reveal component. In those places, the markup to show in the popup is already in the page, but I didn't really want the form to be in the page until it was needed. Instead, AJAX could fetch it in. So I wondered if I could combine Drupal's AJAX APIs with Foundation's Reveal markup and styling. Come with me down the rabbit hole...

There are quite a few components in making this possible. Here's a diagram:

So it comes down to the following parts, which we'll explore together. Wherever custom code is needed, I've posted it in full later in this article.

  • A link that uses AJAX, with a dialog type set in an attribute.
  • Drupal builds the content of the page that was linked to.
  • Drupal's content view subscriber picks up that response and looks for a content renderer service that matches the dialog type.
  • The content renderer returns an AJAX command PHP class in its response, and attaches a javascript library that will contain a javascript AJAX command (a method).
  • That command returns the content to show in the popup, and that javascript method name.
  • The javascript method launches the popup containing the HTML content.

Let's start at the beginning: the link. Drupal's AJAX API for links is pretty neat. We trigger it with two things:

  1. A use-ajax class, which tells it to open that link via an AJAX call, returning just the main page content (e.g. without headers & footers), to be presented in your existing page.
  2. A data-dialog-type attribute, to instruct how that content should be presented. This can be used for the jQuery UI dialogs (written up elsewhere) or the newer off-canvas sidebar, for example.

I wanted to have a go at creating my own 'dialog type', which would be a Foundation Reveal popup. The HTML fetched by the AJAX call would be shown in it. Let's start with the basic markup I wanted to my link to have:

Enquire

This could either just be part of content, or I could get this into a template using a preprocess function that would build the link. Something like this:

<?php // $url could have come from $node->toUrl(), Url::fromRoute() or similar. // For this example, it's come from a contact form entity. $url->setOption('attributes', [ 'class' => [ 'use-ajax', ], // This attribute tells it to use our kind of dialog 'data-dialog-type' => 'reveal', ]); // The variable 'popup_launcher' is to be used in the template. $variables['popup_launcher'] = \Drupal\Core\Link::fromTextAndUrl(t('Enquire'), $url);

After much reading around and breakpoint debugging to figure it out, I discovered that dialog types are matched up to content rendering services. So I needed to define a new one of those, which I could base closely on Drupal's own DialogRenderer. Here's the definition from my module's mymodule.services.yml file:

services: main_content_renderer.foundation_reveal: class: Drupal\mymodule\Render\MainContent\FoundationReveal arguments: ['@title_resolver'] tags: - { name: render.main_content_renderer, format: drupal_reveal }

Adding the tag named 'render.main_content_renderer' means my class will be picked up by core's MainContentRenderersPass when building the container. Drupal's MainContentViewSubscriber will then consider it as a service that can render responses.

The 'format' part of the tag needs to be the value that our data-dialog-type attribute has, with (somewhat arbitrarily?) 'drupal_' prepended. The arguments will just be whatever the constructor for the class needs. I often write my class first and then go back to adjust the service definition once I know what it needs. But I'll be a good tour guide and show you things in order, rather than shuttling you backwards and forwards!

Onto that FoundationReveal service class now. I started out with a copy of core's own ModalRenderer which is a simple extension to the DialogRenderer class. Ultimately, that renderer is geared around returning an AJAX command (see the AJAX API documentation), which comes down to specifying a command to invoke in the client-side javascript with some parameters.

I would need my own command, and my FoundationReveal renderer would need to specify it to be used. That only two functional differences were needed in comparison to core's DialogRenderer:

  1. Attach a custom library, which would contain the actual javascript command to be invoked:
$main_content['#attached']['library'][] = 'mymodule/dialog.ajax';
  1. Return an AJAX command class, that will specify that javascript command (rather than the OpenDialogCommand command that DialogRenderer uses) - i.e. adding this to the returned $response:
new OpenFoundationRevealCommand('#mymodule-reveal')

We'll learn about that command class later!

So the renderer file, mymodule/src/Render/MainContent/FoundationReveal.php (in that location in order to match the namespace in the service file definition), looks like this - look out for those two tweaks:

<?php namespace Drupal\mymodule\Render\MainContent; use Drupal\Core\Ajax\AjaxResponse; use Drupal\Core\Render\MainContent\DialogRenderer; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\mymodule\Ajax\OpenFoundationRevealCommand; use Symfony\Component\HttpFoundation\Request; /** * Default main content renderer for foundation reveal requests. */ class FoundationReveal extends DialogRenderer { /** * {@inheritdoc} */ public function renderResponse(array $main_content, Request $request, RouteMatchInterface $route_match) { $response = new AjaxResponse(); // First render the main content, because it might provide a title. $content = drupal_render_root($main_content); // Attach the library necessary for using the OpenFoundationRevealCommand // and set the attachments for this Ajax response. $main_content['#attached']['library'][] = 'core/drupal.dialog.ajax'; $main_content['#attached']['library'][] = 'mymodule/dialog.ajax'; $response->setAttachments($main_content['#attached']); // Determine the title: use the title provided by the main content if any, // otherwise get it from the routing information. $title = isset($main_content['#title']) ? $main_content['#title'] : $this->titleResolver->getTitle($request, $route_match->getRouteObject()); // Determine the dialog options and the target for the OpenDialogCommand. $options = $request->request->get('dialogOptions', []); $response->addCommand(new OpenFoundationRevealCommand('#mymodule-reveal', $title, $content, $options)); return $response; } }

That AJAX command class, OpenFoundationRevealCommand sits in mymodule/src/Ajax/OpenFoundationRevealCommand.php. Its render() method is the key, it returns the command which will map to a javascript function, and the actual HTML under 'data'. Here's the code:

<?php namespace Drupal\mymodule\Ajax; use Drupal\Core\Ajax\OpenDialogCommand; use Drupal\Core\StringTranslation\StringTranslationTrait; /** * Defines an AJAX command to open certain content in a foundation reveal popup. * * @ingroup ajax */ class OpenFoundationRevealCommand extends OpenDialogCommand { use StringTranslationTrait; /** * Implements \Drupal\Core\Ajax\CommandInterface:render(). */ public function render() { return [ 'command' => 'openFoundationReveal', 'selector' => $this->selector, 'settings' => $this->settings, 'data' => $this->getRenderedContent(), 'dialogOptions' => $this->dialogOptions, ]; } /** * {@inheritdoc} */ protected function getRenderedContent() { if (empty($this->dialogOptions['title'])) { $title = ''; } else { $title = '' . $this->dialogOptions['title'] . ''; } $button = 't('Close') . '" type="button">×'; return '' . $title . parent::getRenderedContent() . '' . $button; } }

Now, I've mentioned that the command needs to match a javascript function. That means adding some new javascript to the page, which, in Drupal 8, we do by defining a library. My 'mymodule/dialog.ajax' library was attached in the middle of FoundationReveal above. My library file defines what actual javascript file to include - it is mymodule.libraries.yml and looks like this:

dialog.ajax: version: VERSION js: js/dialog.ajax.js: {} dependencies: - core/drupal.dialog.ajax

Then here's that actual mymodule/js/dialog.ajax.js file. It adds the 'openFoundationReveal' method to the prototype of the globally-accessible Drupal.AjaxCommands. That matches the command name returned by my OpenFoundationRevealCommand::render() method that we saw.

(function ($, Drupal) { Drupal.AjaxCommands.prototype.openFoundationReveal = function (ajax, response, status) { if (!response.selector) { return false; } // An element matching the selector will be added to the page if it does not exist yet. var $dialog = $(response.selector); if (!$dialog.length) { // Foundation expects certain things on a Reveal container. $dialog = $('').appendTo('body'); } if (!ajax.wrapper) { ajax.wrapper = $dialog.attr('id'); } // Get the markup inserted into the page. response.command = 'insert'; response.method = 'html'; ajax.commands.insert(ajax, response, status); // The content is ready, now open the dialog! var popup = new Foundation.Reveal($dialog); popup.open(); }; })(jQuery, Drupal);

There we have it - that last bit of the command opens the Foundation Reveal popup dialog!

I should also add that since I was showing a contact form in the popup, I installed the Contact ajax module. This meant that a site visitor would stay within the popup once they submit the form, which meant for a clean user experience.

Thanks for following along with me!

WeKnow: Improving Drupal and Gatsby Integration - The Drupal Modules

Mar, 12/04/2018 - 09:15
Improving Drupal and Gatsby Integration - The Drupal Modules

At weKnow we are not only using Drupal, we also take contributing back very seriously and now is the time for improving the Drupal and Gatsby integration.

As mentioned in my personal blog, Moving weKnow's personal blog sites from Drupal to GatsbyJS, we have been using Gatsby with Drupal for projects as our decouple strategy lately, and after building a few sites with Drupal and Gatsby we found some challenges, which we resolved writing custom code. But now we’ve decided to share our knowledge as contributed modules.

Toast UI Editor

This module provides a markdown WYSIWYG editor integration for Toast UI Editor

jmolivas Tue, 12/04/2018 - 11:15

Web Omelette: Simple Guzzle API mocking for functional testing in Drupal 8

Mar, 12/04/2018 - 06:05

In this article I am going to show you a technique I used recently to mock a relatively simple external service for functional tests in Drupal 8.

Imagine the following scenario: you have an API with one or a few endpoints and you write a service that handles the interaction with it. For example, one of the methods of this service takes an ID and calls the API in order to return the resource for that ID (using the Guzzle service available in Drupal 8). You then cast the Guzzle response stream to a string and return whatever from there to use in your application. How can you test your application with this kind of requirements?

The first thing you can do is unit test your service. In doing so, you can pass to it a mock client that can return whatever you set to it. Guzzle even provides a MockHandler that you can use with the client and specify what you want returned. Fair enough. But what about things like Kernel or Functional tests that need to use your client and make requests to this API? How can you handle this?

It’s not a good idea to use the live API endpoint in your tests for a number of reasons. For example, your testing pipeline would depend on an external, unpredictable service which can go down at any moment. Sure, it’s good to catch when this happens but clearly this is not the way to do it. Or you may have a limited amount of requests you can make to the endpoint. All these test runs will burn through your budget. And let’s not forget you need a network connection to run the tests.

So let’s see an interesting way of doing this using the Guzzle middleware architecture. Before diving into that, however, let’s cover a few theoretical aspects of this process.

Guzzle middlewares

A middleware is a piece of functionality that can be added to the pipeline of a process. For example, the process of turning a request into a response. Check out the StackPHP middlewares for a nice intro to this concept.

In Guzzle, middlewares are used inside the Guzzle handler stack that is responsible for turning a Guzzle request into a response. In this pipeline, middlewares are organised as part of the HandlerStack object which wraps the base handler that does the job, and are used to augment this pipeline. For example, let’s say a Guzzle client uses the base Curl handler to make the request. We can add a middleware to the handler stack to make changes to the outgoing request or to the incoming response. I highly recommend you read the Guzzle documentation on handlers and middlewares for more information.

Guzzle in Drupal 8

Guzzle is the default HTTP client used in Drupal 8 and is exposed as a service (http_client). So whenever we need to make external requests, we just inject that service and we are good to go. This service is instantiated by a ClientFactory that uses the default Guzzle handler stack (with some specific options for Drupal). The handler stack that gets injected into the client is configured by Drupal’s own HandlerStackConfigurator which also registers all the middlewares it finds.

Middlewares can be defined in Drupal as tagged services, with the tag http_client_middleware. There is currently only one available to look at as an example, used for the testing framework: TestHttpClientMiddleware.

Our OMDb (Open Movie Database) Mock

Now that we have an idea about how Guzzle processes a request, let’s see how we can use this to mock requests made to an example API: OMDb.

The client

Let’s assume a module called omdb which has this simple service that interacts with the OMDb API:

<?php namespace Drupal\omdb; use Drupal\Core\Site\Settings; use Drupal\Core\Url; use GuzzleHttp\ClientInterface; /** * Client to interact with the OMDb API. */ class OmdbClient { /** * @var \GuzzleHttp\ClientInterface */ protected $client; /** * Constructor. * * @param \GuzzleHttp\ClientInterface $client */ public function __construct(ClientInterface $client) { $this->client = $client; } /** * Get a movie by ID. * * @param \Drupal\omdb\string $id * * @return \stdClass */ public function getMovie(string $id) { $settings = $this->getSettings(); $url = Url::fromUri($settings['url'], ['query' => ['apiKey' => $settings['key'], 'i' => $id]]); $response = $this->client->get($url->toString()); return json_decode($response->getBody()->__toString()); } /** * Returns the OMDb settings. * * @return array */ protected function getSettings() { return Settings::get('omdb'); } }

We inject the http_client (Guzzle) and have a single method that retrieves a single movie from the API by its ID. Please disregard the complete lack of validation and error handling, I tried to keep things simple and to the point. To note, however, is that the API endpoint and key is stored in the settings.php file under the omdb key of $settings. That is if you want to play around with this example.

So assuming that we have defined this service inside omdb.services.yml as omdb.client and cleared the cache, we can now use this like so:

$client = \Drupal::service('omdb.client'); $movie = $client->getMovie('tt0068646');

Where $movie would become a stdClass representation of the movie The Godfather from the OMDb.

The mock

Now, let’s assume that we use this client to request movies all over the place in our application and we need to write some Kernel tests that verify that functionality, including the use of this movie data. One option we have is to switch out our OmdbClient client service completely as part of the test, with another one that has the same interface but returns whatever we want. This is ok, but it’s tightly connected to that test. Meaning that we cannot use it elsewhere, such as in Behat tests for example.

So let’s explore an alternative way by which we use middlewares to take over any requests made towards the API endpoint and return our own custom responses.

The first thing we need to do is create a test module where our middleware will live. This module will, of course, only be enabled during test runs or any time we want to play around with the mocked data. So the module can be called omdb_tests and we can place it inside the tests/module directory of the omdb module.

Next, inside the namespace of the test module we can create our middleware which looks like this:

<?php namespace Drupal\omdb_tests; use Drupal\Core\Site\Settings; use GuzzleHttp\Promise\FulfilledPromise; use GuzzleHttp\Psr7\Response; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; /** * Guzzle middleware for the OMDb API. */ class OmdbMiddleware { /** * Invoked method that returns a promise. */ public function __invoke() { return function ($handler) { return function (RequestInterface $request, array $options) use ($handler) { $uri = $request->getUri(); $settings = Settings::get('omdb'); // API requests to OMDb. if ($uri->getScheme() . '://' . $uri->getHost() . $uri->getPath() === $settings['url']) { return $this->createPromise($request); } // Otherwise, no intervention. We defer to the handler stack. return $handler($request, $options); }; }; } /** * Creates a promise for the OMDb request. * * @param RequestInterface $request * * @return \GuzzleHttp\Promise\PromiseInterface */ protected function createPromise(RequestInterface $request) { $uri = $request->getUri(); $params = \GuzzleHttp\Psr7\parse_query($uri->getQuery()); $id = $params['i']; $path = drupal_get_path('module', 'omdb_tests') . '/responses/movies'; $json = FALSE; if (file_exists("$path/$id.json")) { $json = file_get_contents("$path/$id.json"); } if ($json === FALSE) { $json = file_get_contents("$path/404.json"); } $response = new Response(200, [], $json); return new FulfilledPromise($response); } }

Before explaining what all this code does, we need to make sure we register this as a tagged service inside our test module:

services: omdb_tests.client_middleware: class: Drupal\omdb_tests\OmdbMiddleware tags: - { name: http_client_middleware }

Guzzle middleware services in Drupal have one single (magic) method called __invoke. This is because the service is treated as a callable. What the middleware needs to do is return a (callable) function which gets as a parameter the next handler from the stack that needs to be called. The returned function then has to return another function that takes the RequestInterface and some options as parameters. At this point, we can modify the request. Lastly, this function needs to make a call to that next handler by passing the RequestInterface and options, which in turn will return a PromiseInterface. Take a look at TestHttpClientMiddleware for an example in which Drupal core tampers with the request headers when Guzzle makes requests during test runs.

So what are we doing here?

We start by defining the first two (callable) functions I mentioned above. In the one which receives the current RequestInterface, we check for the URI of the request to see if it matches the one of our OMDb endpoint. If it doesn’t we simply call the next handler in the stack (which should return a PromiseInterface). If we wanted to alter the response that came back from the next handler(s) in the stack, we could call then() on the PromiseInterface returned by the stack, and pass to it a callback function which receives the ResponseInterface as a parameter. In there we could make the alterations. But alas, we don’t need to do that in our case.

A promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise's eventual value or the reason why the promise cannot be fulfilled.

Read this for more information on what promises are and how they work.

Now for the good stuff. If the request is made to the OMDb endpoint, we create our own PromiseInterface. And very importantly, we do not call the next handler. Meaning that we break out of the handler stack and skip the other middlewares and the base handler. This way we prevent Guzzle from going to the endpoint and instead have it return our own PromiseInterface.

In this example I decided to store a couple of JSON responses for OMDb movies in files located in the responses/movies folder of the test module. In these JSON files, I store actual JSON responses made by the endpoint for given IDs, as well as a catch-all for whenever a missing ID is being requested. And the createPromise() method is responsible for determining which file to load. Depending on your application, you can choose exactly based on what you would like to build the mocked responses.

The loaded JSON is then added to a new Response object that can be directly added to the FulfilledPromise object we return. This tells Guzzle that the process is done, the promise has been fulfilled, and there is a response to return. And that is pretty much it.

Considerations

This is a very simple implementation. The API has many other ways of querying for data and you could extend this to store also lists of movies based on a title keyword search, for example. Anything that serves the needs of the application. Moreover, you can dispatch an event and allow other modules to provide their own resources in JSON format for various types of requests. There are quite a lot of possibilities.

Finally, this approach is useful for “simple” APIs such as this one. Once you need to implement things like Oauth or need the service to call back to your application, some more complex mocking will be needed such as a dedicated library and/or containerised application that mocks the production one. But for many such cases in which we read data from an endpoint, we can go far with this approach.

Code Karate: Drupal 8 Rabbit Hole Module

Mar, 12/04/2018 - 02:03
Episode Number: 221

The Drupal 8 Rabbit Hole Module allows you to control what happens when someone views an entity page. Before you ask why this might be important, let me clarify, it's not a layout tool. It's a simple module that allows you to easily redirect or prevent users from viewing specific types on entities on your site.

Tags: DrupalContribDrupal 8Site BuildingDrupal Planet

DrupalCon News: Community Connection - Kelly Tetterton

Lun, 12/03/2018 - 22:34

We’re featuring some of the people in the Drupalverse! This Q&A series highlights some of the individuals you could meet at DrupalCon. Every year, DrupalCon is the largest gathering of people who belong to this community. To celebrate and take note of what DrupalCon means to them, we’re featuring an array of perspectives and some fun facts to help you get to know your community.

DrupalEasy: DrupalEasy Podcast 212 - Commerce Guys: decoupling and roadmap with Bojan Zivanovic and Matt Glaman

Lun, 12/03/2018 - 21:15

Direct .mp3 file download.

DrupalEasy Podcast 212 - Commerce Guys: decoupling and roadmap

Matt Glaman, (mglaman) and Bojan Zivanovic, (bojanz) join Mike live from Disney World to talk about decoupling Drupal Commerce as well as the roadmap for Drupal Commerce as a project. We take a quick side trip into some blog posts Matt recently wrote about running all of Drupal core's automated tests in DDEV-Local.

Interview DrupalEasy News Upcoming events Sponsors
  • Drupal Aid - Drupal support and maintenance services. Get unlimited support, monthly maintenance, and unlimited small jobs starting at $99/mo.
  • WebEnabled.com - devPanel.
Follow us on Twitter Subscribe

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

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

Jeff Geerling's Blog: Testing the 'Add user' and 'Edit account' forms in Drupal 8 with Behat

Lun, 12/03/2018 - 20:20

On a recent project, I needed to add some behavioral tests to cover the functionality of the Password Policy module. I seem to be a sucker for pain, because often I choose to test the things it seems there's no documentation on—like testing the functionality of the partially-Javascript-powered password fields on the user account forms.

In this case, I was presented with two challenges:

  • I needed to run one scenario where a user edits his/her own password, and must follow the site's configured password policy.
  • I needed to run another scenario where an admin creates a new user account, and must follow the site's configured password policy for the created user's password.

So I came up with the following scenarios:

ThinkShout: Pixel Perfect Project Foundations: Part One of a Series

Lun, 12/03/2018 - 10:00

I used to draw a lot. I never thought of myself as a good artist, but I felt like I had a knack for replicating images, so I turned into a game. I’d say, “let’s see if I can take this small cell from my favorite comic and blow it up into a larger version of itself.” Take this for example:

Alita as drawn by Amy

It came as no surprise to me when I became obsessed with creating responsively pixel perfect websites that represented our talented design team’s work precisely. There was a problem, however. Up until recently front end developers didn’t have a great way to create responsive grids, so we used the tools that we had readily available to us. For example, if you intend to bake chocolate chip cookies with carob, the result is going to be wildly different than if you used chocolate chips! (Carob is never a replacement for chocolate, I don’t care what you say…)

Let’s review our options in the evolutionary order we received them:

  1. Tables: Tables were originally intended for tabular data created through HTML and nothing more.
  2. Floats: Since the web was inspired by print, floats were created to successfully wrap text around images. Floats used with inline elements, and specified widths and gutters, have been used for years to create grids. In addition, all browsers support floats. The problem, however, is they can be complex, prone to break, and often contain tricky clearing and nth item margin removal between responsive breakpoints. In other words, it’s a lot of work.
  3. Flexbox: As browsers became more supportive of flexbox, many of us got tremendously excited. Flexbox was designed with rows and columns in mind, including created elements within rows and columns that have equal heights and widths. Vertical centering has never been easier, but that’s a whole other blog post. Flex-wrap made it possible for front end devs to create grids using flexbox, so we kissed floated grids goodbye.
  4. Grid Layout: Low and behold, a CSS solution made with grid styling in mind - finally! As soon as this became widely browser compatible, I jumped at the opportunity to add this to a brand new project implementation.

First things first… after being part of a handful of new site builds from start to finish, it quickly became apparent how important establishing global site containers were at the foundational level. That’s when I created this visual guide:

  • The Full Screen width is as far as the screen allows. This assumes the site could stretch to infinity, if we had a screen that would allow for that. But we don’t. So, the site boundaries need to be established to something more reasonable.
  • The Site Max Width limits how wide the website itself is willing to stretch. In the instance I’ll be talking about, a width of 3000px was set on the <body> tag and centered using margin-left: auto; and margin-right: auto;. Full-site width elements would live here including but not limited to background images that stretch the full width of the site.
  • The Content Side Padding always exists, regardless of device. It creates left/right spacing in between elements we don’t want touching the very edge of the screen, and the edge of screen itself. An example of this would be text elements.
  • The Grid area is where design-determined columns start and end. Designers typically imagine 12-columns when crafting websites, though the total columns can vary. Planning the full grid area pixel width with a designer right at the beginning is crucial for creating precisely planned grid walls, and perfectly centered elements. Grid Layout also makes creating sidebars super easy to create and maintain as well.

In order to make Grid Layout compatible with IE, it was necessary to add a polyfill to the project. We’re using npm, so a dependency was added like so to the package.json file, and npm update was run to update the package-lock.json file.

Next up, create the grid:

You’re going to see a lot of Sass variables in these code examples, so this might provide a bit of context. (Note: This is a simplified version. This project in particular has 4 grid columns on mobile, and 16 on extra large screens. There were a number of media queries needed to be taken into account too):

After creating the global grid, it dawned on me that I could create a visual grid fairly easily so my team and I could check our work against the exact line assignments. The idea came to me after I saw my teammate, Marlene, apply a Neat (of Bourbon and Neat CSS libraries) visual-grid to a previous project. So, I added a bit of markup to the html.html.twig template:

My tech lead, Maria, loved the idea so she came up with a quick way for us to see the visual grid using a preprocess hook in the .theme file. All the team needed to do was apply ?show-grid=1 to the end of any of the site’s urls to check our work and see if it lined up:

Of course, it had to inherit the overall .grid properties (code shown above), in addition to containing its own unique styling, in order to superimpose the visual grid over the top of the entire page.

The visual grid looked like this when we were working on our project:

Given that applying CSS Grid Layout to a project was a new experience for me and my team, a couple things needed to happen:

  • Create documentation
  • Meet with the team to explain how I’ve setup the project,
  • Encourage innovation and communication, and
  • Go over the documentation
  • Encourage updates to the documentation when new tools have been created, and report back to the rest of the team

It was important for the team to know my intentions for applying the horizontal containers and the use of CSS Grid Layout, and to admit that this is new territory and I was relying on all of us to be on the same page, applying the tools in the same way, and finding ways to make our jobs easier and more efficient.

Initially, we started using CSS Grid Layout for specifically layout purposes of an element’s parent wrapper. We are all well versed in Flexbox now, so we applied Flexbox on the child element rows like so:

Later, I discovered a way to generically place child elements into a grid parent without needing to assign each child element a place inside the grid. Check out my Codepen example to see how this might work.

Many of the elements on the site needed grid to be applied first. However these elements needed to be centered as well, like the elements in the screenshot above. CSS Grid Layout comes with a property grid-column that takes two arguments: 1. a start column and 2. an end column. It needed to be IE compatible, so I whipped up this little mixin:

It took my team some acclimating to enter start and end column values for every element in every breakpoint necessary. Admittedly, it was a bit of a mind-bender at times. This especially took some getting used to since applying grid to a parent element will render all its children into a single column out of the box. It wasn’t long before this grid centering code appeared in the project, thanks to innovative thinking from Maria, Marlene, and Jules:

With that, a themer simply enters how many columns the centered element is wide and how many columns exist on the grid at that breakpoint. Voila, centered grid elements in no time flat!

I could go on and on, there’s so much to share. Though designs may have adjusted slightly over the course of the project, the layout and overall elements largely stayed the same. My ultimate goal was to create an exact replication of our designer, Vicki’s, beautiful work. But, I couldn’t do this all by myself. I needed my teammates to be on the same page. And, that they were! Here’s an example of a page I did very little work on. This is also an example of using CSS Grid Layout with a sidebar element with a 12-column across element in the middle of listing items that needed to be placed in fewer columns. One of these screenshots is the design and one is the live site. Can you tell which is which?

This whole experience truly was a team effort. The code snippets I’ve shared with you did not look like that at the beginning. They evolved overtime, and have grown much more beyond the foundation I originally envisioned. To my surprise, my team got so excited about these tools of precision that they helped produce robust mixins, setting global spacing variables. Say our designer wants to change the gutter from 16px to 20px. No problem, change the $grid-gutter variable and all of the elements across the site just fall in line. No more changing every spacing instance of every element across the site. Goodbye frustration, hello efficiency and perfection!

So, if you find you’re as obsessed as I am with creating a pixel perfect responsive experience for your websites, or if you simply want to start using CSS Grid Layout with purpose in your next project, please feel free to adapt these tools into your practice.

Thanks for taking this journey with me, and I hope you look forward to the next blog posts of this series where my teammates discuss other problems we solved in this implementation. Isn’t nerding out with other passionate people the best?!

OpenSense Labs: Architecting your own Drupal site with Layout Builder

Sáb, 12/01/2018 - 00:37
Architecting your own Drupal site with Layout Builder Shankar Sat, 12/01/2018 - 08:07

Having a routine of reading newspaper early in the morning is an intricate tapestry. We need something more to continue with our engagement with a newspaper day after day as we aren’t vessels of information. And that elusive thing is not just the pleasure of words but an engrossing design. So, when the editors make the prose readable, graphic designers work on creating templates that help in sustaining our interest in the act of reading.


Similarly, site builders and content authors require intuitive tools as well for developing pages, alter layouts and add or arrange blocks with live preview. Hence, when it comes to new and refreshing easy-to-use page builders, An ambitious visual design tool called Layout Builder is on its way to change things completely.

Layout Initiative: The inception

Layout Builder took its birth through Layout Initiative which was started with the objectives of:

  • Underlying APIs for supporting layout management to be utilised by core and contributed projects alike.
  • Offering a drag and drop interface for building layouts that can apply both to overall site sections and overridden on separate landing pages.
  • Allowing the layout application to data entry forms and content

Layouts have been a significant tool in component-based theming as they can be utilised to map data to component templates. In Drupal 8.3, the Layout API and the Layout Discovery module were included as an experimental subsystem. They were stabilised in Drupal 8.4.

Layout Builder is being planned to be stabilised in Drupal 8.7

The Layout API and the Layout Discovery module were added in Drupal 8.3 as an experimental subsystem, and they were stabilized in Drupal 8.4. An experimental Layout Builder module was included in Drupal 8.5 and is being planned to be stabilised in Drupal 8.7.

Layout Builder: A guile approach to site building

Layout Builder offers the ability to customise the layout of your content where you start by choosing predefined layouts for different sections of the page and then populate those layouts with one or more blocks. That is, it gives you a UI with a visual preview and supports using multiple layouts together. It lets you place blocks in layout regions and create layouts for separate pieces of content.

Layout Builder gives you a UI with a visual preview and supports using multiple layouts together.


At present, there are some Drupal modules that can enable the functionality of Layout Builder. The combination of Panels and Panelizer can help in developing templated layouts and landing pages. Also, the Paragraphs module can be used for the creation of custom landing pages.

The greatness of the Layout Builder

Following are some of the reasons that show how great the Layout Builder is:

Source: Dries Buytaert’s blog
  • To lay out all the instances of a specific content type, Layout Builder helps in creating layout templates.
  • Layout Builder allows you to customise these layout templates. You can override these layout templates on a case-by-case basis.
  • It can be utilised to create custom pages. You can create custom, one-off landing pages that are not linked to a content type or structured content.
  • The key to stabilise Layout Builder is to make sure that it passes Drupal’s accessibility gate (Level AA conformance with WCAG and ATAG). So, it will ensure web accessibility standards once stabilised in Drupal 8.7.
  • The Menu Item Extras module is used in Drupal 8 for implementing mega menus through additional fields. In Drupal 8.6, all you need to do for creating a mega menu is to enable Layout Builder for the default menu item view display mode.
How to work around with Layout Builder?

Follow the following steps to use the Layout Builder for configuring content types and nodes:

1. In the first step, you start by enabling the Layout Builder module.

Source: OSTraining

2. This is followed by content creation. This requires the installation of Devel module where you enable Devel and Devel generate parts of the plugin. This, then, helps in generating articles.

Source: OSTraining

3. Then, the layout of the article content type is configured.

Source: OSTraining

4. Finally, the layout of a single node is configured.

Source: OSTrainingConclusion

There is no doubt that Drupal’s current site building and content authoring capabilities are great. But Layout Builder will transform the whole experience of creating pages with its simple and intuitive tools.

Opensense Labs has been offering a suite of services to help organisations lead their ambitious plans of digital transformation.

Contact us at hello@opensenselabs.com to dive into the world of Layout Builder and get the best out of it.

blog banner blog image Layout Builder Website layout Drupal Layout Drupal module Drupal 8 Blog Type Articles Is it a good read ? On

Spinning Code: Waterfall-like Agile-ish Projects

Vie, 11/30/2018 - 20:38

In software just about all project management methodologies get labeled one of two things: Agile or Waterfall. There are formal definitions of both labels, but in practice few companies stick to those definitions particularly in the world of consulting. For people who really care about such things, there are actually many more methodologies out there but largely for marketing reasons we call any process that’s linear in nature Waterfall, and any that is iterative we call Agile.

Failure within project teams leading to disasters is so common and basic that not only is there a cartoon about it but there is a web site dedicated to generating your own versions of that cartoon (http://projectcartoon.com/).

Among consultants I have rarely seen a company that is truly 100% agile or 100% waterfall. In fact I’ve rarely seen a shop that’s close enough to the formal structures of those methodologies to really accurately claim to be one or the other. Nearly all consultancies are some kind of blent of a linear process with stages (sometimes called “a waterfall phase” or “a planning phase”) followed by an iterative process with lots of non-developer input into partially completed features (often called an “agile phase” or “build phase”). Depending on the agency they might cut up the planning into the start of each sprint or they might move it all to the beginning as a separate project phase. Done well it can allow you to merge the highly complex needs of an organization with the predefined structures of an existing platform. Done poorly it can it look like you tried to force a square peg into a round hole. You can see evidence of this around the internet in the articles trying to help you pick a methodology and in the variations on Agile that have been attempted to try to adapt the process to the reality many consultants face.

In 2001 the Agile Manifesto changed how we talk about project management. It challenged standing doctrine about how software development should be done and moved away from trying to mirror manufacturing processes. As the methodology around agile evolved, and proved itself impressively effective for certain projects, it drew adherents and advocates who preach Agile and Scrum structures as rigid rules to be followed. Meanwhile older project methodologies were largely relabeled “Waterfall” and dragged through the mud as out of date and likely to lead to project failure.

But after all this time Agile hasn’t actually won as the only truly useful process because it doesn’t actually work for all projects and all project teams. Particularly among consulting agencies that work on complex platforms like Drupal and Salesforce, you find that regardless of the label the company uses they probably have a mix linear planning with iterative development – or they fail a lot.

Agile works best when you start from scratch and you have a talented team trying to solve a unique problem. Anytime you are building on a mature software platform you are at least a few hundred thousand hours into development before you have your first meeting. These platforms have large feature sets that deliver lots of the functionality needed for most projects just through careful planning and basic configuration – that’s the whole point of using them. So on any enterprise scale data system you have to do a great deal of planning before you start creating the finished product.

If you don’t plan ahead enough to have a generalized, but complete, picture of what you’re building you will discover very large gaps after far too many pieces have been built to ellagently close them, or your solution will have been built far more generically than needed – introducing significant complexity for very little gain. I’ve seen people re-implement features of Drupal within other features of Drupal just to deal with changing requirements or because a major feature was skipped in planning. So those early planning stages are important, but they also need to leave space for new insights into how best to meet the client’s need and discovery of true errors after the planning stage is complete.

Once you have a good plan the team can start to build. But you cannot simply hand a developer the design and say “do this” because your “this” is only as perfect as you are and your plan does not cover all the details. The developer will see things missed during planning, or have questions that everyone else knows but you didn’t think to write down (and if you wrote down every answer to every possible question, you wrote a document no one bothered to actually read). The team needs to implement part of the solution, check with the client to make sure it’s right, adjust to mistakes, and repeat – a very agile-like process that makes waterfall purists uncomfortable because it means the plan they are working from will change.

In all this you also have a client to keep happy and help make successful – that’s why they hired someone in the first place. Giving them a plan that shows you know what they want they are reassured early in the project that you share their vision for a final solution. Being able to see that plan come together while giving chances to refine the details allows your to deliver the best product you are able.

Agile was supposed to fix all our problems, but didn’t. The methodologies used before were supposed to prevent all the problems that agile was trying to fix, but didn’t. But using waterfall-like planning at the start of your project with agile-ish implementation you can combine the best of both approaches giving you the best chances for success.  We all do it, it is about time we all admit it is what we do.

Cartoon from CommitStrip

Dries Buytaert: How NBC Sports supports the biggest media events online

Vie, 11/30/2018 - 13:08

Many of Acquia's customers have hundreds or even thousands of sites, which vary in terms of scale, functionality, longevity and complexity.

One thing that is very unique about Acquia is that we can help organizations scale from small to extremely large, one to many, and coupled to decoupled. This scalability and flexibility is quite unique, and allows organizations to standardize on a single web platform. Standardizing on a single web platform not only removes the complexity from having to manage dozens of different technology stacks and teams, but also enables organizations to innovate faster.

A great example is NBC Sports Digital. Not only does NBC Sports Digital have to manage dozens of sites across 30,000 sporting events each year, but it also has some of the most trafficked sites in the world.

In 2018, Acquia supported NBC Sports Digital as it provided fans with unparalleled coverage of Super Bowl LII, the Pyeongchang Winter Games and the 2018 World Cup. As quoted in NBC Sport's press release, NBC Sports Digital streamed more than 4.37 billion live minutes of video, served 93 million unique users, and delivered 721 million minutes of desktop video streamed. These are some of the highest trafficked events in the history of the web, and I'm very proud that they are powered by Drupal and Acquia.

To learn more about how Acquia helps NBC Sports Digital deliver more than 10,000 sporting events every year, watch my conversation with Eric Black, CTO of NBC Sports Digital, in the video below:

Not every organization gets to entertain 100 million viewers around the world, but every business has its own World Cup. Whether it's Black Friday, Mother's Day, a new product launch or breaking news, we offer our customers the tools and services necessary to optimize efficiency and provide flexibility at any scale.

OpenSense Labs: Extract the power of Predictive UX with Drupal

Vie, 11/30/2018 - 04:54
Extract the power of Predictive UX with Drupal Shankar Fri, 11/30/2018 - 12:24

Perhaps it is not very surprising that in an age of austerity and a climate of fear about child abuse, new technology is being sought by social workers for help. The Guardian, news media, revealed that local authorities in the UK have been using machine learning and predictive modelling to intervene before children were referred to social services. For instance, local councils are building ‘predictive analytics’ systems for leveraging cornucopia of data on hundreds of people for constructing computer models in an effort to predict child abuse and intervene before it can happen.


Power of predictive analytics can be extracted not only for social issues like child abuse but for a superabundance of areas in different industries. One such area is the web user experience where implementation of predictive analytics can be very essential. Predictive user experience (UX) can help usher in a plenitude of betterment. But how did predictive analytics came into being?

Destination 1689

Contemporary Analysis states that the history of predictive analytics takes us back to 1689. While the rise of predictive analytics has been attributed to technological advances like Hadoop and MapReduce, it has been in use for centuries.

One of the first applications of predictive analytics can be witnessed in the times when shipping and trade were prominent.

One of the first applications of predictive analytics can be witnessed in the times when shipping and trade were prominent. Lloyd’s of London, one of the first insurance and reinsurance markets, was a catalyst for the distribution of important information required for underwriting. And the name underwriting itself took birth from London insurance market. In exchange for a premium, bankers would accept the risk on a given sea voyage and write their names underneath the risk information that is written on one Lloyd’s slip developed for this purpose.

Lloyd’s coffee house was established in 1689 by Edward Lloyd. He was well-known among the sailors, merchants and ship owners as he shared reliable shipping news which helped in discussing deals including insurance.

Technological advancements in the 20th century and 21st century have given impetus to predictive analytics as can be seen through the following compilation by FICO.

Source: FICOPredictive Analytics and User Experience: A Detailed Look

IBM states that predictive analytics brings together advanced analytics capabilities comprising of ad-hoc analysis, predictive modelling, data mining, text analytics, optimisation, real-time scoring and machine learning. Enterprises can utilise these tools in order to discover patterns in data and forecast events.

Predictive Analytics is a form of advanced analytics which examines data or content to answer the question “What is going to happen?” or more precisely, “What is likely to happen?”, and is characterized by techniques such as regression analysis, forecasting, multivariate statistics, pattern matching, predictive modelling, and forecasting. - Gartner

A statistical representation of data compiled by Statista delineates that predictive analytics is only going to grow and its market share will keep expanding in the coming years.

Predictive analytics revenues/market size worldwide, from 2016 to 2022 (in billion U.S. dollars) | Statista

A Personalisation Pulse Check report from Accenture found that 65% of customers were more likely to shop at a store or online business that sent relevant and personalized promotions. So, instead of resulting in alterations to the user interface, applying a predictive analytics algorithm to UX design presents the users with relevant information. For instance, a user who has recently bought a costly mobile phone from an e-commerce site might be willing to buy a cover to protect it from dust and scratches. Hence, that user would receive a recommendation to purchase a cover. The e-commerce site might also recommend other accessories like headphones, memory cards or antivirus software.

How does Predictive Analytics Work?

Following are the capabilities of predictive analytics according to a compilation by IBM:

  • Statistical analysis and visualisation: It addresses the overall analytical process including planning, data collection, analysis, reporting and deployment.
  • Predictive modelling: It leverages the power of model-building, evaluation and automation capabilities.
  • Linear regression: Linear regression analysis helps in predicting the value of a variable on the basis of the value of another variable.
  • Logistic regression: It is also known as the logit model which is used for predictive analytics and modelling and is also utilised for application in machine learning.
Leveraging Predictive Models in UX Design

Data will drive the UX in the future. Patterns that derive data make for a terrific predictive engine. This helps in forecasting a user’s intent by compiling numerous predictors that together influence conversions.

Data will drive the UX in the future

With the help of predictive analytics in UX design, conversation rates can be improved. For instance, recommendation systems leverage data such as consumer interest and purchasing behaviour which is then applied via a predictive model for generating a listicle of recommended items. 

Amazon, e-commerce giant, utilises an item-item collaborative filtering algorithm for suggesting products. This helps in displaying the books to a bookworm and baby toys to a new mother. Quantum Interface, which is a startup in Austin Texas, has built a predictive user interface with the help of natural user interface (NUI) principles. This utilises the directional vectors - speed, time and angle change - for forecasting user’s intent.

Implementing Predictive UX with Drupal

Predictive UX adapts content based on a user’s previous choices just like web personalisation does. But predictive UX extracts the power of machine learning and statistical techniques for making informed decisions on the user’s behalf.

While modern technology is oscillating from mobile-first to AI-first, predictive UX is the next huge thing which is going to be a trend-setter. It is meritorious as it helps users reduce the cognitive load because coercing users to make too many decisions will propel them to take the easy way out.

Drupal provides different ways of implementing predictive UX:

Acquia Lift

Acquia Lift Connector, a Drupal module, offers integration with the Acquia Lift service and an improved user experience for web personalisation, testing and targeting directly on the front end of your website.

It leverages machine learning to automatically recommend content based on what a user is currently looking at or has looked in the past. It has a drag-and-drop feature for developing, previewing and launching personalisations and has a customer data repository for providing a single view of customers.

It has the feature of real-time adaptive targeting that refines segments while A/B helps in keeping the users engrossed with the content that resonates.

ApachePrediction IO

Bay Area Drupal Camp 2018 has a session where a demonstration showed how predictive UX helps users decide. It was geared towards both UX designers and developers. It talked about how machine learning powers predictive UX and the ways of implementing it using Drupal.
 


It exhibited a Drupal 8 site which had a list of restaurants that could be sorted by proximity. That means you can check out the nearest restaurant and order food. When users log in to this site, they see top recommendations customised to them.

There are some interesting things happening behind-the-scenes to show the recommendations. An API query is being sent to the machine learning server which, in return, shows a ranked list of recommendations. So, when users go to a restaurant and order food, all that data is sent to the event server through the API which is how data is being collected. Here, the Apache PredictionIO server, which is an open source machine learning stack, offers simple commands to train and deploy engine.

Gazing into the future of UX

UX Collective says that the future of UX is effulgent in the coming years. Demand for pixel perfect usable and delightful UX is sky-high especially when digital transformation endeavours underway globally. Following graphical representation shows the top design-driven organisations against all of Standard and Poor’s (S&P) index.

Source: Job Trends Report: The Job Market for UX/UI Designers

It further states that UX design will consist of more formal studies:

  • Study of cognitive neuroscience and human behaviour
  • Study of ethics
  • Artificial Intelligence advances, generated and unsupervised machine learning-based system interactions, predictive UX, personalised robotic services and so on
Conclusion

User experience will always be an integral component of any sector in any industry. While web personalisation is a sure-shot way of improving digital web experience, disrupting technologies like machine learning take it to another level. Leveraging machine learning algorithms, predictive UX can forecast user choices and help them decide. Implementing predictive UX is a praiseworthy solution to offer users an unprecedented digital experience.

When it comes to Drupal development, OpenSense Labs has been making steadfast in its objectives of embracing innovative technologies that can be implemented with Drupal’s robust framework.

Contact us at hello@opensenselabs.com to implement predictive UX with Drupal.

blog banner blog image Predictive UX Drupal 8 Machine Learning Predictive Analytics Predictive Modelling User Experience Web user experience Digital user experience Customer experience UX web personalisation Blog Type Articles Is it a good read ? On

Páginas