Website Accessibility Tricks & Tips

Article Pre-Evaluation:

Estimated read-time: 14 Minutes

Level of reading competence and understanding: Semi-Technical

Author: Gavin McQuienn, Lead Front-End Engineer, Aceik


What we cover in this article:


What is Website Accessibility?

Website accessibility is the inclusive practice of structuring a website to ensure that the maximum number of people can access/navigate and obtain information within websites on the World Wide Web, in particular for those with physical disabilities & situational disabilities, such as socio-economic restrictions on bandwidth and speed.

In technical-speak, it is the practice of implementing/leveraging the proper usage functionally-descriptive HTML tags, best practices-practice HTML structures, CSS, images and media, such as video and audio.

Accessibility Users – Web Statistics & Debunking the Myths 

In the past, there has often been a mindset that users utilising disability related accessibility website features were the minority. Well here are a few things that most do not consider when casting thought upon this subject.

Accessibility – not only benefits people with disabilities 

Business Cases for Accessibility Improvements

  • Legal & General Group – doubled visitor numbers, cut maintenance costs by two thirds and increased natural search traffic by 50%. 
  • Tesco – £35 thousand GBP to build their accessible website, £13 million GBP per year in resultant revenue. 
  • CNET – 30% increase in traffic from Google after CNET started providing transcripts, “We saw a significant increase in SEO referrals when we launched an HTML version of our site, the major component of which was our transcripts.” – Justin Eckhouse, CNET, 2009.
  • This American Life is a broadcast heard on more than 500 National Public Radio (NPR) stations by about 2.1 million listeners each week in the United States. In 2011, the broadcaster committed to creating transcripts for their entire archive of recorded programs and recorded. This subsequently resulted in:
    • search traffic increased 6.86%,
    • better comprehension for visitors who use English as a second language,
    • visitors were able to use transcripts in noisy or sound-sensitive environments,
    • ability to more easily translate, and
    • ability to search text to reference a specific section of audio.
  • “Many organisations are waking up to the fact that embracing accessibility leads to multiple benefits – reducing legal risks, strengthening brand presence, improving customer experience and colleague productivity.” – Paul Smyth, Head of Digital Accessibility, Barclays

Accessibility Internet Traffic Statistics 

In the USA ~ according to the Census Bureau on July 25, 2012:

  • 54% of adults living with a disability go online.
  • 56.7 million Americans (18.7% of the population), that is a figure of 19.9 million (roughly 8.2%) have proven to have difficulty lifting or grasping objects, which could impair their ability to use a mouse or keyboard.
  • 8.1 million (3.3%) suffer from vision impairment. Such demographics commonly use tools such as a screen magnifier, screen readers, or might have a form of color blindness, to which colour contrasts become ever so important.
  • 7.6 million (3.1%) have been proven to have a hearing impairment – given such disabilities would rely heavily on transcripts and/or captions for audio/video media.
  • Sight and hearing impairments cover an average of 6.8 percent of the population aged 15 years +. These figures jump to a whopping 21.3 percent of the population when you look specifically at the ageing population, people aged 65+.
  • The Baby Boomer generation (born between 1945 and 1964) is going to cross that 65-year barrier in 2010. This same web-savvy generation created the Internet, for the most part and represents one of the largest single demographics in the United States.

What can you do to increase your website’s accessibility?

Implementing accessibility features has been proven to not only increase the overall user experience and usability of a website, which will ultimately translate into higher traffic and increased SEO impact / reach, but will ensure modern best-practice standards are adhered to, which ultimately instills a higher level of code and content quality throughout a site. 

There are many things that you can start doing today, but to successfully administer a high level of accessibility is generally a 3-pronged approach:

  1. Design considerations
    1. Ensuring that even at the initial design phase that colour-contrasts, disability user-journey/navigation & audio/video media content alternatives are considered
  2. Content editors preparation, structures, awareness and consideration 
    1. Preparing audio/video media and written content for multiple demographics, such as transcripted media, listing average article read-time estimations, competency reading level grading & text alternatives for media including images, video and audio
  3. Adopting technical development hygiene / strategies 
    1. Making use of the correct usage and structured HTML, such as tab-indexed links/navigation items, hidden content for screen-readers, and especially accessibility related HTML tags & CSS, such as Aria labels, CSS user-interaction related Pseudo classes. 

Accessibility – Technical Standards, approaches, best practices & things to consider.

We have separated some well-known strategies into categories of implementation-difficulty and ultimately, development/preparation related costs/efforts ~ it must be noted that some of these tactics can be implemented to existing codebases in a, ‘moving forward’ mentality / approach, which will still slowly start to increase your accessibility support.

This may include, but is not limited to such items as:

Low Cost / Effort / Preliminary planning required
Implementing correct usage of functionally user-interactive CSS Pseudo-Classes such Focus, Active, Visited, Hover, etc

.btn {
  &:hover,
  &:focus,
  &.focus {
    color: $purple5;
    background-color: darken($yellow1, 10%);
  }
}
  • Meaningfully named, underlined/colored (or otherwise differentiated) Anchor links
  • Textual equivalents provided for images
  • Providing meaningful `alt` & `title` tags for all imagery
<img src="" alt="ENTER IMAGE DESCRIPTION - Helpful with SEO" title="This is an image of a Ragdoll cat jumping">

`Tab-indexed` user journey-tested Anchor Links and Buttons, as well as `title` tags explaining functionality 

<a class="btn btn-secondary" href="#" tabindex="0" title="Click here to see cats from category 1">
Pictures of category 1 cats
</a>
<a class="btn btn-secondary" href="#"  tabindex="1" title="Click here to see cats from category 2">
Pictures of category 2 cats
</a>
<a class="btn btn-secondary" href="#"  tabindex="2" title="Click here to see cats from category 3">
Pictures of category 3 cats
</a>

Medium Cost / Effort / Preliminary planning required

  • Text and images are large and/or enlargeable
  • Mobile optimised imagery, media & mobile-specific layouts 
  • Textual equivalents provided for images 
  • Text and images are large and/or enlargeable

High Cost / Effort / Preliminary planning required

  • Keyboard supported Menu-Navigations
  • Magnifying text/imagery options for content
  • Alternate methods of obtaining information regarding visual/audio media, such as  closed captioned and/or a sign language versions
  • Captha’s that have multiple options to human validity, such as Audio options regarding successful passphrases, or modern captchas do not require input from a user


  • Print-friendly web pages – making sure that your pages are accessible and usable even when printed or saved as a PDF file

Aria Label HTML Tags & Screen Reader Specific CSS Classes 

What are Aria Labels HTML related Tags?

ARIA stands for Accessible Rich Internet Applications and is a set of attributes that define/provide alternatives to make web applications / content (in particular those written using Javascript) more accessible to people with disabilities.

Aria Labels extend HTML and pass information to assistive technologies related to interactions and widgets commonly used in applications, which provide the user with additional information that would not otherwise be accessible. For example, ARIA enables accessible navigation landmarks in HTML4, form hints and error messages, live content updates, JavaScript related widgets and many more. 

Luckily HTML5  provides a lot more descriptive HTML tags, which are designed to provide additional information to the end user regarding the type of element they are viewing, while enabling more descriptive code which enables developers to more easily decipher new code block/snippets, which in turn increases productivity and the efficiency one can alter existing components. 

Here’s the markup for a progress bar widget: ~ snippet taken from Developer.Moziila

<div id="percent-loaded" role="progressbar" aria-valuenow="75"
    aria-valuemin="0" aria-valuemax="100">
</div>

Here we have a progress bar and it is built using a `<div>`, which actually gives the user no meaning. Currently HTML5 has new inbuilt tags that allow you to break up your elements with more meaning, but unfortunately, a lot of the time there isn’t a more semantic tag available for developers to use HTML4 or 5, so we need to include ARIA roles and properties. 

In this example, we are adding specified attributes to the element such as the `role=”progressbar”` attribute, which notifies the browser that this element is a Javascript driven progress bar widget. The `aria-valuemin` and `aria-valuemax` attributes specify the minimum and maximum values of the element, and the `aria-valuenow` expresses the current state of the progress but, so this must be kept in sync with the JavaScript.

Screen Reader Specific CSS Classes

There are occasional instances where content should be made available to screen reader users, but hidden from sighted users. In the vast majority cases, content that is available visually should be available to screen reader users, and vice versa. Cases where verbose cues or instructions are provided only for screen reader users are most likely a reflection of poor design, usability, and accessibility. However, there are a few cases where information or meaning is apparent visually, but may not be apparent to screen reader users. In these rare cases, it may be appropriate to cause content to be read by a screen reader, but remain invisible to sighted users.

Techniques for hiding content 

There are several mechanisms that can be used for hiding content. It’s important that a technique be implemented that results in the desired outcome and accessibility.

/* Text meant only for screen readers. */
.screen-reader-text {
  border: 0;
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  width: 1px;
  word-wrap: normal !important;
}

Here is a few approaches of embedding additional information for the user to utilise

  • `display:none` or `visibility: hidden`
display:none;
// or
visibility: hidden;
  • hidden attribute
<p hidden></p>
  • `width:0px`, `height:0px` or other 0 pixel sizing technique
width: 0px;
height: 0px;
  • `text-indent: -10000px;`
text-indent: -10000px;
  • Absolutely positioning content off-screen
.sr-only {
  position:absolute;
  left:-10000px;
  top:auto;
  width:1px;
  height:1px;
  overflow:hidden;
}
  • The `.sr-only` CSS class, which stands for  “screen reader only”, is just an abrtiory name and can be called anything you wish, but whatever you name this should then be referenced from within the tag of the element being hidden, as shown:
<div class="sr-only">This text is hidden.</div>

For more information regarding these techniques, please visit WebAim.org

Resources for Online Accessibility Audits

The following is a list of websites and web tools that are built to help you plan, design and also evaluate any accessibility flaws that may have been overlooked in the development of your current site. 

Most of these tools are free (at an entry-level anyway) and if nothing else can evaluate and provide feedback into any website that is currently live on the internet and include tools that can help evaluate colour contrasts, HTML structures / markup that could be improved to ensure small, and sometimes large wins in regards to increasing accessibility compliance.

There are many tools and services available at www.w3.org/WAI/ER/tools, but a lot are actually links to businesses trying to entice you to let them assess & implement your accessibility upgrade, so finding the hidden-gems that are free can be a little painstaking. So here is shortlist we recommend:

Accessibility Evaluation / Compliance tools & helpers: 

Best Practice Examples of Accessible Websites

Here, in no particular order are some examples of websites that meet a high accessibility standard and still look modern, fun and/or are highly functional: 

Based on what you’ve just read above, take a look at these websites and let us know what accessibility features you can find. Post a comment below or reply back to info@aceik.com.au

Technical Legalities around Accessibility

More and more cases are starting to surface regarding end-users suing companies for negligence in regards to not adhering to Accessibility compliance, which means your organisation’s website could be at risk without you realising it. The reality here is, you are not alone.  

Here are some related statistics regarding Accessibility Laws and also some examples of what has happened in the past when an end-user of these websites decides to take these companies to court, in regards to failure to comply with these laws and the needs of individuals with disabilities.

Some surprising statistics regarding Accessibility Law

  • In the UK alone, on average 70% of websites are not compliant with accessibility laws. Globally, around 10% of the world’s population (650 million people) live with a disability. As life expectancy increases, this number is also expected to grow.
  • 92% of the most popular federal websites fail to meet basic standards for accessibility, says a study from the Information Technology and Innovation Foundation

Accessibility related Legal Case Studies in the US

  • In January 2019, Beyoncé Knowles’ company, Parkwood Entertainment, became the defendant in a class-action lawsuit alleging that it violated the Americans with Disabilities Act (ADA). The suit, filed by a blind woman from New York, claimed that the company’s website, Beyonce.com, did not provide accommodation for people with significant vision impairments, leaving an estimated 2 million blind people and others with vision impairments unable to access the primary portal for news about all things Bey.
  • A blind man filed a lawsuit against Domino’s in September 2016 and claimed that he was unable to order customized pizza or take advantage of online-only discounts because both the website and mobile app wouldn’t work with his screen reading software. Neither the website or app met basic Web Content Accessibility Guidelines (WCAG) and a judge ruled in favor of Guillermo Robles, the man who filed the lawsuit.
  • A class action lawsuit was filed in January 2018 against Burger King by a visually-impaired woman. The individuals involved were using screen reading software to understand and interact with the website. Because there were no alt-tags or other features in place, the individuals reached significant barriers in accessing basic information on the website.

Accessibility related Legal Case Studies in Australia

  • Coles.com.au – Closer to home, a case originated in early November 2014 where coles.com.au was sued by disability-user who claimed that she was being discriminated against in regards to being able to access the website ~ Please follow these related article links: Coles lawsuit Article 1, Coles lawsuit Article 2
  • 2000 Sydney Olympics – On the 7th June 1999, The Maguire Law Firm made a complaint to the Human Rights & Equal Opportunity Commission (HREOC), alleging that the Sydney Organising Committee for the Olympic Games (SOCOG) had discriminated against him as a disbled person, in contravention of the Disability Discrimination Act 1992 in three aspects: 
    • The failure to provide braille copies of the information required to order Olympic Games tickets
    • The failure to provide braille copies of the Olympic Games souvenir programme, and
    • The failure to provide a website which was accessible to Maguire

After the completion of the ticket book case (Maguire v SOCOG 1999 ) on 30 September 1999, conciliation on the remaining matters was attempted but by 29 November 1999, the talks failed. ~ This information taken from Wikipedia

Aceik – Current Accessibility Examples 

We thought it best to highlight a couple of examples from our current clientele that highlight some great development-integration accessibility pieces that we have had the honour of implementing of late:

  • The City of Yarra Council – https://www.yarracity.vic.gov.au/
    • Including features such as a fully keyboard function navigation, the ability to increase website text-sizes, print-friendly page options have been included, multi-language selection abilities, clearly highlighted link focus states and whole range other accessible consideration can be found throughout this website.
  • Chisholm Institute of Tafehttps://www.chisholm.edu.au/
    • Once again the navigation here is completely keyboard accessible, link focus and hover-states are clearly highlighted, colour contrasts have been carefully  considered, images are clearly labelled and media accessibility has also been considered, this allowing users multiple methods to access non-written media.

Personal notes from the author

In closing, personally I have researched this topic for years, and to my knowledge no one document or article pulls together all related facets (and so extensively) on this subject matter as I have attempted to do here, hence why I have made this quite a lengthy piece. 

It really is a massive topic to cover and there are so many angles one needs to consider to gain a holistic understanding that will empower/compel business-owners and stakeholders to justify the additional effort, cost and benefits associated with implementing extensive and well planned Web-Accessibility, so I hope this helps to empower not only business owners, but also educates and increases the level of Website Development standards, industry wide.

Article Resources

Next Gen Image Compression in Sitecore

Spoiler: This post is not a post about Dianoga, I take a deep dive into Tiny PNG and Kraken.IO integrations into Sitecore. The results are worth checking out at the bottom.


At the start of the year, I’ve picked up where I left off, on page speed. Last year I took a deep dive into attempting to improve the page speed on Sitecore SXA sites by using some of Google’s recommended techniques to structure the page. If you haven’t already seen it, head on over the Sitecore Speedy and see some of the results we achieved.

I’ll be the first to admit that getting really good page speed scores isn’t easy. It takes a lot of different factors to come together. Just as a reminder, here is the main list that I would consider you need to check off to be winning at this game.

1) Introduce image lazy loading

2) Ensure a cache strategy is in place and verify its working.

3) Dianoga is your friend for image compression

4) Use responsive images (must serve up smaller images sizes for mobile)

5) Introduce Critical CSS and deferred CSS files

6) Javascript is not a page speed friend. Defer Defer Defer

For this post, i’m going to look at an alternative to Dianoga. I’m a big fan of Dianoga and have used it over the years to crunch loads of oversized images introduced by Content Editors. I will, however, say that it can add complexity to deployments and CI/CD pipelines and while some claim to have had success in Azure Apps, others have not.

On the flip side, content editors love Tiny PNG, which is one of the most popular image compression website utilities going around. Tiny PNG also has a developer API, so we have used this to build in a compression tool that can be used directly from your Sitecore toolbar.

The button below is hooked up to chat to Tiny PNG API. It will send across your image data and receive a compressed image back for storage.


Full disclosure, I’m not the first person to hook up Tiny PNG to the image library. I could find two other implementations

One will allow you to run a powershell script to connect to the Tiny PNG API and the other is a module to connect to the API on upload.


This implementation of the Tiny PNG API introduces the following variances:

  • A button in the CMS to crunch any single image.
  • A scheduled task that will process any image not already processed.
  • Error handling for when the API limits are reached
  • Logging that outlines which images were processed.
  • Before and After compression information stored in any Image field of choice.
  • A feature toggle to turn the whole feature on/off

All the source code is available at: https://github.com/Aceik/ImageCompression

Now let’s jump in have a look at the results just from crunching a few images down:

Without image compression:

Click to Enlarge Image

To compress the images on the page, we head on over to the “Compress” button in the Media tab that we have introduced.

Click to enlarge

A few examples of compression results taken from homepage images:

Before: 158.4 KB | After: 110.6 KB

Before: 197.8 KB | After: 135.3 KB

Before: 640.0 KB | After: 120.7 KB

After compressing all the images on the page the saving can be seen below.

Click to enlarge

So our total image size saving is 2.4MB – 1.3MB = 1.1MB

A pretty decent saving from just pressing the compress button on 27 homepage images. Also, consider that the user won’t notice any difference in image quality as this method uses lossless compression.


The compression achieved is great for helping us tick off one of the requirements for fast pages with Google. But as we are about to find out Google will likely still complain about two other criteria. When it comes to Google Page Speed insights a page that does not have properly processed images will bring up the following three recommendations:

Here is a break down of how we address each one:

  1. Serve image in next-gen formats – Image formats like JPEG 2000, JPEG XR, and WebP often provide better compression than PNG or JPEG, which means faster downloads and less data consumption. Learn more.
  2. Properly Size images – Your CSS layouts should be responsive and use modern image retrieval techniques that adapt the image size requested based on screen size. Read More
  3. Efficiently encode images – The Tiny PNG integration above will take care of this. This is all about compressing the image to as small as it can get without a visible loss of quality.

So assuming you have already achieved number three using the Tiny PNG integration or another source, let us look at how we can solve the next-gen image requirement.

As a quick side note the testing I did after converting the images to next-gen also ticked item number two above. I don't think this should be relied on however and its best to incorporate responsive images into your projects from the beginning.  

When looking into how to convert images to a next-gen format I opted to target webp. Google has a nice little page explaining the format here.

WebP is natively supported in Google Chrome, Firefox, Edge, the Opera browser, and by many other tools and software libraries.

Once again I opted to look for an API that would provide the conversion for me so that Sitecore could easily connect, send the image and then store the result. All without any extra hosting requirements. I opted to go with Kraken.IO image APIs as they have a free 100MB trial offer and well free is a good price when building proof of concepts. The integration is all available on Aceik’s github repository. Just signup for your own API keys add them to the module settings (in the CMS) and start converting.

To test out just how much this would impact the image payload size for the whole page, I once again converted all the images on the SXA habitat homepage.

Here are the results:

Click to enlarge

So our total image size saving is now 2.4MB – 0.79MB = 1.61MB

The reduction in size from a non-compressed image to a webp formatted image is truly impressive.

A few examples:


Conclusion

I can only conclude by saying that if page speed is really an important factor for your Sitecore project take a look at Tiny PNG. If you want to go next level with your image formats and achieve great compression try out the Kraken.IO API integration as it could be well worth the small subscription fee.


Results

CompressionTotal Image SizeSaving
None2.4 MB
Tiny PNG1.3 MB1.1MB
Kraken.IO (webp)0.79MB1.61MB

Notes:

The module and code mentioned in this blog post are available on Aceik’s Github account. This also contains installations instructions.

GitHub: https://github.com/Aceik/ImageCompression

After installation, your content editors will simply be able to compress and convert images as needed from within the CMS.

Click to enlarge

The Github Readme contains a run down and the standard settings inside Sitecore as shown below:

Accessing the JSS Dictionary in C#

This is a quick post to guide developers through gaining access to the JSS Dictionary in the backend C# code.

Why would you want to be able to do this?

The reason we originally had to do this was that our JSS Angular application had editable content from the dictionary that we also wanted to access in C#. In our particular case, it was to inject the content into an email template that would be sent to the user. To save duplicating content it made sense for both the front end and C# to have access to the same dictionary.

Where do we start?

The following assumes you have a Sitecore instance with JSS installed and a JSS application you are working on. Grab your favourite de-compilation tool (I use ILSpy) and locate the following DLL in the bin folder of your running Sitecore instance:

Sitecore.JavaScriptServices.Globalization.dll

Once you have that open in ILSpy you want to have a search for DictionaryServiceController

public class DictionaryServiceController : ApiController

The following method is what we want to use in our C# code:

public DictionaryServiceResult GetDictionary(string appName, string language)

It takes the unique application name (that belongs to your application) and the language (“en”) as a parameter. As a result, you will get back a dictionary object that you can use to lookup up your content.

This is the Controller that would normally be called via an API on the front end. So how do we call it from normal C# service for instance?

Firstly, the controller has a constructor that has three parameters that are injected via DI (Dependency Injection).

IConfigurationResolver configurationResolver, 
BaseLanguageManager languageManager, 
IApplicationDictionaryReader appDictionaryReader

Using ILSpy once again you can find that the above three parameters are all set up in the DI container via RegisterDependencies.cs in various JSS assemblies. The Controller itself is already registered in the DI Container as well, which is very handy.

If you have a look at showconfig.aspx in the admin tools you can see that a lot of the dependencies are registered via RegisterDependencies.cs

For example:

<configurator type="Sitecore.JavaScriptServices.AppServices.RegisterDependencies, Sitecore.JavaScriptServices.AppServices" patch:source="Sitecore.JavaScriptServices.AppServices.config"/>

Dependency injection is a whole other topic so I will leave that to your personal preference as to how you achieve it. For the purposes of the following complete code example, I have used the Services Attribute style setup. If you want to keep consistency with Sitecore you could also setup via the RegisterDependencies.cs class of your own and use a patch file to kick it off.


Example Service:

using Sitecore.Foundation.DependencyInjection; // Borrowed from habitat
using Sitecore.Diagnostics;
using Sitecore.JavaScriptServices.Globalization.Controllers;

namespace Sitecore.Foundation.JSS.Services
{
    public interface ITranslationService
    {
        string TranslateKey(string key);
    }

    [Service(typeof(ITranslationService), Lifetime = Lifetime.Transient)] 
    public class TranslationService : ITranslationService
    {
        private readonly DictionaryServiceController _controller;
        
        public TranslationService(DictionaryServiceController controller)
        {
            this._controller = controller;
        }

        public string TranslateKey(string key)
        {
            var dictionary = GetDictionary();
            if (dictionary.phrases.ContainsKey(key))
                return dictionary.phrases[key];
            Log.Error("Dictionary key {key} not found", this);
            return string.Empty;
        }

        private DictionaryServiceResult GetDictionary(string appName = "myAppName", string language = "en")
        {
           return _controller.GetDictionary(appName, "en");
        }
    }
}

Above is a simple service that can be used from just about anywhere in your C# code.

Simply change the appName and language as required to access the correct JSS dictionary. Also, remember to publish your app dictionary to the web database or you may get no results.


There we have it, accessing the JSS dictionary from C# in a nutshell. I hope this helps some other folks get this done quickly on JSS builds.

An Introduction to Sitecore Pipelines

What is a Sitecore Pipeline?

In Sitecore pipelines describe a series of discrete steps that are taken to achieve some objective.  If you think about writing code to handle an HTTP request for example you could create a monolithic class that does the job from end to end; however the pipeline approach is a number of classes that can be invoked in order.  First do this and then do that etc. 

There are many Pipelines in Sitecore.  You can view existing pipelines and the processors that they call using Sitecore Rocks in Visual Studio.  Right click on the site connection and choose Manage. Click on the Pipelines tab in the Visual Studio edit pane.  Click on one of the listed pipelines to see all the processors that are executed as part of the pipeline.  There are pipelines with a single processor at one end of the scale to the httpRequestBegin pipeline with 45 distinct steps at the other.

Why are they useful?

Thinking about the monolithic class above it would be very difficult to maintain or modify, It would also be truly massive.  So modularising it would make it much easier to maintain. 

It also makes it much easier to customise.  For example, if we consider a pipeline that has three processors it might be drawn something like

To add to the existing functionality we could include a new step like

Where we add some custom function after Step 1 and before Step 2. 

We could also replace an existing step completely

How are they defined?

Pipelines are defined using XML in sitecore.config.  In the example below we can see the httpRequestEnd pipeline definition.  The three processors are called in the order in which they are listed.  A parameters object is passed between them to provide continuity.  The final processor is also receiving four additional parameters from the config file.

<?xml version="1.0" encoding="utf-8"?>
<sitecore database="SqlServer" xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:security="http://www.sitecore.net/xmlconfig/security/">
…
<pipelines>   
… 
<httpRequestEnd>
      <processor type="Sitecore.Pipelines.PreprocessRequest.CheckIgnoreFlag, Sitecore.Kernel" />
      <processor type="Sitecore.Pipelines.HttpRequest.EndDiagnostics, Sitecore.Kernel" role:require="Standalone or ContentManagement" />
      <!--<processor type="Sitecore.Pipelines.HttpRequest.ResizePicture, Sitecore.Kernel"/>-->
      <processor type="Sitecore.Pipelines.HttpRequest.StopMeasurements, Sitecore.Kernel">
        <ShowThresholdWarnings>false</ShowThresholdWarnings>
        <TimingThreshold desc="Milliseconds">1000</TimingThreshold>
        <ItemThreshold desc="Item count">1000</ItemThreshold>
        <MemoryThreshold desc="KB">10000</MemoryThreshold>
      </processor>
    </httpRequestEnd>
…
    </pipelines>
…
  </sitecore>

How can I work with Sitecore Pipelines?

Existing Sitecore pipelines can be customised as outlined above and it is also possible to create a brand new pipeline from scratch

Customise existing Pipelines

First thing to do is to create a configuration patch to add the new processor class into the pipeline at the desired location.  As you can see from the code it is possible to pass variables to the processor.  Here we are adding a processor called NewsArticleLogEntryProcessor into the httpRequestBegin pipeline after the ItemResolver

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <httpRequestBegin>
        <processor type="Fourbyclub.CustomCode.CustomCode.Pipelines.httpRequestBegin.NewsArticleLogEntryProcessor,Fourbyclub.CustomCode" patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel']">
          <NewsArticleTemplateID>{B871115E-609F-44BB-91A4-A37F5E881CA6}</NewsArticleTemplateID>
        </processor> 
      </httpRequestBegin>
    </pipelines>
  </sitecore>
</configuration>

Then we need to create the processor.  Inherit the HttpRequestProcessor and Implement the Process method.  All we are doing here is writing to the log if the requested item is a NewsArticle.

namespace Fourbyclub.CustomCode.CustomCode.Pipelines.httpRequestBegin
{
    using Sitecore.Pipelines.HttpRequest;
    using Sitecore.Diagnostics;

    // TODO: \App_Config\include\NewsArticleLogEntryProcessor.config created automatically when creating NewsArticleLogEntryProcessor class.

    public class NewsArticleLogEntryProcessor : HttpRequestProcessor
    {
        
        // Declare a property of type string:
        private string _newsArticleTemplateID;
        public string NewsArticleTemplateID { get { return _newsArticleTemplateID; } set { _newsArticleTemplateID = value; } }

        public override void Process(HttpRequestArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            if ((Sitecore.Context.Item != null) && (!string.IsNullOrEmpty(_newsArticleTemplateID)))
            {
                Assert.IsNotNull(Sitecore.Context.Item, "No item in parameters");
                // use util to get id from string property
                if (Sitecore.Context.Item.TemplateID == Sitecore.MainUtil.GetID(_newsArticleTemplateID))
                {
                    // view in log file later, so add FourbyclubCustomCode
                    Log.Info(string.Format("FourbyclubCustomCode: News Article requested is {0} and the item path is {1}", Sitecore.Context.Item.DisplayName, Sitecore.Context.Item.Paths.FullPath), this);
                }
            }
        }

    }
}

Create a new Pipleline

To create and new pipeline is a little more work but still very simple.  The first thing to do is to declare the pipeline with a configuration patch

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <logWriter>
        <processor type="Fourbyclub.CustomCode.CustomCode.Pipelines.logWriter.logWriterProcessor,Fourbyclub.CustomCode" />
      </logWriter>
    </pipelines>
  </sitecore>
</configuration>

The XML above will create a pipeline called logWriter that has a single processor called logWriterProcessor, which will be in the Fourbyclub.CustomCode.dll.

Pipelines must pass a PipelineArgs object to each processor as it is called so that needs to be defined

using Sitecore.Pipelines;

namespace Fourbyclub.CustomCode.CustomCode.Pipelines.logWriter
{
    public class LogWriterPipelineArgs : PipelineArgs
    {
        public string LogMessage { get; set; }
    }
}

At least one processor is needed to do the work of our pipeline

using Sitecore.Diagnostics;

namespace Fourbyclub.CustomCode.CustomCode.Pipelines.logWriter
{
    public class logWriterProcessor
    {
        public void Process(LogWriterPipelineArgs args)
        {
            Log.Info(string.Format("FourbyclubCustomCode: The message was {0}", args.LogMessage), this);
        }
    }
}

Finally we need to invoke the pipeline in our code somewhere.  Instantiate the LogWriterPipelineArgs and set the LogMessage.  Then call CorePipeline.Run and pass it the name of the pipeline and the args.object

var pipelineargs = new LogWriterPipelineArgs();
pipelineargs.LogMessage = "Requested item is not a News Article";
CorePipeline.Run("logWriter", pipelineargs);

Conclusion

Thank you for reading and I hope that this short introduction to Sitecore Pipelines has shown the power of pipelines to customise Sitecore and help to build maintainable code.  However we should always check if there is a way we can implement something using existing Sitecore functionality rather than going for a pipeline as a first resort. As with any customisation does each pipeline or processor added have a potential to increase the challenge of Sitecore upgrades?