Planet Drupal

Syndicate content
Drupal.org - aggregated feeds in category Planet Drupal
Updated: 42 min 37 sec ago

Chromatic: Announce Your Organization’s Drupal.org Statistics In Slack

Tue, 05/26/2020 - 20:19

As longtime members of the Drupal community, Chromatic strives to contribute whenever we can. Some of those contributions are monetary, such as with the ongoing Drupal Cares campaign, but others involve activity directly on drupal.org, including creating/testing patches, maintaining projects, and submitting case studies. For organizations that list themselves in the Drupal Marketplace, these statistics are all inputs into a formula whose output is your organization’s rank on the marketplace pages.

Tag1 Consulting: The best-kept secrets of headless Drupal - part 1

Tue, 05/26/2020 - 16:49

Now that decoupled Drupal has permeated the Drupal community, even to the furthest extremes, articles (including my own) introducing concepts and how-to tutorials describing how you can build your first decoupled Drupal architecture are ubiquitous. As a matter of fact, decoupled Drupal now also has a book on the subject as well as an annual conference dedicated to the topic. Particularly with the JSON:API module in Drupal core as of 8.7.0, decoupled Drupal out of the box has never been easier.

Read more preston Tue, 05/26/2020 - 08:50

DrupalCon News: How are you including Drupal strategically in your digital transformation?_MJ

Tue, 05/26/2020 - 16:11

Day 2, Keynote - Monique J. Morrow - DrupalCon Vienna 2017. Photo by Dominik Kiss

Acro Media: What It Costs to Build an Ecommerce Site

Tue, 05/26/2020 - 16:00

Many costs are associated with developing a new ecommerce site or migrating from an antiquated setup to an upgraded version. And unless you work in the thick of ecommerce development every day, you likely don't know what questions to ask to ensure you’re getting the full picture.

This article explains what your typical expenses will look like and makes a few suggestions about how to approach budgeting for this undertaking.

Open Source vs. SaaS: A Comparison of Costs

You need to decide whether you will go with open source or a Software-as-a-Service (SaaS) platform to power your site. The cost of doing business is very different with each model.

An open source ecommerce framework has the expenses front-loaded. You pay for development time and configuration costs, and then the final product is yours to own and manage—license-free. 

A SaaS approach is quicker to get live and has lower costs up front. But then you pay an annual license fee and give a percentage of your revenue to the platform with each transaction made. 

Start by doing some easy math. Calculate three percent of your average annual sales. With an SaaS approach, if you sell $50 million online each year, you'll pay $1.5 million in revenue share (on top of licensing fees). If that is an acceptable cost of doing business and allows you to “set it and forget it," then SaaS is likely the right way to go for you.

But if you're a business that needs or wants more control of the front- and back-end experiences, you can use that three percent as a starting point to decide how to shape and invest in your online architecture. With open source software, you’d invest this money up front in year one. In years two and beyond, expenses taper down to about 15 percent of this initial investment annually to keep operational. 

Complete this exercise in relation to your own revenue and figure out what your working budget would be to get started. If three percent leaves you with peanuts, I’d suggest searching out a DIY platform-first ecommerce tool and seeking the help of an independent contractor to start generating revenue online. Your year-one investment may look closer to 50 percent of your annual online revenue to get where you need to be. 

Try to avoid thinking of this as an expense. Instead, think of how much money you’re going to spend to get a return on investment. How long will it take you to earn that ROI? Are these expectations realistic?

How to Budget for an Open Source eCommerce Architecture

Moving from an existing platform (typically SaaS or home-brew) over to a fully open source, headless ecommerce architecture setup incurs costs like:

Planning

Planning is the backbone of a successful ecommerce development project. If you don’t spend the time and money to work out that foundational blueprint, you will get a half-assed outcome that will likely cost more than you were initially promised.

On average, the planning processes for building a substantial ecommerce site for businesses that generate $50 million or more in revenue take 10 weeks of work and cost about $50,000. 

Planning is the absolute MUST-DO on your list. If you skip it, you may save $50,000, but your project will spend it on the other end trying to figure out who meant what because you flew cheap and blind. 

Ask if your proposed agency completes the following activities in their planning phase: 

  • Visualization / live prototyping 
  • Conversion planning, persona development, user journeys 
  • API integration planning, platform and integration reviews and selections 
  • ERP / product mapping 
  • Server and dev ops planning, security, performance and scalability planning

If you’re being pitched the above list, and you can see working past examples of blueprints such as these, then you’re spending your money wisely and you have a shot at getting this project right the first time. 

TIP: This plan should be detailed enough that you can either take it and build out your new site in its entirety with your on-staff tech team, or take it to ANY agency and have a crystal-clear spec for execution. 

Planning is not conceptual. It is a fully operational blueprint that the engineers have stamped and approved. This is a one time cost and the most essential ingredient in your budget. 

If you can only afford to get through planning in year one, make it a priority and wait for the next round of capital expenditure funding to implement it.  

Creative Design

Designing a new eComm site is the fun part. This phase of the project should be done after planning is fully signed off on. That’s because planning allows ideas to flow and evolve. And changes in functionality dictate front-end experiences. 

Your design phase will vary in price depending on what you want to see mocked up versus just built by the team without your input. Set aside $25,000 to $45,000 to make sure your creative phase reflects the quality of your business accurately. This is a one-time cost.

Here are a few tips to ensure that you’re spending your money wisely:

  • Beware of agencies that propose mockups for 30 pages within your new ecommerce site. This is a waste, a cash grab, and a sign of an inexperienced development team.  
  • Limit mockups to the home page, catalog landing page, product details page, and a general content page. However, if you have some funky options in your cart and/or checkout process, design them, too. 
  • Don’t bother fully mocking up creative designs for responsive options. If you’re dead set on seeing the mobile experience, start with the homepage on phone only and evaluate from there. 
  • Don’t waste time or money creating full mockups for each page. You can always add more designs as you go, if needed, or designers can provide elements to improve designs on single pages.
  • Complete and approve the home page design fully first before moving onto any “internal” templates. You don’t want rework across multiple designs. 
  • Use a web design agency, not a design agency. There are specifics for designing to web standards that don’t apply to companies that deal in logos, brands, and print work.
Sprinting / Development

Your project team should work with you to break your planning into stories, block these stories into epics, and group these epics into sprints. You’ll then have an idea of how many sprints you’ll need to get live.

Typical costs for sprinting range from $20,000 to $60,000 a month for the lifetime of the build cycle, which is usually six to 12 months. After this investment, you have a feature-rich ecommerce setup to push live. (Remember: These expenses are front-loaded. After this one-time cost, you own the site and don’t have to pay licensing fees or share your revenue).

Sprinting costs depend on velocity. That is, how many bodies can we afford to put on this development until the sprints are done? If you have $20,000 a month to spend for six months, you’ll get through $120,000 worth of programming or about 600 hours (give or take per agency).

That’s a decent amount of programming time for a version one go-live. You can alter the velocity, or speed with which you move, by altering your spend. After you get to that first launch, you may have the option to taper down resourcing (i.e., output) and slow spending over the following months.

Additional Features or Ongoing Support

Your site is not a static business channel. You’ll need to budget for continued rollout of new ideas, features, integrations, and changes. We often work with companies to train an in-house developer and take the agency expense out. With an open architecture and open source ecommerce setup, the ongoing costs are fully in your control.

Plan out your monthly spend over 12 months to figure out what’s realistic to your ROI, and if you should start right away or take a break.

TIP: Budget for  at least a year of ongoing expenses at whatever rate you deem suitable if you want to get a little consulting, training, advice, or coding from some experts. Just be sure to align your expectations of output with your willingness to spend.

Third-Party Expenses

Look past your site to see the full picture. What else does it need or plug into that has an annual contract? Account for these costs, too. A few typical additional expenses include:

  • Hosting
  • Server maintenance, security, updates and monitoring
  • Accounting software
  • ERP software / PIM 
  • CRM software
  • 3PL software (shipping, warehousing, labeling)
  • Programmers on staff
  • CSRs on staff 
  • Training and documentation
Conclusion

Your website is not an expense; it's a revenue channel that needs to be flexible and well architected. A substantial investment will be needed to compete online, so make sure you understand the costs involved. 

If you don’t know where to start, chat with a consultant to see if your math lines up with your goals, and then take this information to your internal team. You have options, and they should be clearly laid out for you up front, not presented to you with an invoice when you’re well into development with an agency’s team. 

Inform yourself on the process, not on the programming, and you’ll be in a better position to evaluate the best path forward.  

Specbee: Drupal 8 Custom Module development – A beginners Guide

Tue, 05/26/2020 - 11:32
Drupal 8 Custom Module development – A beginners Guide Mohammed Farhaz 26 May, 2020 Top 10 best practices for designing a perfect UX for your mobile app

The power of Drupal lies with its modules. With thousands of core and contributed Drupal modules to choose from, Drupal developers can easily implement ones that meet their needs. But what if the requirements are very specific and you don’t have a module available for it? How can you customize a Drupal website for a client who has unique needs that just cannot be accomplished with core or contributed modules? Enter Custom modules.

Custom modules in Drupal 8 give you the flexibility to create new features and/or tweak existing features to accommodate a business’ unique and growing aspirations. Drupal 8 custom modules propels innovation and enhancements to help enterprises expand their horizons. This article should help you get started with creating your very own Drupal 8 module 

Getting started with Module development in Drupal 8

Let’s now get started with creating a custom module in Drupal 8 in a few easy steps:

Step 1: Name the Drupal 8 Module

First, we need to create a custom module under ‘web/modules/custom’ folder. We will name the folder as welcome_module.

Some things that you should keep in mind before giving a machine name to your module are:

  • It should not start with uppercase letters.
  • There should not be any spaces between the words.
Step 2: Get noticed with the info.yml file

We have to create a yaml file with the machine name of our module for Drupal to be able recognize the module. I’ll create a yaml file like this welcome_module.info.yml.

Here is our welcome_module.info.yml file created under "welcome" directory we created in Step 1.

name: Welcome Module type: module description: 'First Custom Drupal 8 Module.' package: Custom version: 1.0 core: 8.x

name: Welcome Module (The name displayed on the modules list in Drupal) 
type: module - (Declaring that this is a module or theme) 
description: Custom Example Drupal 8 Module (Description of the module) 
package: Custom - (Mentioning that this is a custom module) 
version: 1.0 - (Module version) 
core: 8.x - (Drupal version)

Step 3: Creating the routing file with routing.yml

Next step is to add a welcome_module.routing.yml file under the "welcome" directory:

welcome_module.welcome: path: '/welcome/page' defaults: _controller: '\Drupal\welcome_module\Controller\WelcomeController::welcome' _title: 'Welcome to My Module in Drupal 8' requirements: _permission: 'access content'

The first line is the route name [welcome_module.my_welcome].
Under path, we specify the URL path we want this route to register. This is the URL to the route.
Under defaults, we have two things: the _controller which references a method on the WelcomeController class and the default page title (_title).
Under requirements, we specify the permission of the accessing. User needs to have to be able to view the page.

Step 4: Adding a Controller 

Create a folder "modules/custom/welcome_module/src/Controller". In this folder, create a file named "WelcomeController.php" with the following content:

<?php

namespace Drupal\welcome_module\Controller;

class WelcomeController {

  public function welcome() {
    return array(
      '#markup' => 'Welcome to our Website.'
    );
  }

}

 

Now Login to your Drupal site and enable your module. To check if it functions properly, visit the path you specified in your routing file, that is /welcome/page. If you get the ‘Page Not Found’ error, then clear the cache by navigating to admin->configuration->performance. Check again and it should function properly this time.


That’s it! You’ve successfully created your very first custom module in Drupal 8.
Finally, when you go to /welcome/page URL, you'll see Title “Welcome to My Module in Drupal 8" and markup “Welcome to our Website." text printed from our module.

The great advantage of CMSs like Drupal is their ability to create websites without the need for developers to delve into coding. However, when you get to make your own custom modules in Drupal 8 and customize them according to your needs, the real power of Drupal is unleashed. Want us to help you with your next Drupal website? Contact us now!

Drupal Planet Shefali ShettyApr 05, 2017 Subscribe For Our Newsletter And Stay Updated Subscribe

Leave us a Comment

  Shefali ShettyApr 05, 2017 Recent Posts Image Drupal 8 Custom Module development – A beginners Guide Image Top Questions about Adobe Experience Manager Image How to Integrate Drupal 8 with Bitly for URL shortening Want to extract the maximum out of Drupal? TALK TO US Featured Success Stories

Know more about our technology driven approach to recreate the content management workflow for [24]7.ai

link

Find out how we transformed the digital image of world’s largest healthcare provider, an attribute that defined their global presence in the medical world.

link

Discover how a Drupal powered internal portal encouraged the sellers at Flipkart to obtain the latest insights with respect to a particular domain.

link

Debug Academy: Our DrupalCon Trainings are now available!

Mon, 05/25/2020 - 22:09
Our DrupalCon Trainings are now available!

Due to current conditions with COVID-19, DrupalCon was forced to cancel all trainings. Because of how popular our trainings were, we are pleased to offer them fully online. 

Our DrupalCon trainings are back!

With our newfound time and our ongoing commitment to accessibility & remote-availability, the Debug Academy team is proud to announce that we are offering our DrupalCon courses directly! We plan to donate a portion of the proceeds to the Drupal Association.

ashrafabed Tue, 05/26/2020

Evolving Web: What on Earth Is WCAG? Web Accessibility Guidelines Demystified

Mon, 05/25/2020 - 20:15

One can't utter the words web accessibility without mentioning the WCAG guidelines. They are a great resource, but trying to interpret them to make your website accessible can be intimidating. Fortunately, there are some great accessibility testing tools, such as WAVE, that can point out the problems. Great! Except when you try to use it and turn on an accessibility testing tool in your browser, you instantly find a sea of red and yellow warnings. If you're as new to this as I am, you may sit there wondering, well what now? What do these all mean and where do I even begin to fix the problems? Fortunately, it can be easier than you think to solve the biggest problems.   

Here's a list of 10 ways to increase web accessibility across the board, before you start wading through all the nitty gritty details:  

1. Logical Headings and Page Structure

Well-structured and organized content will make it easier for everyone to navigate your page and take in your content. Both humans and search engines appreciate clear and consistent content. Taking the time to structure your user-interface properly can really pay off, and will be especially appreciated by readers who use assistive technology like a screen reader to access your page. No one wants to sit there guessing what the difference is between your three "Main Menus." The W3 page has some good tips on how to properly structure your page.

If you turn off CSS and Javascript, you can get an idea of how your webpage is read for someone using a screen reader. CSS allows you to position elements wherever you want on the page, regardless of where they are in the code. However, to users using a screen reader, the page won't appear as it does visually but how it is ordered in the code. The same goes for JavaScript. It allows you to manipulate elements by hiding them, removing them or showing them, but the webpage won't appear the same way it does visually to a screen reader.   

2. HTML Semantic Markup and Use of Landmarks plus ARIA  

Always use native HTML elements to make the website more accessible when available. You should use HTML5 tags to mark up the main sections of a page (footer, header, navigation, main, etc.), as well as sections, paragraphs and lists. HTML tags can be used to tell a computer about the content of a website and can make navigating using a screen reader much more accessible. This page has a good checklist on HTML elements and attributes for accessibility. When HTML markup is not sufficient, use ARIA markup. ARIA (Accessible Rich Internet Applications) is a set of attributes you can add to HTML elements to make them more accessible for users who use assistive technologies. The first rule of ARIA is don't use ARIA. If there's a way to do it with semantic HTML, that's always a safer bet but if you're not sure how or when to use it, this page does a good job of explaining that.   

3. Headings

The proper use of headers is another element that goes a long way in helping to structure your page and making it easier to navigate. Headers allow users with screen readers to skip to the section they want. The element denotes a main heading and there should only be one per page: your page title. indicates subsections beneath it, and further embedded subsections of that are labelled with , with imbedding your content even further, and so on. For more details on how to structure headers, try this blog. Just don't be tempted to skip a layer and add a beneath an because users will end up confused. That's like skipping arithmetic and trying to learn algebra after just learning how to count. What happened to and and why are there letters in math class all of a sudden?! 

4. Forms

It is essential that forms can be accessed by the keyboard alone for users that cannot use a mouse. Provide overall instructions about filling out the form before the element since screen readers usually switch to 'Forms' mode when they encounter a form. Each field in the form needs to be properly labelled and the label needs to be in close proximity to the input box for that field. Also make sure any additional instructions are outside the box and not placeholder text inside. For more details on forms, the University of Guelph accessibility page has a good explanation on forms. Basically, when you're building a form, it's one place where you don't want to think outside the box.  

5. Images

Users who rely on a screen reader to access your site need images with alternative (alt) text and there are different types of alt text to use depending on the type of image. If the image is descriptive, such as a young child riding a bike in downtown Boston, the alt text should describe something to the effect of "A young child riding a bike on the streets of downtown Boston." If the image is a functional image which denotes an action, such as magnifying glass to represent a search action, it should indicate the action in the alt text, saying "search." The exception to all this is purely decorative images, which should have an empty alt text. Keep your alt texts snappy. A picture is worth a thousand words, but in this case, 140 characters is usually enough. If you need more clarification on what to write for alt text or how to make them more accessible, then here is a handy guide.   

6. Tables

Only use tables when absolutely necessary. Do not use tables as part of the layout or to display lists. Misusing tables can make them confusing for screen readers. Use tables to display data with a logical relationship that is best represented in a grid. To make tables more accessible, mark headers with and cells with . Here's more info on accessible tables.  

7. Keyboard Navigation

It is important that the site be navigable with a keyboard. Some users cannot use a mouse, and certain assistive technologies do not allow for precise clicking or hovering. Or maybe the user's track-pad just stopped working. To make sure that your website can be navigated using a keyboard, tab through the site using your keyboard. As you tab through the site, check that there is a focus ring  (usually a light blue outline by default) around focusable elements (buttons, links, form inputs, etc.) and that the keyboard focus order matches the visible focus order. Remove any off-screen focusable elements. If you're still not sure how to make your site more keyboard navigation friendly, here is an excellent checklist.   

8. Add a 'Skip to Content' Link

Another great way to improve site accessibility is to add a 'skip to content' link. When tabbing through a screen to access content, it can quickly become tedious if you have to go through a ton of repeated elements in the header of each page before getting to the main content. A 'skip to content' link provides a keyboard-supported means of bypassing these repeated elements to access the main content, making navigating your page with a keyboard or while using a screen reader much easier. Trust me, if you've ever heard a screen reader reading your mega-menu items every time you land on a page, you'll jump at the chance to let users skip to the good stuff. You can find a bit more about skip-to-content links here

9. Appearance

Certain design elements can also help improve accessibility. Ensure there is enough contrast between the text and the background. Also, choose a sans-serif font for increased legibility, ensure the font is large enough, and enable resizable text. Never underestimate the value of space. Ensure adequate spacing between each line of text and between paragraphs. We've written a more detailed explanation on how to keep the design elements of your website accessible.   

10. Media

It is always best to have alternative ways for users to access essential media and consider removing most non-essential media. Avoid any flashing media since this can trigger seizures in some users.  Always caption all audio or video content. Some video platforms such as YouTube have auto-captioning that uses speech recognition to caption videos. It is less than perfect though, so while it can be a good start, it is best to manually review the auto-captions. Captions can benefit everyone, and sometimes users would prefer reading captions to a video than hearing audio when visiting your page in a library, at work or on a busy subway.  

Another way to make media more accessible is to include an audio description of the key visuals in video content. Another important thing to do is to disable automatic playback of all media. There is nothing more annoying than trying to figure which open tab that noise is coming from. Imagine how much more annoying it can be for those who rely on screen readers and keyboards to navigate. If you need more tips on how to make media accessible, this page does a good job of explaining alternative media types and requirements.   

In Conclusion

With this list in hand, you're not an accessibility expert, but you could just make your site more accessible than most of your competitors. And you're well on your way to adopting more inclusive practices into your work. If you need a hand figuring all this out, contact us or join our Web Accessibility training, which guides you through this step-by-step.

+ more awesome articles by Evolving Web

imalabya.co: Lazy load inline images using Filter API & Image styles

Mon, 05/25/2020 - 18:12
Lazy load inline images using Filter API & Image styles

Lazy loading is a technique that defers the loading of images when it is actually required and not loading them upfront. Thus, images will be loaded only when an image is in the viewport of the browser as the user scrolls. This helps in reducing the initial size of the payload of a webpage and improving the performance.

There is an excellent article Lazy Loading Images and Video which describes how to use Intersection Observer API to register an observer to watch image elements. The whole idea is to load a small lightweight placeholder image upfront on page load and lazily load the original image when the observer detects an image in the viewport. This is similar to the technique used by Medium to load images on their portal.

Image lazy loading in Medium. 
Credit: https://developers.google.com/web/fundamentals/performance/lazy-loading-guidance/images-and-video

Using the method described in Lazy Loading Images and Video, to lazy load an inline image in Drupal we will need to do 3 things:

  1. Add an image style to create a lightweight placeholder image
  2. Add a filter to alter the HTML markup of images
  3. Add an intersection observer in JavaScript to lazy load image
Tl;dr

Check out the plugin file here: https://github.com/malabya/imalabya/blob/master/web/modules/custom/im_filters/src/Plugin/Filter/LazyLoad.php

The JavaScript file with the intersection observer: https://github.com/malabya/imalabya/blob/master/web/themes/imalabya/src/scripts/lazyload.es6.js

Add an image style to create a lightweight placeholder image

This step is fairly simple. Create a new image style to generate a small lightweight placeholder image. This placeholder image will be loaded when a page is loaded to show a blurred out image which will be replaced by the intersection observer.

For this, create an image style called placeholder and apply the Scale effect to have the image width of 5px.

Add a filter to alter the HTML markup of images

To lazy load an image we will the image to be in a particular HTML structure

Filter API is a great plugin that can be added to text formats which will alter the text before it is being rendered and gets cached. We can also attach libraries to the plugin which will ensure that the intersection observer JavaScript gets loaded only when it is required [more performance improvement].

Start off by defining a Filter plugin using annotations.

/** * Lazy load image. * * @Filter( * id = "lazy_load_image", * title = @Translation("Lazy load inline images."), * type = Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE * ) */

The plugin class extends the FilterBase class which has a process method where all the action will happen. In the process method, loop through all img tags and apply the changes required.

To apply the placeholder image style, generate the URL of the image after applying the effects.

$filename = pathinfo(urldecode($src), PATHINFO_BASENAME); $style = ImageStyle::load('placeholder'); $uri = $style->buildUrl('public://inline-images/' . $filename); return file_url_transform_relative($uri);

The last thing to do is to add the attributes for the image HTML. In the HTML snippet above there are 3 attributes that need to be added. 

  • The class attribute which will be used as a selector for the javascript
  • The src attribute will hold the placeholder image
  • The data-src attribute will hold the actual image to be loaded.
$src = $element->getAttribute('src'); // Get the placeholder image src. $placeholder = $this->getPlaceholder($src); // Get any existing classes and add the lazy class for lazy loading image. $classes = explode(" ", $element->getAttribute('class')); array_push($classes, 'lazy'); // Set the attributes. $element->setAttribute('class', implode(" ", $classes)); $element->setAttribute('src', $placeholder); $element->setAttribute('data-src', $src); Add an intersection observer in JavaScript to lazy load image

Intersection Observer API is a relatively new API in browsers that is really simple to detect when an element enters the viewport and take an action when it does. 

The javascript will fetch all the img tags in the dom with lazy class and when IntersectionObserver is in the viewport, it will replace the src of the image with the path set in the data-src. There is a fallback for browsers that doesn't support IntersectionObserver

document.addEventListener('DOMContentLoaded', function () { var lazyImages = [].slice.call(document.querySelectorAll('img.lazy')); if ('IntersectionObserver' in window) { let lazyImageObserver = new IntersectionObserver(function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { let lazyImage = entry.target; lazyImage.src = lazyImage.dataset.src; lazyImage.classList.remove('lazy'); lazyImageObserver.unobserve(lazyImage); } }); }); lazyImages.forEach(function (lazyImage) { lazyImageObserver.observe(lazyImage); }); } else { // Fall back to a more compatible method lazyImages.forEach(function (lazyImage) { lazyImage.src = lazyImage.dataset.src; }); } }); Lazy loading in action

Once, the plugin and the javascript is implemented and the filter is enabled on a text format check, the lazy load functionality will kick in for all the images being uploaded in CKEditor.

To check how if lazy loading actually working, watch the below gif animation.

Give it a little time, it's a big image.

As you can see in the initial stage, only the placeholder images are loaded which are pretty lightweight ~750B in size. As I scroll down the page, the IntersectionObserver comes into play and loads the original image when the image comes in the viewport of the browser. So, even though the final page is over ~3.5MB the initial load of the webpage is a little over 1.5KB.

Conclusion

Lazy loading, if implemented properly can significantly improve the page speed by loading the necessary content of a page and defer loading the big image assets when it is required. All done keeping the content intact. With faster loading of pages, the user experience will also improve greatly which users will love.

Down the lane, I am planning to build a Drupal module out of it to contribute it back to the community so that more people can use this on their sites and improve the performance.

malabya Mon, 05/25/2020 - 21:42 Drupal developmentPerformance

Danny Englander: Layout Builder With Drupal 8: a Few Tips, Tricks, and Gotchas

Mon, 05/25/2020 - 11:00

Over the past month, I have been working on a large scale Drupal 8 build that is leveraging the Layout Builder module for much of the site's displays. If you are not familiar with Layout Builder, it's a fairly new initiative that hit Drupal 8 core as an experimental module in 8.5 and then gained full status in 8.7.

So far, I am really enjoying using Layout Builder, my point of view being very much form a theming perspective. In my option, Layout Builder is almost like a hybrid between Panels and Paragraphs. It's ideal for content-centric sites where you'd like to hand over more control of content display to editors while keeping to a structured modular content model. This paradigm should sound vaguely familiar for those folks who have been building with Paragraphs.

"Drupal 8's Layout Builder allows content editors and site builders to easily and quickly create ...

ARREA-Systems: Jitsi in Drupal

Sun, 05/24/2020 - 04:14
Jitsi in Drupal Integration module of Jitsi video conferencing service. Allows to point to a Jitsi Meet server, start a new video session or join existing directly from a Drupal 8 site.

eiriksm.dev: Walktrough: How I am using Github for my blog comments

Sat, 05/23/2020 - 11:04

My last blog post was about my journey towards "getting rid" of Disqus as a comment provider, and moving over to hosting my comments on Github. The blog post was rather light on technical details, so here is the full technical walkthrough with code examples and all.

Since I already explained most of the reasoning and architectural choices in that post I will just go ahead with a step by step of the technical parts I think is interesting. If that means I end up skipping over something important, please let me know in the (Github) comments!

Step 0: Have a Gatsby.js site that pulls it's content from a Drupal site

This tutorial does not cover that, since many people have written such tutorials. As mentioned in my article "Geography in web page performance", I really like this tutorial from Lullabot, and Gatsby.js even has an official page about using Drupal with Gatsby.js.

Step 1: Create a repo to use for comments

The first step was to create an actual repository to act as a placeholder for the comments to be. It should be public, since we want anyone to be able to comment. I opted for the repo https://github.com/eiriksm/eiriksm.dev-comments. To create a repository on GitHub, you need an account, and then just visit https://github.com/new

Step 2: Associate blog posts with issues

The second step is to have a way to indicate which issue is connected to which blog post. Luckily I am still using Drupal, so I can just go ahead and create a field called "Issue id". Then, for each post I write, I create an issue on said repo, and take a note of the issue id. For example, this blog post has a corresponding issue at https://github.com/eiriksm/eiriksm.dev-comments/issues/6, so I just go ahead and write "6" in my issue id field.

Step 3: Fetch all the issues and their comments to Gatsby.js

This is an important part. To be able to render the comments at build time, the most robust approach is to actually "download" the comments and have them available in graphql. To do that you can try to use the source plugin for GitHub, but I opted for getting the relevant issues and comments and creating the source myself. Why, you may ask? Well the main reason is because then I can more easily control how the issue comments are stored, and by extension also store the drupal ID of the node along with the comments.

To achieve this, I went ahead and used the same JSONAPI source as Gatsby will use under the hood, and then I am fetching the issue comment contents of each of the nodes that has an issue ID reference. This will then go into the gatsby-node.js file, to make the data we fetch available to the static rendering. Something along these lines:

exports.sourceNodes = async({ actions, createNodeId, createContentDigest }) => { const { createNode } = actions try { // My build steps knows the basic auth for my API endpoint. const login = process.env.BASIC_AUTH_USERNAME const password = process.env.BASIC_AUTH_PASSWORD // API_URL holds the base URL of my Drupal site. Like so: // API_URL=https://example.com/ let data = await fetch(process.env.API_URL + 'jsonapi/node/article', { headers: new fetch.Headers({ "Authorization": `Basic ${new Buffer(`${login}:${password}`).toString('base64')}` }) }) let json = await data.json() // Create a job to download each of the corresponding issues and their comments. let jobs = json.data.map(async (drupalNode) => { // Here you can see the name of my field. Change this to whatever your field name is. if (!drupalNode.attributes.field_issue_comment_id) { return } let issueId = drupalNode.attributes.field_issue_comment_id // Initialize the data we want to store. let myData = { drupalId: drupalNode.id, issueId, comments: [] } // As you can see, this is hardcoded to the repo in question. You might want to change this. let url = `https://api.github.com/repos/eiriksm/eiriksm.dev-comments/issues/${issueId}/comments` // We need a Github token to make sure we do not hit any rate limiting for anonymous API // usage. const githubToken = process.env.GITHUB_TOKEN let githubData = await fetch(url, { headers: new fetch.Headers({ // Hardcoded to my own username. This probably will not work for you. "Authorization": `Basic ${new Buffer(`eiriksm:${githubToken}`).toString('base64')}` }) }) let githubJson = await githubData.json() myData.comments = githubJson // This last part is more or less taken from the API docs for Gatsby.js: // https://www.gatsbyjs.org/docs/node-apis/#sourceNodes let nodeMeta = { id: createNodeId(`github-comments-${myData.drupalId}`), parent: null, mediaType: "application/json", children: [], internal: { type: `github__comment`, content: JSON.stringify(myData) } } let node = Object.assign({}, myData, nodeMeta) node.internal.contentDigest = createContentDigest(node) createNode(node) }) // Run all of the jobs async. await Promise.all(jobs) } catch (err) { // Make sure we crash if something goes wrong. throw err } }

After we have set this up, we can build the site and start exploring the data in graphql. For example by running npm run develop, and visiting the graphql endpoint in the browser, in my case http://localhost:8000/___graphql:

$ npm run develop > eiriksm.dev@0.0.0 develop /home/eirik/github/eiriksm.dev > gatsby develop # ... # Bunch of output # ... ⠀ You can now view eiriksm.dev in the browser. ⠀ http://localhost:8000/ ⠀ View GraphiQL, an in-browser IDE, to explore your site's data and schema ⠀ http://localhost:8000/___graphql

This way we can now find Github comments with graphql queries, and filter by their Drupal ID. See example animation below, where I find the comments belonging to my blog post "Reflections on my migration journey from Disqus comments".

In the end I ended up with the following graphql query, which I then can use in the blogpost component:

allGithubComment(filter: { drupalId: { eq: $drupal_id } }) { nodes { drupalId comments { body id created_at user { login } } } }

This gives me all Github comments that are associated with the Drupal ID of the current page. Convenient.

After this it's only a matter of using this inside of the blog post component. Since this site mix and match comment types a bit (I have a mix of Disqus exported comments and Github comments), it looks something like this:

let data = this.props.data if ( data.allGithubComment && data.allGithubComment.nodes && data.allGithubComment.nodes[0] && data.allGithubComment.nodes[0].comments ) { // Do something with the comments. } Step 4: Make it possible to fetch the comments client side

This is the part that makes it feel real-time. Since the above code with the graphql storing of comments only runs when I deploy this blog, comments can get quickly outdated. And from a UX perspective, you would want to see your own comment instantly after posting it. This means that even if we could rebuild and deploy every time someone posted a comment, this would not be instant enough to make sure a person actually sees their own comment. Enter client side fetching.

In the blog post component, I also make sure to do another check to github when you are viewing the page in a browser. This is because it is not necessary for the build step to fetch it once again, but I want the user to see the latest updates to the comments. So in the componentDidMount function I have something like this:

componentDidMount() { if ( typeof window !== `undefined` && // Again, only doing this if the article references a github comment id. And again, this // references the field name, and the field name for me is field_issue_comment_id. this.props.data.nodeArticle.field_issue_comment_id ) { // Fetch the latest comments using Githubs open API. This means the person using it will // use from their own API limit, and I do not have to expose any API keys client side. window .fetch( "https://api.github.com/repos/eiriksm/eiriksm.dev-comments/issues/" + this.props.data.nodeArticle.field_issue_comment_id + "/comments" ) .then(async response => { let json = await response.json() // Now we have the comments, do some more work mixing them with the stored ones, // and render. }) } } Step 5 (bonus): Substitute with Gitlab

Ressa asked in a (Github) comment on my last blogpost about doing this comment setup with Gitlab:

Do you know if something like this is possible with Gitlab?

Fair question. Gitlab is an alternative to Github, but differs in that the software it uses is itself Open Source, and you can self-host your own version of Gitlab. So let's see if we can substitute the moving parts with Gitlab somehow? Well, turns out we can!

The first parts of the project is the same: Create a field, have an account on Gitlab, create a repo for the comments. Then, to source the comment nodes, all I had to change was this:

--- a/gatsby-node.js +++ b/gatsby-node.js @@ -125,15 +125,25 @@ exports.sourceNodes = async({ actions, createNodeId, createContentDigest }) => { issueId, comments: [] } - let url = `https://api.github.com/repos/eiriksm/eiriksm.dev-comments/issues/${issueId}/comments` - const githubToken = process.env.GITHUB_TOKEN + let url = `https://gitlab.com/api/v4/projects/eiriksm%2Feiriksm.dev-comments/issues/${issueId}/notes` + const githubToken = process.env.GITLAB_TOKEN let githubData = await fetch(url, { headers: new fetch.Headers({ - "Authorization": `Basic ${new Buffer(`eiriksm:${githubToken}`).toString('base64')}` + "PRIVATE-TOKEN": githubToken }) }) let githubJson = await githubData.json() + if (!githubJson[0]) { + return + } myData.comments = githubJson + // Normalize it slightly. + myData.comments = myData.comments.map(comment => { + comment.user = { + login: comment.author.username + } + return comment + }) let nodeMeta = { id: createNodeId(`github-comments-${myData.drupalId}`), parent: null,

As you might see, I took a shortcut and re-used some variables, meaning the graphql is querying against GithubComment. Which is a bad name for a bunch of Gitlab comments. But I think cleaning those things up would be an exercise for the reader. The last part with client side updates was not possible to do in a similar way. The API for that requires authenticating the request. Much like the above code from sourcing the comments. But while the sourcing happens at build time, client side updates happens in the browser. Which would mean that for this to work, there would be a secret token in your JavaScript for everyone to see. So that is not a good option. But it is indeed theoretically possible, and could for example be achieved with a small proxy server, or serverless function.

The even cooler part is that the exact same code also works for a self-hosted Gitlab instance. So you can indeed run open source software and own your own data with this approach. That being said, not using a server was one of the requirements for me, so that would defeat the purpose. In such a way, one might as well use Drupal as a headless comment storage.

I would still like to finish with it all working in Gitlab too though. In an animated gif, as I always end my posts. Even though you are not allowed to test it yourself (since, you know, the token is exposed in the JavaScript), I think it serves as an illustration. And feel free to (Github) comment if you have any questions or feel I left something out.

Danny Englander: Drupal 8 Architecture: How to Add Custom HTML Data Attributes to Menus

Sat, 05/23/2020 - 11:00

In a new Drupal 8 build that I am working on, there is a use case for some menu items to have an abbreviation underneath. I wanted to create a content editor friendly way of achieving this in the Drupal menu admin UI. Since I have already implemented the Drupal 8 Link Attributes widget module, I got to thinking that perhaps I could extend the module to handle these abbreviations.

Extending the Link Attributes widget

I was happy to discover that Link Attributes can be extended to any kind of additional HTML attribute you might need for your menu. I came up with the idea that if I could add a new field for the abbreviation, I could turn it into an HTML data attribute for a menu item and then output it with a little jQuery.

There are two pieces to extending the widget within a custom module, my_module.

...

Danny Englander: Drupal 8 Architecture: How to Add Custom HTML Data Attributes to Menus

Sat, 05/23/2020 - 11:00

In a new Drupal 8 build that I am working on, there is a use case for some menu items to have an abbreviation underneath. I wanted to create a content editor friendly way of achieving this in the Drupal menu admin UI. Since I have already implemented the Drupal 8 Link Attributes widget module, I got to thinking that perhaps I could extend the module to handle these abbreviations.

Extending the Link Attributes widget

I was happy to discover that Link Attributes can be extended to any kind of additional HTML attribute you might need for your menu. I came up with the idea that if I could add a new field for the abbreviation, I could turn it into an HTML data attribute for a menu item and then output it with a little jQuery.

There are two pieces to extending the widget within a custom module, my_module.

...

Lullabot: 5 Steps to a More Accessible Website

Thu, 05/21/2020 - 17:09

Whether you're a developer or a designer, everyone has a role to play in making websites more accessible and usable for site visitors. Our design and development teams got together to create this checklist of high-priority tasks you can execute to make your site more accessible. These are some of the issues that affect users of assistive technologies the most, so they should be first on your list when you're forming a plan to improve website accessibility.

wishdesk.com: Drupal 9 upgrade: making your website ready with the latest tools

Thu, 05/21/2020 - 16:52
Drupal 9 release is more than just round the corner — the 9th version is already knocking at our doors. Today, let’s discover how to prepare your website for the Drupal 9 upgrade with the help of the latest tools.

Evolving Web: 7 Design Considerations for Accessibility  

Thu, 05/21/2020 - 15:16

Designing an attractive and highly functional website has a lot of important considerations, like whether users would intuitively connect more with turquoise or cyan, and whether it works with the branding. However, one often overlooked but important consideration is accessible design, and since it's always easier to fix things that you uncover in the design process, it is best to consider accessible design upfront in the design process.

Here are seven design elements to keep in mind when designing your website so it'll not only look great, but be easy to use for everyone.   

1. Colour Contrast

Colour contrast is important for both low-sighted and color blind users. I also appreciate good contrast when I'm trying to read my phone by the pool in the bright sun at noon after three margaritas. Furthermore, according to WebAIM, poor text contrast is the number one accessibility error in the top 1 million visited sites. For AAA standards, text and background need to be black and white. For AA standards, there is a 4.5:1 ratio to background for text and 3:1 for headings, as well as a 3:1 ratio for non-text contrast. 

The following tools can help you analyze your colour contrast: my preferred contrast checker, aptly named Contrast Checker and the Webaim one, and a browser extension for Firefox and Chrome.  

2. Hierarchy and Layout

Keep the hierarchy and layout of your page logical and organized and everyone will thank you. Make sure key information is visible at a glance and follows a logical hierarchy. There is nothing more frustrating than to have to scroll through an entire page or click a ton of links to get to the important information. It can be even more annoying on a screen reader. If you're not sure on how to proceed, here are some tips on layout on creating accessible layout. And remember, a good general rule is less is more. Cut the clutter and find your inner Marie Kondo.   

3. Fonts

Use a sans-serif font. Sans-serif fonts are clearer and legible at any size, not to mention they scream bold and modern design. Sans-serif fonts are so cool that I once watched an hour-long documentary on Helvetica titled the same. Or maybe that just shows how cool I am? Either way, sans-serif fonts are where it's at because they're simply easier to read. Also, make sure your text is large enough to read; have a text size of at last 16 px. If you need to emphasize information, bold is easier to read than italic or uppercase. Lastly, don't use stylized fonts outside of your logo. This page from Penn State provides a nice list of accessible fonts.   

4. Enable Text Resizing

Ensure your text is resizable so users who have just had their glasses trampled by their obese Saint Bernard can zoom in on your content while looking up opticians. Most modern day browsers support scalability, however be sure not to inadvertently turn off user scalability as a function. Check to make sure your site scales properly. You can easily achieve scalability by using relative sizes such as percent or ems rather than absolute sizes like pixels or points. The Yale accessibility site has a nice guide on how to ensure text is resizable.   

5. Text Spacing

Serifs are out, space is in. Think lovely Scandinavian minimalism. Leaving enough space between lines of text and images helps the user focus more on what is important. Ensure that the line height is at least 1.5 times the font size and that the spacing following paragraphs is two times the font size. Letter spacing (tracking) should be at least 0.12 times the font size and word spacing at least 0.16 times the font size. If I still haven't convinced you of the importance of text spacing, this page might, along with providing more tips.   

6. Links

Ensure links are distinguishable by something other than colour. An underline is standard and does the job. Also, name them something useful, short and descriptive. And definitely not 'Click Here.' All links linking to the same page should have the same description. Be sure to mention if the link opens a new tab or triggers a download, in which case indicate the file type and size, too. Again, the Yale accessibility site has a nice guide on how to make links accessible.   

7. Style Focus

Browsers display a focus ring around currently focused elements. Often, this is turned off because designers find it visually unappealing but it can be essential to those using a keyboard to navigate your site. If you are going to remove the default style focus, then be sure to replace it with something else to denote the focus. Or alternatively, have a style focus which is activated only when using the keyboard to navigate and not the mouse. Here are some more tips on how to implement style focus.   

Need More Accessibility Guidance?

If you follow these seven tips, you'll be well on your way to having a site that is accessible and enjoyable for everyone. And if you need a hand figuring all this out, take our Web Accessibility training, which guides you through this step-by-step. Also, I hear retro is in. Just think how cool your site can be with a sleek retro aesthetic and accessible design.

+ more awesome articles by Evolving Web

Promet Source: Today is Global Accessibility Awareness Day

Thu, 05/21/2020 - 06:34
"Never doubt that a small group of thoughtful, committed citizens can change the world; indeed, it's the only thing that ever has.”         - Margaret Mead  

Drupal.org blog: What's new on Drupal.org? - April 2020

Wed, 05/20/2020 - 23:52

Read our roadmap to understand how this work falls into priorities set by the Drupal Association with direction and collaboration from the Board and community. You can also review the Drupal project roadmap.

Project News Drupal 9 will be released on June 3rd, 2020

Despite the disruption of a global pandemic, the Drupal community has beaten the odds and Drupal 9.0 is on time for it's scheduled release window on June 3rd, 2020.

Drupal 9 represents the culmination of all of the features developed over the course of the Drupal 8 lifecycle, as well as the realization of the project's commitment to easy upgrades.

Drupal 9 beta 3 is available now, and the first release candidate will be available soon. We encourage you to participate in the Drupal beta test program, to help us ensure a smooth release.

Drupal 9 porting weekend from May 22-23

With the release of Drupal 9 only a couple weeks away, the community is coming together to support the effort to get modules ready for Drupal 9. After a successful Drupal 9 porting on April 28th, nearly 75% of the top 200 most used modules are already Drupal 9 compatible. Never before has so much of the contributed module ecosystem been ready even before the new release.

If you'd like to join in on the Drupal 9 module porting weekend, community member @kristen_pol has written a guide to the event.

New Drupal Brand assets available

The Drupal Association was very pleased to announce a new evergreen Drupal brand in time for the release of Drupal 9.

What does 'evergreen' mean?

The new branding is evergreen in the sense that it is no longer tied to a specific major version of Drupal. Whether for Drupal 9, Drupal 10, and beyond this new brand can remain the consistent identity for Drupal. This parallels the Drupal project's own development philosophy, where major version upgrades should no longer be a difficult process for end users.

With these new brand materials we hope to be able to unify the presentation of Drupal throughout the ecosystem, and help reintroduce Drupal to the world when the project inevitably gains more attention during Drupal 9's release.

We encourage you to begin using the new brand within your own materials as well - to support this effort.

Automated Deprecation Patches to port your module to Drupal 9

The Drupal Association is working together with the Drupal Rector team from Palantir and contributor Tedbow from Acquia to provide automatically generated Drupal Rector patches for all the projects on Drupal.org.

As of April, these patches are already available through DrupalCI. In May we hope to begin having a bot automatically post these fix patches to Drupal.org issues

More Drupal 9 Readiness tools Drupal.org Updates Events listing feature on Drupal.org

As we spoke about in last month's update, we've been working on a Event Listing Content Type on Drupal.org to help replace the aging Groups.Drupal.org subsite, and to support our global community by providing a central repository of events.

The new event listings are nearly ready for user submissions, and to feed existing community tools like Drupical.com.

If you'd like to add your events, reach out to rachel@association.drupal.org to be added as an early event editor for this new feature.

Respectful Advertising

The COVID pandemic and its impact on DrupalCon has only emphasized the need for the Drupal Association to further diversify its revenue sources. We've made significant strides over the last several years, but as we've heard from many of you, that work must accelerate.

We've made a few changes over the course of April to start accelerating this revenue diversification:

In the most noticeable change, we've partnered with CarbonAds, a network that focuses on advertising to technical audiences, to create placements on Drupal.org.

These placements are hidden for Drupal Association members, so this program also helps promote DA membership as well, and does not put advertising in the workspace of our committed supporters.

Enhanced Membership Options

Speaking of membership - we also made some major overhauls to the Drupal Association membership program during the #DrupalCares campaign. Many members of the community reached out to us asking for more options for supporting the Drupal Association through membership, and we were happy to accommodate those requests.

There are now new membership levels for annual renewal, and we've also added a monthly membership option, which is now the default. We hope to continue to expand the membership program and its benefits to further support our fiscal stability in the future. 

A special thanks

———

As always, we’d like to say thanks to all the volunteers who work with us, and to the Drupal Association Supporters, who make it possible for us to work on these projects. In particular, we want to thank:

If you would like to support our work as an individual or an organization, consider becoming a member of the Drupal Association.

Follow us on Twitter for regular updates: @drupal_org, @drupal_infra