Mar 13 2018
Mar 13

Here at Appnovation, we live, love and breath all things Drupal, so it should come as no surprise that Drupal 8 is a big deal to us. With a cast list of over 3,000 contributors, Drupal 8 is a testament to the open source community, in which we have an active role, our dedication, and the ever-increasing popularity of open technologies in general. 

So, let's take a look at some of the main reasons why companies and corporations are increasingly chosing to either migrate or upgrade to Drupal 8...

1) Semantic Versioning (http://semver.org/

Drupal 8 now uses semantic versioning. This meant that, with major, minor, and patch releases, we will always know if there are bug fixes, new features, or API breaking changes. Simply superb, just like Drupal 8.

2) The Release Cycle

A new minor release is launched every 6 months. This means, in simple terms,  that we don't have to wait 5 years to get new features into core. Time, cost and all around efficiency. Drupal 8 delivers again.

3) “Getting off the island”

Reference: http://www.garfieldtech.com/blog/off-the-island-2013)

Drupal now uses lots of code that wasn’t initially written, or invented for use with Drupal. In essence, it’s just good, standard code from the wider PHP community. This allows flexibility of development, never a bad thing. Drupal development continues to offer even more flexibility for users and developers alike.

Another added advantage, is the presence of ‘small’ updates, meaning that there are fewer things you need to test – i.e. going from D7→ D8 could be quite a leap, but with multiple, smaller updates throughout the year, it makes things much easier to manage (like cooking a lobster, slowly boiling the water, if you will).

4) Object Orientated

Much of the code is now object orientated, a lot of this being due to "getting off the island".

5) Views in Core

Views is the most used Drupal module, in fact, it’s a key building block to how Drupal functions, and stands head and shoulders above other CMS’s, so it makes a lot of sense that it has now been moved into core… so it's used ‘out of the box’.

Drupal 8 list image.jpg

6) Plugins, Events, & Services

These are all new concepts in Drupal 8, when writing modules it gives a whole new scope of how to build things.

7) Configuration Management

Drupal has always suffered from configuration living in the database alongside content, but Drupal 8 changes that…for the better. Configuration can now live in YAML files, and can also be managed along side code

8) Big Pipe

This is one of those features we could add in a minor release and was added in 8.1.0. Big Pipe is a concept from Facebook (https://www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/389414033919/) to build faster loading pages.

9) Time to Migrate

To help people move from Drupal 6 or Drupal 7, Drupal 8 adds basic migration.

It’s that simple, we’re not sure why you wouldn’t want to do it!

10) Twig Templates

Previously the front end was written in PHP frontenders don't like php. Twig is a lot better. http://twig.sensiolabs.org/

To read more about the Drupal 8 revolution, download our free D8 eBook: 

https://www.appnovation.com/resources/ebook/drupal-8-developed-deliver-drupal-domination

Feb 22 2018
Feb 22

This is the last post of my quick Headless journey, in the first one I approached the concept of Headless and presented some solutions like Drupal, GraphCMS, Contentful and Cockpit CMS. In the second one, I extended those concepts by detailing Cockpit CMS, mostly due to the simplicity of the admin interface and the way that we deal with common operations like creating a content type and manage his contents.

This post will culminate with the last but not less important piece, the frontend layer, where we interact with the CMS API to retrieve or send contents.

As explained in the first post, when using a Headless approach we are not anymore restricted by the CMS in terms of presentation, we can deal with it as we want, our only compromise is on following the API data contract, usually in a form of JSON structured data.

So to implement a website quickly and at the same time dynamic, modern, robust, and easy to maintain I suggest React JS as it provides all the mechanisms that we need, and by doing a very simple website, components based, I hope to convince you.

The below diagram illustrates how the contents are organized in Cockpit and React:

For each Cockpit collection, I have a corresponding React component, the Basic Page collection corresponds to a Basic Page component that is responsible for handling the navigation pages. All other collections have also a corresponding React component.

Above screenshot illustrates my collections on Cockpit and they are corresponding on React to their counterparts:

On React when the App is initialized, I fetch the Basic Pager collections using the /api/collections/get/basicpage?token=xxtokenxx endpoint.

componentDidMount() {
   if (this.props.pages.length === 0) {
     this.props.fetchPages.fetchCollection();
   }
 }

The fetchCollection() is defined in the actions:

export function fetchCollection(collection) {
 return dispatch => {
   return fetch(getCollectionUrl('basicpage'), {
     method: 'post',
     mode: 'cors',
     body: JSON.stringify({
       filter: { published: true },
       populate: 1,

       simple: 1,
       limit: 50,
     }),
     headers: {
       'Content-Type': 'application/json',
     },
   })
     .then(response => response.json())
     .then(json => dispatch(parsePage(json)));
 };
}
 

The fetchCollection() will set the pages as an array of objects, where each item corresponds to a Basic Page collection, that structure is exemplified as below:

Having all the basic pages it’s enough to build the navigation menu. I have an attribute on the basic page that defines if it should be displayed on the main menu or not:

The navigation menu links are created and they will be used on the NavigationBar component that will display them as links. The pages are passed down to a component that will build the React Routes:

class App extends Component {
 componentDidMount() {
   if (this.props.pages.length === 0) {
     this.props.fetchPages.fetchCollection();
   }
 }

 render() {
   const pages = this.props.pages;
   const links = [];

   pages.map(
     (entry, idx) =>
       entry.menu &&
       links.push({
         title: entry.title,
         content: entry.body,
         path: (idx === 0 && '/') || `/${entry.title_slug}`,
       })
   );

   return (
     <ConnectedRouter history={history}>
       <div className="App">
         <Grid fluid>
           <Row>
             <Col xs={12}>
               <NavigationBar
                 title="Cockpit React Example"
                 links={links}
               />
             </Col>
           </Row>
           <Row>
             <Main pages={pages} />
           </Row>
         </Grid>
       </div>
     </ConnectedRouter>
   );
 }
}


So for each received page I only need to inspect the components field (Multiple Link Collection), that field includes the components for that page and for each one I have a mapping that will dynamically include the React component:

import React from 'react';
import PropTypes from 'prop-types';

const componentsConfig = [
 {
   name: 'banner',
   component: require('../../components/Banner').default
 },
 {
   name: 'faq',
   component: require('../../components/Faq').default
 },
 // (...)
];

let dynamicComponents = {};
for (var i = componentsConfig.length - 1; i >= 0; i--) {
 dynamicComponents[componentsConfig[i].name] = componentsConfig[i].component;
}

const Components = props => {
 return (
   <div>
     {props.components.map((collection, idx) => {
         if (dynamicComponents.hasOwnProperty(collection._link)) {
           let Component = dynamicComponents[collection._link];
           return (
             <div key={`${collection._link}-${idx}`}>
               <Component {...collection} />
             </div>
           );
         }
       })}
   </div>
 );
};

Components.propTypes = {
 components: PropTypes.array
};

export default Components;


My BasicPage component just needs to make use of the above Components React component passing as a prop the array of Linked Collections:

import React from 'react';
import PropTypes from 'prop-types';
import Components from './Components';

const BasicPage = props => {
 return (
   <div className="components">
     <Components components={props.data.components} />
   </div>
 );
};

BasicPage.propTypes = {
 idx: PropTypes.number,
 data: PropTypes.object,
};

export default BasicPage;

This seems to result really simple and nice and fulfill my needs of having the Cockpit collections being rendered as React components. Extending it a bit further with some libraries like:
 

  • Prettier - Code formatter that enforces a consistent style by parsing your code and re-printing it with its own rules that take the maximum line length into account, wrapping code when necessary. In the example code that I provide I have a git pre-commit hook that runs prettier every time a commit is performed doing auto-formatting of the code. There are also Prettier addons for editors like VSCode or Sublime Text.

  • Redux - Predictable state container for any Javascript view library like React.

  • History - Minimal API that lets you manage the history stack, navigate, confirm navigation, and persist state between sessions.

  • React Router - React Router is a collection of navigational components that compose declaratively with your application.

  • Material UI - Library that provides React components that implement Google's Material Design (http://www.material-ui.com).

  • Flexbox Grid - A set of React components that implement flexboxgrid.css (http://flexboxgrid.com)

  • React Slick - React port of the slick carousel plugin (http://kenwheeler.github.io/slick/).

  • React Markdown - Render Markdown text as React components (https://github.com/rexxars/react-markdown).

...and we have everything that we need to render the components in a responsive and modern layout as you can observe in the following screencast:

https://youtu.be/lGzIJKcp-d4

<iframe width="560" height="315" src="https://www.youtube.com/embed/lGzIJKcp-d4" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

The final example website can be accessed at  https://pauloamgomes.github.io/cockpit-react-example/

Project code can be accessed at https://github.com/pauloamgomes/cockpit-react-example

Conclusions

My main purpose with above implementation was to explain the simplicity and flexibility we have when handling a Headless CMS in combination with a Javascript library like React JS. However, and as you can understand, in the real world things may be not so simple as I described, and some further work may be required, but that is what we face everyday, understand the needs and make all the things pretty and functional, and at same time having some fun on the work we do.

Feb 20 2018
Feb 20

Drupal is really good at allowing the user (developer) manipulate its data.

It’s very common to override templates for nodes and views in D7, but in Drupal 8, it’s been made even easier to override templates at every level.  I found I was writing a lot less pre-processors on a D8 project versus D7. 

On a recent project, and I’m sure the majority of projects, Node and View templates will need to be overridden.  For nodes, it’s pretty much the same as before and very easy to find documentation.  Simply copy the base template and create a new file with this pattern:

               node--[type|nodeid]--[viewmode].html.twig

It’s really useful when you have multiple view modes.  For example, my recent project used the default view mode for a full page and a custom “Card” view mode for Views.

David Drupal Blog_0.JPG

On Views (D7), I use to output data with fields and override the View template at the row level for theming. 

D8, I found it more efficient to output data as Content then select the view mode.  For this approach, I reuse the node “Card” display and only worry about the wrapping DIVs from the view.  At most I would be adding some classes to the View’s row template, everything else about the content itself comes from the node card template.

               Container - views-view--[viewname].html.twig

               Row - views-view-unformatted--[viewname]--[displayname].html.twig

I also found I’ve used field template overrides more often than before.  It was useful when adding Bootstrap classes to fields for positioning or implementing other components such as tabs or carousels.  

Drupal.org has a list of twig naming conventions here for all entities that can be customized here

[https://www.drupal.org/docs/8/theming/twig/twig-template-naming-conventi....

The best way to find all the layers of template suggestions is to enable debug mode.  There’s a great step-by-step on Drupal.org that outlines how to enable twig debug mode as well as disable caching while you develop

[https://www.drupal.org/node/2598914]

Once this is enabled, inspect your page and you’ll find that every level of HTML will have a block of comments.  If you’re looking at a View, you’ll find all the suggestions for each level (container, row, node, field). 

In my opinion, this has made development a lot easier and efficient, minimizing the need to write code that will only be used in specific scenarios.  Hope this helps anyone that’s looking to start a new project!

Feb 13 2018
Feb 13

Using Cockpit CMS

In my previous post, I presented some Headless CMS solutions and suggested using Drupal mostly due to the content editorial capabilities and flexibility. Drupal can be leveraged as a vanilla solution or in a distro flavor (e.g. Contenta, Reservoir). I also approached Cockpit CMS, because it's a pure Headless CMS that is open-source, simple, with a great UI and provides the basis for starting a Headless website.

So the purpose of this post is to give you an overview of Cockpit, in terms of installation, configuration,  the core concepts and how to retrieve contents. In my next post of that series, I'll provide the last piece in form of a simple website implemented in React and that can consume dynamically the contents available on Cockpit.

Cockpit CMS

Cockpit comes in two flavors, Official Release, the most stable or Preview, also known as Next. All examples I am providing here are based on the Next branch.

Requirements

Humm! Quite simple, right? Yes, as you can see, no generation or build scripts, or heavyweight PHP libraries or dependencies. It means that Cockpit can run with low resources.

Installation

The installation is a straightforward process, just extract to your docroot folder and point the browser to http://<yourdomain>/install, no configurations are required during the installation, you are redirected to the login page and can login using admin/admin (better to change the password after the first login).

A docker compose file is also provided, so if you want to try the docker version just run:

docker-compose up -d

Usage and Core concepts

Cockpit is based on the below main concepts:

  • Collections

  • Regions

  • Forms

  • API

  • Webhooks

  • Collections

  • Addons

Collections

Collections are probably the most important, they can be compared with content types on Drupal, a collection can define any piece of information (e.g. Page, a Product, etc..) so as a node in Drupal, a collection contains fields. Cockpit provides already a complete set of field types:

Asset, Boolean, Code, Color, Color Tag, Date, File, Gallery, HTML, image, Layout, Layout Grid, Location, Markdown, Multiple Select, Object, Password, Rating, Repeater, Select, Set, Tags, Text, Textarea, Time, wysiwyg (html editor), Collection Link

Above list is probably more than enough for most of the business cases to define a content type, however, if you require something different you can extend them by providing your own field types.

Something that can seem a bit weird is that the definition of the field attributes is a plain JSON object! Yes, it is, however, I don't see it as a big problem, in fact for me it worked better I was able to define all the attributes of a field quicker than using a step based UI. Something that helps is to have the docs in hand (https://getcockpit.com/documentation/reference/fieldtypes), so you can copy paste the JSON object directly from the template and do the modifications you need.

http://take.ms/MEStO


Defining the fields as JSON objects is something that I consider valuable, as it permits to update the fields easily if required.

Resuming, collections are the core of Cockpit in terms of structuring information, they can virtually represent any piece of information and Cockpit interface is powerful enough for developers and simple enough for non-technical users, the perfect wedding.

I will return further below in the article to collections as I pretend to demonstrate it's power by providing some examples.

Regions

Regions are editable contents and code snippets that can be re-used, for example, if we need a block of content for contacts that will display a list of contacts (e.g. phone number, e-mail, address) we can build a region named Contacts and access it using the API. One major difference to collections is that we can define templates for regions, however, I believe that by doing that we are corrupting the main headless concept, so I suggest to use them without templates.

Forms

Forms are available on the Next branch, however, they are not yet functional and no documentation is available. They look to seem a kind of special collection to be exposed as typical forms, a bit similar concept of webforms in Drupal.

API

The API is the core of the headless CMS, is the bridge between the client (application) and the contents. Cockpit provides a security layer based on API tokens, it's possible to define full access tokens, custom tokens that can interact with specific collections only or can only retrieve and not save data, or tokens that are user based.

Retrieving collections using the API and Javascript can be performed with one command:

fetch('/api/collections/get/basicpage?token=xxtokenxx', {
   method: 'post',
   headers: { 'Content-Type': 'application/json' },
   body: JSON.stringify({
       filter: {published:true},
       limit: 10,
       sort: {_created:-1}
   })
})
.then(res=>res.json())
.then(res => console.log(res));

On the above example we are retrieving the last 10 contents of type "basicpage" that have the field published = true.

Webhooks

Webhooks are reactive actions that can interact with 3rd party applications/services when something happens (e.g. after or before a collection is saved or a collection is removed). Let's imagine that we have a newsletter collection that collects an email and a name and we want to store that data in a google sheets document. We can create a webhook with a 3rd party service like Zappier (as it can interact easily with Google sheets) that is triggered every time that the subscription collection is saved. When triggered it will invoke the Zappier service with the saved data and Zappier will create a new entry in the configured Google sheet.

Addons

Like Drupal or other CMS, Cockpit can be extended by the installation of add-ons, basically, we need to follow a simple structure. An addon is a folder that should contain a bootstrap.php file where depending on the Addon functionality (e.g. It will provide Admin functionality or a REST endpoint) we need to provide the correct code to initialize it.

An addon implementation may require the understanding of Riot.js (http://riotjs.com) if it provides admin functionality and the Lime php micro framework (https://github.com/agentejo/lime) for example to handle events.


After playing a bit with Cockpit I implemented two new add-ons:

Conclusion and Next Steps

For me, the most interesting part of Cockpit is not on the features that are available but in the way they are, and mostly on the quickness of creating/updating collections. So taking that into consideration my next step is to build something usable and see how it really works to build a headless experience. To prepare that exercise I will be using React.js in the frontend as a consumer for Cockpit contents.

My simple exercise consists of a typical website that needs to provide:

  1. Creation of Basic Pages using a "componentized" approach, so instead of having a typical bunch of static fields like summary, body, etc, I have instead different components:

  • Banner

  • Text

  • Block of text with a CTA

  • FAQ section

  • Quote section

  • etc..

  1. Have a main menu and the ability to define the pages that should be visible in the main menu

  2. Responsive

  3. Easy to change the UI without touching Cockpit

Using a "Componentized" approach permits easily to have a relationship between the Collection and a React component, for example, if you pick The Quote section it can be described in Cockpit with two fields, one for the quoted text and other for the quote author, for the quoted text we can use a Markdown field and for the author we can use a simple text field. When retrieving the collection it will be represented in JSON as below structure:

[
   {
       "author": "Some Author",
       "name": "Quote - Homepage",
       "content": "Quo usque tandem abutere, Catilina, patientia nostra?",
       "_mby": "5a61396e7640edoc1261186187",
       "_by": "5a61396e7640edoc1261186187",
       "_modified": 1517826090,
       "_created": 1517347771,
       "_id": "5a70e3bb09cdddoc1719074663",
       "_link": "quote"
   }
]


On the client side, we can build a Quote stateless component, that has two props, the quoted text, and the author and finally render the markup. The below workflow represents the build of the component from the Cockpit collection until is rendered on React:

Pretty simple right! The same approach is applied to all other components, we have in Cockpit the content structure and in React we build the corresponding component, depending on the functionality of each and interaction with the user the React components can be stateful or stateless.

In my next post  the third and final part of this series, I’ll detail the React implementation, and will provide a full working example in React and Cockpit.

Feb 05 2018
Feb 05

I strongly believe that the path for innovation requires a mix of experimentation, sweat, and failure. Without experimenting with new solutions, new technologies, new tools, we are limiting our ability to improve, arresting our potential to be better, to be faster, and sadly ensuring that we stay rooted in systems, processes and technologies that are not current, or at least not as up to date as they could be.

As this three part blog will uncover, sometimes, progress is all about simplicity, and innovation can be delivered by not over-complicating the path to a digital solution.

So, on with part 1.....

Such a quest can be lots of painful, mostly because most of the times you'll fail, not that I consider it a failure in the real meaning of the word, but because you didn't achieve exactly what you were expecting. However, until you realize it as a failure you already won something, you increased your skills, you enriched your knowledge and, maybe on the next time you achieve completely your expectations.

But innovating can be also quite simple. For me, the simple fact of doing something different that you are used is already innovation.

Some years ago I was doing something in Photoshop and a friend of mine, designer, that was working with me, told to me: "Get up and get back a little and you'll see better what you are doing".

If you are a developer, its a bit of the same, sometimes just by switching to another language or experimenting with a different framework gives you some other perspective on the things.

Here at Appnovation, we are committed to our customers by providing the best implementations, by delivering in time, by fixing what is not working, but also to innovate, and share the results of such experiments. That's the purpose of my post, a journey that starts with a trending concept (Headless CMS) where I'm evaluating different solutions. Later in further posts, I'll add more detail by providing a practical example of leveraging Cockpit CMS and React.

Headless CMS

A Headless CMS is not an entirely new concept, however, only recently it gained traction with a bunch of interesting solutions. It's defined in Wikipedia as "A Headless CMS is a back-end only content management system (CMS) built from the ground up as a content repository that makes content accessible via a RESTful API for display on any device."

So, what above differs from the traditional CMS we are used? Basically that the headless solution is only responsible for the architecture of the contents, how they are composed and how they are related, not how they should be presented.

A typical Headless CMS provides an Admin interface to define the content structure and to create/edit/update/delete the corresponding contents, and a RESTful API used to expose those contents in a way they can be easily consumed by an application (e.g. Website, Mobile App, etc..). Resuming the presentation layer is discarded and the focus is on the contents. That approach can result in more freedom for the designers and frontend developers, as they are not limited by the typical constraints of the CMS. Moreover, it provides the ability to switch easily between designs or provide better UX across different devices.

Headless CMS solutions

There are plenty of solutions, in different forms and flavors, open source/free or commercial, self-hosted or cloud-based, simple or more advanced, it's like suddenly we shifted from half dozen well established traditional CMS to some dozen of new providers that promise to shake the usually "slow to adapt" CMS scene.

Some time ago, like any other curious web developer, I decided to take a look at those contenders and see what they are able. My purpose was mainly to have a high-level understanding of each one, to see how they deal with the contents from the conception of the content structure to the editorial part and how they can be consumed using a REST client.

My criteria were in fact very simple:

  1. Quality of the project page, availability of documentation

  2. Is free/open source or commercial, price?

  3. Easiness of installation, availability of docker image, can be self-hosted?

  4. Admin UI

  5. How to define content structures

  6. How to use the API to consume contents

I will not enter into the detail of the above exercise because is not the purpose of this article (maybe something for another post), for now only a few insights on some of the solutions that I analyzed:

Drupal - https://www.drupal.org

Well, having Drupal as the first option think it is a bit obvious, I work with Drupal for some years, I love it, and from my perspective is the most capable open-source CMS/CMF in the market, in fact, its better than most of the commercial and expensive solutions. However Drupal is not a Headless CMS, Drupal is a pure CMS/CMF where the presentation layer is part of the core system and cannot be turned off. Also, Drupal is not API only, it is an API first solution, as it is very well explained by Drupal creator, Dries Buytaert in his blog (https://dri.es/drupal-is-api-first-not-api-only). So we can see Drupal more as a hybrid, that can work for decoupled applications, by leveraging a set of modules or by using a Drupal distribution like Contenta (http://www.contentacms.org/) or Reservoir (https://github.com/acquia/reservoir). Both are promising, the power and flexibility of Drupal for shaping and editing the contents and a standard API  for consuming the contents.

GraphCMS - https://graphcms.com

GraphCMS is the first headless CMS built around GraphQL, a modern and powerful data query language built by Facebook, that can solve some issues with a REST API like returning only what the client requests and nothing more, limiting the payload, what can be crucial on mobile apps. GraphCMS comes has a cloud solution, with a free (but limited) tier, setup is simple, a project can be created from scratch, from a template (Blog or News page) or by migrating from another solution (Contentful). The admin UI is built on React and Material UI and creating content types and fields is an intuitive process, most of the times in form of wizard/steps, however, the whole UI seems a bit clunky and slow to me.

Contentful - https://www.contentful.com

Contentful is another commercial and cloud-based solution, that fits in the medium/large level due to the price. A free but very limited version is available and the admin interface is very well conceived, we have 4 main sections, the Content model for modeling the content types, Content for managing the contents, Media for managing the assets and API to manage the project APIs. In overall, the interface is simple, fast and powerful, creating/updating fields puts Drupal in shame in terms of UX.

Directus - https://getdirectus.com  

Directus is a full Headless CMS that is available as an open source solution (free) or hosted solution (pay). The admin UI is minimalist and the content types fields are shaped in form of tables and columns, something that I personally don't appreciate, when using a CMS I expect to define the contents using less technical concepts, for me a content type is a representation of some piece of information (e.g. page, product, etc..) that is composed of attributes (e.g. product name, product price) and therefore I'm not interested where it will be stored and how it will be stored, unless I'm a developer. That approach of database tables is yet more visible on the API calls like when retrieving contents - /api/1.1/tables/[table-name]/rows.

Cockpit CMS - https://getcockpit.com

Cockpit CMS is a small solution that was built from scratch with Headless in mind. Its a product of one person mostly one person - Artur Heinze. As it mentioned on his website, "Simple Content Platform to manage any structured content".  It's a self-hosted solution based on PHP 7, Riot.js and SQLite (or MongoDB) that can be quickly installed using the docker image that is provided. The Admin interface is minimalist but intuitive, creating a new content type with a few fields is something that can be performed in less than one minute, something astounding when compared with other solutions. The REST API is simple to understand making the retrieving of contents an easy task. It can be extended by using the webhooks functionality or and since it’s an open-source and self-hosted solution by creating new add-ons.

If I was requested to choose one solution, as always I would ask for the business scenario and requirements, and probably would choose Drupal depending on the level of required customizations and dimension of the project. But let's imagine that we don't need anything fancy, we don't have the need for complex editorial workflows, we just need a simple website that will be managed by a few users and we want to build the frontend using a javascript framework.

In that scenario, my decision would be probably Cockpit and I'll try to explain why in the next post.

Jan 04 2018
Jan 04

Dans la rue is a Montreal-based organization dedicated to helping homeless and at-risk youth. Dans la rue cares for the immediate needs of youth and helps equip them with the skills and resources they need to lead more autonomous and rewarding lives.

Appnovation worked with Dans la rue to build a French and English Volunteer Application webform to transition Dans la rue’s volunteer application process from a manual form workflow to an online workflow.

Our team built a Drupal 8 webform which allows interested volunteers to fill out the application form directly on their website. In order for an interested applicant to apply for a position, the applicant must fill in required information or they will be unable to submit. This built in functionality saves Dans la rue staff and volunteers time, as they do not need to email potential volunteers back and forth to clarify information or request missing information.

Screen Shot 2018-01-03 at 9.39.58 AM.png

This webform will allow Dans la rue staff and volunteers to capture and manage application forms more effectively and efficiently which means they can spend even more quality time working youth.

https://benevole.danslarue.org/

https://benevole.danslarue.org/en

Screen Shot 2018-01-03 at 9.45.49 AM.png

 

Project Highlights included the work being part of Appnovation’s Corporate Citizenship program, as well as the multilingual element of the Drupal 8 work.

This is just the kind of project that highlights both our commitment to making a positive contribution to our community, as well as furthering the use of open technologies across different platforms, delivering results in both these endeavours.

What a great way to start 2018. 

Dec 05 2017
Dec 05

To​ ​fix​ ​or​ ​not​ ​to​ ​fix,​ ​that​ ​is​ ​the​ ​question….​ ​if​ ​you​ ​don’t​ ​mind​ ​my​ ​shameless misappropriation​ ​of​ ​the​ ​famous​ ​Shakespearean​ ​quandary.  

It may seem like a somewhat simple question, but it is a more serious consideration for most companies. As the earlier blogs in our website accessibility series highlight, this is not just a passing topic, but an ongoing concern for website development and developers.

Blog P 3.png

Imagine you are buying a house, with critical accessibility needs for one of the residents: do you make the necessary changes to the home, which you may like enough to consider, or do you build a home with such considerations in the blueprint?

This is, on a virtual level, the same dilemma.

Whether it is costing or branding, there may be a plethora of reasons why a business may agonize over updating or recreating their website, with advantages to be considered in both cases.

Sometimes, starting from scratch, building and developing from the ground up seems like the preferable option, ensuring that website accessibility elements are seamlessly merged into the foundations of the site. But it’s not as simple as that, evidenced by the fact that some companies prefer to repair rather than rebuild.

Well, think of it simply: if you have to meet with a specified criteria, does that make your replace or rebuild decision any simpler…

Here are the basics before you decide on remediation or a shiny new site:

  • You MUST ensure your website design follows a consistent navigation scheme across all pages, and that the menus or other navigation mechanisms are located in the same place

  • You MUST provide a page title that describes the topic or purpose of the page

  • You MUST provide structural headers to convey the structure of your page.

  • You MUST provide a text based equivalent if non-text web content is integral to understanding the editorial content (video, audio etc.).

  • You MUST ensure that all functionality is available using the keyboard alone

Also key to remember, is that there are minimum standards, additional requirements and the more desired level of website accessibility features.

So, will repairing your existing site merely meet the minimum, and potentially mean constant redevelopment, or will it be more fiscally sound to start from the ground up?

In the case of two of our clients, the University of Phoenix and University of California, it boiled down to how far from the desired accessibility their sites were.

Clearly, these elements alone provide a development dilemma, which is what Drupal.org has become so proactive with website accessibility compliance. Drupal 7 was designed to support the development of sites that comply with WCAG 2.0 and ATAG 2.0, and the Drupal accessibility community is deeply involved in adopting best practices in Drupal 8, both in the first instance and as they evolve.

For example, within Drupal,org, the accessibility team continues to identify, and work on improving accessibility barriers, resolving them swiftly and committing the improvements.

Having identified and resolved a number of issues in the core code of Drupal 7, the Drupal community have raised website accessibility awareness, both within and beyond their own development community. They have even added some additional support for Rich Internet Applications, by adding some WAI-ARIA support.

There have been many improvements to both the visitor and administrator sides of Drupal, denoting the commitment to website accessibility, especially:

  • Search engine form and presentation

  • Drag and Drop functionality

  • Color contrast and intensity

  • Adding skip navigation to core themes

  • Image handling

  • Form labeling

  • Removing duplicate or null tags

Again, though there is no ‘one size fits all’ solution when deciding whether to repair or rebuild your website, these considerations must be factored in.

Ultimately, there will only ever be two options in terms of  meeting website accessibility standards: repair and renovate your existing online furniture, or get a whole new design, and release a whole new website.

Nov 21 2017
Nov 21

As we discussed in Part 1 of our Website Accessibility series, web accessibility refers to the inclusive practice of removing barriers that prevent interaction with, or access to websites, by people with disabilities.

When sites are correctly designed, developed and edited, all users have equal access to information and functionality. That’s the plan. That’s the goal.  

As this series is highlighting, Drupal website accessibility is something about which our Appnovation team is acutely aware, and actively working on. Whenever we audit and evaluate the features of our own site, we look to immediately remove any identified accessibility barriers, and are just as vigilant in terms of client sites, including Drupal website accessibility considerations from the start.

Even after the initial launch, or relaunch of a client site, we are also aware that ongoing support and maintenance is important for our clients, which is why we offer packages to ensure ongoing accessibility needs are met.

When developing a new site, it is advisable to incorporate accessibility into the initial planning. That said, companies with existing or older website designs have to address accessibility issues retrospectively (as we all do, as accessibility functionality improves), so they have their site audited to deliver suggested alterations.

Many of the audit results depend on the CMS, which plays a major part in how accessible a site is, or can become. Having researched the most recent website accessibility audit surveys, I have discovered that the most common elements that required immediate alteration were:

Specifically, in terms of Drupal development, there is an ongoing focus on website accessibility, making it one of the more recommended platforms for those looking to upgrade or build in accessibility.

For example, the Drupal community contributors are continually to rolling out accessibility improvements (to both the visitor and administrator sides) including:

  • Search Engine Form and Presentation

  • Drag and Drop Functionality

  • Colour Contrast and Intensity

  • Adding Skip Navigation to Core Themes

  • Image Handling

  • Form Labelling

  • Removing Duplicate or Null Tags

Ongoing alterations are not just important in terms of user experience for those with disabilities, they are an important part of determining the most efficient CMS. Drupal is clearly committed to website accessibility, as shown by their own site’s acknowledgement:

“As an inclusive community, we are committed to making sure that Drupal is an accessible tool for building websites that can also be accessed by people with disabilities”

In many ways, this quote could be used for the platform on which to base any audit, and the springboard from which to address necessary alterations. Any audit-recommended alterations should, of course, be done to ensure that the correct standards are met, as outlined on  WCAG 2.0 and ATAG 2.0. with all elements of the site considered...

 

So, how important is an audit, if you feel your company site is not meeting accessibility standards? Well, consider the fact that this is your digital destination, which can be reviewed by users just like a hotel on TripAdvisor, and what people think matters.

When we completed our projects with the University of California and the University of Phoenix, an extensive part of our QA was ensuring that web accessibility was on point, and any reviews would be favourable.

But, more than this, website developers should care about the UX, not as an afterthought, but as an intrinsic part of what users will need to enjoy a full, unencumbered experience, from homepage to checkout, from browsing to booking. And, if you do want your site to be audited, and are willing to implement any and all suggested changes, that will enable you to set new standards for your own digital experience, and that of all your users.

Just in case you missed it, don’t forget to check out the first part of our series,  Drupal Website Accessibility, Part 1: The problem, and why it matters… and keep your eye out for Part 3, coming soon....

 

Nov 15 2017
Nov 15

What prompted you to write a book? And why did you pick module development as a central theme?

Answer: To be honest, I had never thought about writing a book. I was always quite active in the Drupal community, often writing articles, and  there are quite a few people who know me for this and appreciate it. This publication came about after I was approached by Packt Publishing to write the Drupal 8 version of the module development book. The previous one (for D7) had quite the prolific authors, so I had some big shoes to fill. But I took on the challenge and (I hope) it paid off.

For whom did you write this book? And what did you aspire to?

Answer: The most obvious audience for this book is novice Drupal 8 developers. This is because it starts from the basics. This can include Drupal 7 developers, site builders, but also PHP programmers from other communities. However, the target group is even larger than this. It can be very useful for intermediate Drupal 8 developers as well, because the range of functionalities covered is quite broad. My aim was to build a journey from the basics to quite advanced topics, to provide a comprehensive coverage of the most important APIs and subsystems.

How do you see the future for Drupal, where do you think it's headed? What's your vision for it?

Answer: I was happy to hear that during his DrupalCon Vienna keynote, Dries finally admitting that Drupal 8 is better suited for larger and more complex applications (mid to high market) than the smaller blog-like websites (small market). I agree with that and I think most of the community already knew this, but definitely some did not want to accept or admit it. Drupal 8’s new architecture allows building highly dynamic and complex platforms and at the same time can be quite the overkill for smaller websites.

What was the biggest challenge for you personally dissecting module development? Was there a learning curve for you too? 

Answer: I think the biggest challenge for me was to build this reader journey I mentioned earlier. Many people jokingly asked me: so are you just going to compile a bunch of your website articles into a book? And I really didn’t want to do that. I wanted the book to have a logical flow, its chapters to build one on top of the other, the level of difficulty to progress naturally and to cover everything I deemed important for the scope of this book. So yes, I have quite a lot of writing experience but none of this magnitude. I mean the book is 500 pages and 18 chapters long, so it was definitely a challenge. But I’m glad I did it, I learned a lot of new things (both about Drupal 8 and about organising a book), so I am generally happy with the undertaking.

Was there a specific subject that interested you in particular? Why? 

Answer: Typically, I am most interested in learning about APIs and subsystems most people don’t know very much about. If everybody knows how to do X or Z, what is my added value? This also allows me to help my colleagues when they have questions regarding things they cannot find information about on their own. So, for example, I enjoyed learning about low level stuff like the TypedData API and things related to data modeling and storage.

Tell me more about the writing process. How long did you work on it? 

Answer: I think writing the book took a few months to complete. The most impressive thing has been the impact it had on my life. I work for Wunderkraut full time and have my own activities on the side. Not to mention family life and things like that. So it took quite a toll. There were people who did ask me: “how do you do it?” I really don’t have an answer. Except maybe a supporting wife.

Moreover, I found that writing is not something I can do in the same way as I code. For example, if I have 15 minutes free on the train I can easily grab my computer and do work on a project. But when it comes to writing,  I need to have some good rested hours to dedicate at a time. And still, some days words just shoot out of me and others it’s like trying to squeeze blood from a stone. Luckily though, the research part did feel more like coding.

What was it like to work with a publisher in a tech-specialised domain?

Answer: To be honest, it was quite easy. I was always on my own doing the research and writing, always trying to stay ahead of the schedule to account for times in which I couldn’t work (holidays, etc). And, at the end, there were expectedly a bunch of remarks from the publisher that needed my attention, but it was quite organised, so it went by quickly. What I did find a bit weird was that before even doing anything, I had to come up with the entire plan mapping out ALL the chapter titles and their approximate lengths. That can be daunting, always thinking: “what did I forget?, What if I need a new chapter? Can I fill up 40 pages on this chapter?”. I obviously didn’t know from the beginning any of this for sure, but in the end it turned out ok. And the publisher was definitely not rigid in deviating from that.

What's your next project? You think you will take on a writer's carrier? Maybe even teaching?

Answer: Nothing is for sure, but I am not thinking of any such projects for the moment. I do like teaching, so I will continue writing on my website and passing on knowledge that I learn myself. And perhaps, even come up with a training programme. You never know.

Nov 14 2017
Nov 14

When an enterprise implements messaging, Guaranteed Delivery (Messages are persistent and are not lost even when the system crashes) becomes an imminent requirement.

When implementing messaging, ensuring Guaranteed Delivery means answers to the following:

  • Where does the message get sent when a condition is not met?
  • Can each individual message be re-delivered?
  • What happens to the message when an exception is thrown?

Before we answer these questions, let’s crack into “Dead Letter Queue”

What is “Dead Letter Queue”?

Dead Letter Queue is a service to store messages when:

  • The message that is sent to a queue doesn’t exist
  • Message length exceeds the limit set on Queue.
  • Message is rejected, by another queue or exchange.

Consider a simple example of accepting an http Inbound request, storing the message and then processing the request. 

1_0.png2_0.png

In the Publisher Flow (above diagram), Http Inbound connector delivers the message to the AMQP Outbound Connector, which connects to RabbitMQ.

<amqp:outbound-endpoint

          exchangeName="${rabbitmq.exchange.name}"

          queueName="${rabbitmq.sendemail.message.queue}"

          routingKey="${rabbitmq.sendemail.message.routingkey}"

          exchangeType="direct"

          exchangeDurable="true"

          queueDurable="true"

          responseTimeout="${rabbitmq.response.timeout}"

          connector-ref="AMQP_0_9_Connector"

          doc:name="Publisher Flow">

          <reconnect frequency="${rabbitmq.reconnect.frequency}" count="${rabbitmq.reconnect.count}" />          

</amqp:outbound-endpoint>

The “reconnect” element ensures that the delivery of messages is re-delivered in case of connection errors to RabbitMQ.

The Subscriber Flow is configured with an AMQP Inbound Connector, listening to any messages received and then delivers the message to Application Flow – to perform business logic.

<amqp:inbound-endpoint

          exchangeName="${rabbitmq.exchange.name}"

          queueName="${rabbitmq.sendemail.message.queue}"

          routingKey="${rabbitmq.sendemail.message.routingkey}"

          exchangeDurable="true"

          exchangeType="direct"

          queueDurable="true"

          responseTimeout="${rabbitmq.response.timeout}"

          connector-ref="AMQP_0_9_Connector"

          doc:name="Subscriber Flow">

          <reconnect frequency="${rabbitmq.reconnect.frequency}" count="${rabbitmq.reconnect.count}" />  

          <properties>

                    <spring:entry key="amqp-queue.x-dead-letter-exchange" value="${rabbitmq.exchange.name}" />

                    <spring:entry key="amqp-queue.x-dead-letter-routing-key" value="${rabbitmq.sendemail.message.dead.letter.routingkey}" />

          </properties>

</amqp:inbound-endpoint>

In the Subscriber flow, we have configured 2 additional properties to configure the dead letter queue. Messages will be sent to “Dead Letter Queue”, when the given condition is not met.

Until, this point we have answered 2 major questions:

Where does the message get sent when a condition is not met?

How to configure re-delivery of messages?

Let’s look at what happens when there is an exception in the application flow (in the above diagram) and where does the message get sent.

Typically, on successful processing of message, a positive “Acknowledgement” is sent to the queue, which then safely deletes the message from the queue.

<amqp:acknowledge-message  doc:name="AMQP-0-9 Acknowledge Message" />

But, when an exception occurs a “Reject” acknowledgement needs to be sent to the queue so that the message is rolled back into the queue for further use.

<exception-strategy ref="global-choice-rollback-exception-strategy" doc:name="Reference Exception Strategy" />

A rollback exception strategy is configured as:

<choice-exception-strategy name="global-choice-rollback-exception-strategy">

          <rollback-exception-strategy maxRedeliveryAttempts="${exception.strategy.rollback.attempts}">

          <choice>

                    <when expression="#[message.inboundProperties['http.status'] != null &amp;&amp; Integer.parseInt(message.inboundProperties['http.status']) != 200]">

                    <flow-ref name="perform-api-error-event-logging" doc:name="perform-api-error-event-logging" />

                    <set-property propertyName="Content-Type" value="application/json" doc:name="Property" />

                    <set-payload value="#[flowVars.payloadJson]" doc:name="Set Response" />

                    <json:object-to-json-transformer doc:name="Object to JSON" />

                    </when>

          <otherwise>

                    <logger message="No other exception handled" level="INFO" doc:name="Payload Logger" />

          </otherwise>

          </choice>

          <!-- re-queue message for re-tries -->

<amqp:reject-message requeue="true" doc:name="AMQP-0-9 Reject Message" />

             <!-- reject message, this will deliver message to DLQ -->

                    <on-redelivery-attempts-exceeded>

                              <amqp:reject-message doc:name="AMQP-0-9

                                        Reject Message" />

                    </on-redelivery-attempts-exceeded>

</rollback-exception-strategy>

</choice-exception-strategy>

The rejected messages in a queue can be viewed in the queue browser (like RabbitMQ Admin Console). The rejected messages can then be processed manually after taking corrective actions or the recovery process can be automated.

In conclusion, we have looked at how to implement Guaranteed Delivery of messages and answered the core questions of Guaranteed Delivery.

Nov 10 2017
Nov 10

Drupal Website Accessibility, Part 1: The problem, and why it matters…

"The power of the Web is in its universality.  Access by everyone regardless of disability is an essential aspect."

- Sir Tim Berners-Lee, W3C, Director and Inventor of the World Wide Web

In the coming weeks, I’ll be taking a look into one of the hot topics in the Drupal community, as well as the wider world of digital experiences: website accessibility.

As a digital solutions provider, and expert Drupal development company, Appnovation is always looking to lead rather than follow…but that does not mean there is no room for improvement when it comes to drupal website accessibility issues. That said, as Drupal experts and creators of outstanding digital experiences, we are continually striving to build websites that are as accessible as possible. This fact is highlighted in a recent blog post, titled Drupal 8 accessibility.  

So, let’s start with the basics: It’s fairly common knowledge that, when building a new premises, making it accessible to those with disabilities is something incorporated into the plans. In the case of older establishments, it’s fair to say that improving accessibility is one of the most common reasons for renovations or alterations.

Imagine that the the same level of accessibility directives and considerations for constructing an office space where used when building a website…and consider that it is just as important to be virtually accessible, as it is to be physically.

As a company, and as open digital devotees, we believe a physical disability should not stop a person’s digital odyssey. Essentially, nothing should affect a person’s right to access online services, and that is exactly the issue at hand…and website designers are sitting up and taking notice.

By way of an example, consider the case of a visually impaired user:

-If a site is coded with semantically meaningful HTML, with textual equivalents provided for images, and with links named meaningfully, this helps blind users using text-to-speech software and/or text-to-Braille hardware.

It seems simple, intuitive, elementary…but there are instances where these, and other basic elements of usability and accessibility are neither implemented nor evident.

In general terms, ‘web accessibility’ refers to the inclusive practice of removing barriers that prevent interaction with, or access to websites, by people with disabilities. When sites are correctly designed, developed and edited, all users have equal access to information and functionality, with specific consideration being given to the following:

1) Visual: Visual impairments (including blindness, various common types of low vision and poor eyesight, various types of color blindness)

2) Motor/mobility:  examples of this include: difficulty or inability to use the hands, including tremors, muscle slowness, loss of fine muscle control, etc., due to conditions such as Parkinson's Disease, muscular dystrophy, cerebral palsy, stroke.

3) Auditory: Deafness or hearing impairments, including individuals who are hard of hearing.

4) Seizures: Photo epileptic seizures caused by visual strobe or flashing effects.

5) Cognitive/Intellectual: Developmental disabilities, learning disabilities (dyslexia, dyscalculia, etc.), and cognitive disabilities of various origins, affecting memory, attention, developmental "maturity," problem-solving and logic skills, etc.

As the Web Accessibility Directive clearly shows, the list of priorities is vast, but it also has a gradation system of 1-3, in order of most critical, to most desirable. This effectively attempts to guide developers and their developers, and outline the most critical accessibility features and functions, without which the site would not even achieve the most basic standards of accessibility.

Appnovation is actively working with clients to achieve drupal website accessibility (as well as constantly looking to improve our own site). Clients such as the University of Phoenix, for example, are looking at ADA website accessibility compliance (ADA, Americans With Disabilities Act, 2010, Standards for Accessible Design). Changes and improvements on their site, for example, include:

  • Images (i.e. seeing how images are being displayed--dynamically, through controlled content or hard-coded and ensuring alt text is included)
  • Headers (i.e. H1, H2 tags, etc. in the page markup, ensuring they were set up properly)
  • Navigation - tabbing through content, left to right, top to bottom
  • Visual contrasts - an example of this was the calendar page, previous months and those had a grey background and text to indicate it was in the past...the contrast had to be increased between the background and text to meet compliance standards

As design and development continue to incorporate accessibility features, either as standard, or in terms of retroactive improvements, more companies, institutions and organizations are looking into website accessibility compliance.

Another example of Drupal website accessibility in action, is another of our clients, the University of California. As Appnovation was responsible for both the design and implementation, the designs had web accessibility and screen-reader considerations incorporated up front, another reason for selecting Drupal.

During the design stage, University of California stakeholders were already performing contrast testing on the design mockups to ensure the development and implementation would comply with WCAG 2.0 guidelines as proactively and smoothly as possible. The portal site is currently in User Acceptance Testing stage with a version 1.0 launch targeted for November 2017.

Not all companies are as proactive, however, and with the frequent failure of companies to ensure that their websites are accessible for those with disabilities, this new development consideration is more important than ever, with Drupal leading the open technologies charge. Naturally, very few sites are perfect in this regard, ours included, and there are always improvements that can be made, as technology enhances our ability to deliver upgraded accessibility.

Ultimately, various acts across the US, and globally, are being brought into law to ensure that all sites, both desktop and mobile, are attaining a decent standard of web accessibility as a matter of course, making this an essential part of the development, rather than a casual, post-launch afterthought. This is important to the Drupal community, which makes website accessibility such a critical part of why people would chose Drupal to start with.

Appnovation’s research team and, ultimately, our developers always see development as a process, leading to an optimized user experience, regardless of who that user may be.

 

Nov 06 2017
Nov 06

If you’ve been wondering where I’ve been and why I haven’t been writing any articles lately, I am here to put your mind at ease: I've been working heavily on my first book about Drupal, called Drupal 8 Module Development. And I am happy to announce that it has finally been published and is available for purchase.

Released by Packt Publishing, a leading publishing house for technical books in the Open Source world, my book is a comprehensive guide for developers new to Drupal 8. It aims to introduce you to module development starting from scratch but building up to complex functionalities. In doing so, you learn about all the fundamental subsystems and APIs available to work with in your Drupal module.

Book.JPG

As you know, my website mainly focuses on Drupal knowledge via articles about tips and techniques, especially in Drupal 8 (most recently). So if you’ve been finding these helpful, I recommend checking out my book as it contains about 500 pages of great content aiming to help you ramp up your Drupal 8 module development skills. I appreciate each and every one who decides to give it a chance and I hope you find it as useful as I intended it to be.

Here is the list of chapters that will take you on the journey from starting a simple module to writing performant functionality using complex subsystems and APIs:

  • Chapter 1,  Developing for Drupal 8 , provides an introduction to module development in Drupal 8. In doing so, it introduces the reader to the various subsystems and outlines the requirements for running a Drupal 8 application.
  • Chapter 2,  Creating Your First Module , gets the ball rolling by creating the first Drupal 8 module of the book. Its main focus is to explore the most common things module developers need to know from the get-go.
  • Chapter 3,  Logging and Mailing , is about the tools available for doing something every web- based application does and/or should be doing, that is, sending emails and logging events.
  • Chapter 4,  Theming , presents the theme system from a module developer's perspective in Drupal 8.
  • Chapter 5,  Menus and Menu Links , explores the world of menus in Drupal 8 and shows how to programmatically create and work with menu links.
  • Chapter 6,  ata Modeling and Storage , looks at the various types of storage available in Drupal 8, from the state system to configuration and entities.
  • Chapter 7,  Your Own Custom Entity and Plugin Types , takes a hands-on approach creating a custom configuration and content entity type, as well as custom plugin type to wire up a practical functional example.
  • Chapter 8,  The Database API , presents the database abstraction layer and how we can work directly with data stored in custom tables.
  • Chapter 9,  Custom Fields , exemplifies the creation of the three plugins necessary for creating a custom field that can be used on a Drupal 8 content entity type.
  • Chapter 10,  Access Control , explores the world of access restrictions in Drupal 8, from roles and permissions to route and entity access checks.
  • Chapter 11,  Caching , looks at the various cache mechanisms available for module developers to improve the performance of their functionality.
  • Chapter 12,  Javascript and the AJAX API , introduces module developers to the specificities of writing JavaScript in Drupal 8, as well as the powerful AJAX system, which can be used to build advanced interactions.
  • Chapter 13,  Internationalization and Languages , deals with the practices Drupal 8 module developers need to observe in order to ensure that the application can be properly translated.
  • Chapter 14,  Batches, Queues, and Cron , explores the various ways module developers can structure their data processing tasks in a reliable way.
  • Chapter 15,  Views , looks at the various ways module developers can programmatically interact with Views and even expose their own data to them.
  • Chapter 16,  Working with Files and Images , explores the various file and image APIs that allow module developers to store, track, and manage files in Drupal 8.
  • Chapter 17,  Automated Testing , explores the various types of automated test module developers can write for their Drupal 8 applications to ensure stable and resilient code.
  • Annex, Drupal 8 Security , recaps some of the main things module developers need to pay attention to for writing secure code in Drupal 8.

If you find something incorrect or out of place, please use the appropriate errata submission form mentioned in the book. And as always, feel free to drop comments below about the your thoughts on the book. Enjoy and thank you very much for purchasing my book!

Danny Sipos's picture

My name is Danny Sipos and I am a Drupal web developer located in Brussels, Belgium. I work on projects, big and small, as well as write technical articles to keep myself sharp.

https://www.webomelette.com/

You'll see me published here but also on Sitepoint.comTutsPlus or DigitalOcean.

Oct 26 2017
Oct 26

Get to know Appnovation's Fall 2017 cohort of post-secondary co-op students.

This September 2017 has been both busy and exciting here at Appnovation! We've relocated to a brand new office in the Railtown area of Vancouver, BC, we've hopped into a brand new fiscal year, and we've hired a super cool group of co-op students to help break in the new digs. As the recruiter of co-op students, I am pleased to introduce our latest undergrad Appnovators to you:


Albert Cherng, New Business Coordinator Co-op
Program: Bachelor of Commerce (BCom) specializing in Business Technology Management (BTM) at The University of British Columbia.

Albert is looking forward to working with an amazing team and learning the ins and outs of Appnovation, a digital solutions and managed services provider. What he really enjoys about his team is how are teaching and challenging him to think of ways to improve existing processes. Every day, he gets to work on something new and cool. In the longer term, he would love to own a restaurant!

A random fact about him is that he loves to cook (and finds it therapeutic!) In fact, right now, he's quite proud of his guacamole. Now, he's currently working on perfecting beef tongue tacos!
 

Jean-Paul Morneau, New Business Coordinator Co-op
Program: Bachelor of Business Administration (BBA), concentrating in Management Information Systems (MIS)

Jean-Paul is looking forward to improving his technical knowledge and growing his network in the Open Technologies industry.  He would like to somehow combine his hospitality experience, business mentality, and technical knowledge down the road. 

A fun fact about Jean-Paul is he's a certified Glider Pilot (and was an air cadet for 5.5 years).
 

Antoine Torossian, Project Analyst Co-op
Program: Electrical Engineering at The University of British Columbia

Antoine is attending The University of British Columbia for electrical engineering in the biomedical option. He thinks a co-op term at  Appnovation will greatly improve his object-oriented programming and teach him how to efficiently integrate frameworks in projects, which he is excited to learn about. Long term, he doesn’t have a set plan yet for where he wants to be exactly, but the tech sector is definitely the direction he intends to continue to grow in.

A fun fact is when he was 6 years old he broke my leg while running from his brother and his friends.

To learn more about Appnovation's co-op program, contact our global Talent Acquisition team today! We look forward to hearing from you.

L1024451.jpg

Oct 20 2017
Oct 20

SEO for Drupal Part One - Project Discovery and The Google Algorithm

In this new, fortnightly ‘A-Z of Drupal SEO and SEM’ series of Appnovation blog posts, we’ll see what it takes to turn a Drupal site into a traffic magnet, driving traffic growth and providing better Call to Action fulfillments without using Pay Per Click.

We’ll examine how we can discover a Keyword Universe, find out just what the difference is between short and long tail keywords, and look at some of the Drupal code tweaks and contributed modules that can help us optimize our pages for extra search traffic. We’ll also look at the role that site architecture plays in a well-optimized site, and how we can analyze traffic, proactively refine our content, and rinse and repeat these activities for sustained growth, whilst keeping everything on track and well-managed.

It’s aimed at a broad audience, so that an SEO Specialist might gain a new level of understanding about Drupal SEO under the hood, and so that a Drupal Developer might understand SEO beyond the code changes, become aware of the wider SEO knowledge that they should have in order to be able to come up with new ideas; and be able to tweak the Drupal codebase to perform exceptionally well for Search Placement, or as it is more commonly known - PageRank.

New Beginnings: Discovery

Every SEO Campaign should begin with a Discovery Phase, and it’s no different from a site development project in that respect. A good Discovery Phase will help us determine Campaign Purpose and Scope and Level of Effort, and define expectations.

The first requirement is to understand the client’s wider digital strategy, and to identify how your SEO efforts can be aligned to support this. In conversations with your client, this should be distilled into a single Page of Requirement, because on this all your subsequent activity will be judged. There is an element of knowledge transfer to the client here also - as the workshop or series of discussions progress, new opportunities can be identified, and these can lead to subsequent digital strategy refinement and evolution.

Client’s needs as regards SEO can vary widely. Are they primarily an e-commerce site looking to reduce their reliance on the blood money of Pay Per Click to drive traffic? Perhaps they are more services-oriented, needing better-targeted leads and a subsequent increase with Call to Action returns? Each scenario will require a different strategy, series of activities, and Campaign call.

A Discovery Phase typically encompasses:

An SEO Site Audit, including reviews of current SERPs (Search Engine Results Pages) positions, identification of technical issues that might affect bot crawlability, site architecture, and some measure of how performant the site is. We need to be aware of current User behaviour, traffic and activity by examining Google Analytics and Search Console. We also need to be aware of the extent of a client’s web properties and reach extending beyond that of the main Drupal website, including YouTube, Social Media platforms, microsites and backlinks.

The creation of a Keyword Universe - the basket of keywords and key phrases that Users would enter into Google to find your site. Each keyword should be assessed for relevancy, search volume (number of queries per month), competition (how hard it is to rank for a first page position?), and most importantly - does it’s inclusion meet with client strategy requirement? There are many online tools that can help in identifying which keywords you should consider for inclusion, but client knowledge and your understanding of the client’s business will yield a starting position to begin work, consisting perhaps of thirty keywords. Discovery Focus is the key here.

Competitor Analysis - who is occupying the first page of SERPs for a particular keyword? What will it take to displace them? A Gap Analysis can help identify Keywords that your competitors are using that should be added to your own Keyword Universe.

Resource deliverables are a comprehensive roadmap and SEO strategy to move from where the site is now, to where the client wishes it to be, inclusive of levels of effort and scope. Requisite changes to a site’s content and architecture will be identified if needed, and stakeholder buy-in is essential to this.

These activities will provide a baseline from which everyone can work from. From which we can measure any future growth and effectively monitor Campaign health and wellness. New opportunities for growth will be identified, and a realistic SEM/SEO Campaign effort and strategy presented and realized.

Teamwork is essential, and a typical Appnovation Team would be cross-discipline, comprised of Project Management, Drupal Front and Backend Developers, an SEO Specialist, and Creative and Marketing support to hand. But if you’re flying solo - then this series will help you.

SEM: Identifying the Win

Google, (yes - there are other Search Engines but we’ll group under this generic), lives and dies by relevancy. It’s ability to provide a relevant list of sites in response to a User’s Search Query. The win is persuading the Google Algorithm, [good review at https://searchengineland.com/8-major-google-algorithm-updates-explained-..., that any particular piece of content on your Drupal site is the most relevant for a particular search term - either consisting of one keyword or a pre-determined combination, and that it belongs on the first page of results. That is literally all there is to it.

But that Algorithm has many inputs and knows much competition, wise to Google alone - and Google is forever making tweaks in an effort to refine relevancy (the ‘Google Dance’), to try and understand the User’s intention, and to return ever-better, sometimes personalized, quality results. In future posts we’ll be examining the more important elements of the Algorithm and how we can best address them, but to illustrate just a small amount of its known scope, the Google Algorithm scores on:

  • Keyword frequency in a piece of content, keyword in title, h1 tag, the page title
  • Associated keywords present it might expect to find alongside a main keyword or phrase
  • User experience (i.e. not mobile-first, or a high image to text ratio is defined as a poor user experience)
  • Backlinks, especially Social Platform indicators (‘Off-Page’)
  • Site performance, render speed
  • Site architecture, structure, navigation, hyperlinks, presence of keyword-rich silos of content
  • Domain metrics, neighborhood
  • Accessibility
  • Technical issues Frequency of posts, post length
  • Presence of structured data, metadata
  • Bounce rates, visitor behaviour, visit length
  • Contextually-relevant and title-attr marked inbound and outbound links, an ‘authority site’ assay

The presence or absence of any of the above will positively or negatively affect your determined SERP positioning.

Some stats to think about:

Next post, we’ll look at how getting the site architecture right can seriously boost visitor numbers, start some keyword research, and begin installing Drupal modules that help with our Search Engine Optimization. In future posts, we’ll examine tuning content, making tweaks to your Drupal codebase, and to your server, - to further growth, and move to examine both Enterprise and Personal solutions that will increase your traffic and engagement.

Resources

Site performance - Google likes to offer fast-loading, performant sites in their Search Results - so use www.webpagetest.org to see how your site is doing. New Relic will reveal Drupal hook, view and module usage and server resource wall times. SEO Software - we use SEMRush, it integrates well with Google Analytics, and it’s reporting is good. Moz.com should also be reviewed. Both are all-in-one SEO research and tracking software that will give good results.

Oct 17 2017
Oct 17

Who are you? What's your story?

My name is Paulo Gomes, I am from Portugal and moved to the UK with my wife in 2016 to join Appnovation crew.

I am an tech and web enthusiast since the 90's (so not too old and not too young), I graduated in Computers and Management in 2002, after that worked in many places and companies, as freelancer, trainer and teacher, software engineer, system tester, system integrator, system administrator, developer and web architect. That was an amazing journey and I’m happy I can remember every place and colleague like yesterday.

What's your role at Appnovation?

I am working as a Drupal Senior Developer, mostly involved in D8 projects with team lead responsibilities.

What's the greatest lesson you've learned in your professional career (or even personal life) that you would like to share with others?

I believe that we learn something new everyday, however the greatest lesson we can have is still to come.

What do you do outside of work?

I try to enjoy a bit of everything, mostly traveling, listening to music, watching a good movie, cooking or read something interesting.

Where do you hope to take your career at this point/what's next for you in your professional career?

My ambition is to be able to provide more value in the initial phase of a project, so probably working more on the architecture side of things.

*BONUS* What are some fun/random facts about you that many may not know?

I am a big fan of Apple design and products for a very long time (since the first iMac G3), however I used an “hackintosh” for few years, and only moved to an iPhone some months ago.

Paulo 3.jpg

Oct 13 2017
Oct 13

Working in our Managed Services department, we handle many Drupal 7 and 8 sites - all of which have one thing in common. Despite their different requirements, designs and content - they all need security updates applying and are all in need of some care and attention when it comes to securing them.

Here’s 5 things I like to apply to any Drupal site that comes my way… security is something that - as a team - we take really seriously.

  • Sanitise Personal data
    Inevitably, we need to run 2-3 development versions of a site, so we can run QA, UAT and development work on a close to live, working copy of the codebase. When we copy a database from Production, it’s best practice to remove all personally identifiable information and sanitise the data we receive, whilst still having a realistic copy of the data.

    We have one great tool at our disposal for sanitising the database - which is sql-sanitize. In its simplest form, running

    drush sql-sanitize

    in a drupal directory with drush installed, will prompt you to enter ‘y’ to replace all the passwords with the word ‘password’ and change all the email addresses to be [email protected]. You can make this a bit more advanced (especially in an automated script) by running something like

    drush sql-sanitize –sanitize-email=“fakeemail+%[email protected]” –sanitize-password=“test123”

    to select a password and email address format of your choice.

    You can extend this even further by using hook_drush_sql_sync_sanitize to update other fields such as twitter accounts, webforms, names, LinkedIn etc with sanitised patterns that mask user identifiable content.

    It’s probably worth noting - never ever run sql-sanitize on your production server… or you’ll be getting a lot of frustrated users contacting you for passwords…!

  • Admin usernames and passwords
    For each dev environment, it’s good to have a different password - or at least a different password from the production site - this helps prevent accidentally logging into the production site and making changes you’re not intending to. Again, there’s an easy way to change passwords in drush and it’s well worth getting into the habit of doing so, to change our appnovation-admin user* it’s:

    drush user-password appnovation-admin --password="Nice*Secure&Password4Here"

    It’s also a great idea - if you can - to rename the admin user to something other than admin. When it comes to brute force attacking a login of a Drupal site, knowing the username is admin makes hacker’s lives a lot easier than the admin user being named something they can’t easily guess. (*oh and, we don’t actually use appnovation-admin as a username on any of our client sites…!)

  • Backup
    Before doing anything potentially destructive to a site, it’s best to back things up and store them away from your production site and somewhere nice and safe.

    Drupal has an amazingly simple tool for backing up - drush archive-dump or ard for short - and it definitely takes the ‘ard work out of backups.

    Running ‘drush ard’ in a Drupal directory will backup code and database and store it somewhere away from the root of the site. This can be built on easily using a simple bash script and cron to create a copy of the site every night with a date-stamped file name - which you could then store offsite or on another server.

    If you do get hacked - knowing you have a working copy of the site to fall back on is incredibly helpful.

  • Keep Drupal Core and Contributed Modules Updated
    To jump back to our house analogy, if I told you your front door had a crack in the window that a passerby just needed to press on to make it shatter and give them access to your home - you’d probably replace the glass, pretty quick.

    In a similar way, security updates are released regularly - generally on a Wednesday evening in the UK - and it is generally a quick and painless task to update your modules and keep your site safe. (Although, be warned, sometimes there are knock on issues when upgrading modules - so always backup and always run a full regression test before pushing the changes to production.)

    To make things a bit easier, you can run some drush commands to check what updates there are for your site. Running

    drush pm-updatestatus

    will tell you what needs updating. In the MS team, we’re developing a great automated tool for this - which automatically applies any security updates to a copy of the codebase and lets the QA team know there’s an update that needs checking. This is just one way we seek to proactively help out our clients.

  • Build your house on solid ground
    I’ve talked a lot about Drupal itself - but you also need to keep an eye on the servers your site’s installed on - if they’re at risk, your site will be too. Here’s a few ways I like to lock things down:

    1. Keep your server security patched
      This is vital - if you leave things to rot, there will be holes that can be exploited.

    2. Firewall off SSH access, or change the port number
      To stop hackers being able to brute force attack your server by ssh - it’s good to limit the IP addresses that people can login to ssh from. If that’s not possible - due to lots of remote access - then change the port from 22 to anything else.

    3. Limit HTTP and HTTPS traffic to the IP addresses of your CDN / Load balancer
      Load balancers are there to do just that - balance the load to your web servers and CDN products, such as Cloudflare, are there to reduce traffic (and, in particular, dangerous traffic) to your site. So it’s always good practice to only allow these IP addresses to hit your webserver. Failing to do so, is like locking your front door and leaving your side gate wide open.

  • Oct 10 2017
    Oct 10

    Meet Janice Cheer, Sales Enablement from Vancouver, BC.

    1. Who are you? What's your story?
    I’m a Chinese-Canadian who grew up in a small town called Squamish. After finishing high school, I moved out to Vancouver for school and obtained my Bachelor’s Degree in Business Administration with a minor in Marketing. Since I was 15 years old and before I joined Appnovation, I had nine different jobs in various industries. In those jobs, I honed my skills, gained experience, and grew as an individual. Interestingly, my role here at Appnovation is my tenth job!

    2. What's your role at Appnovation?
    My role at Appnovation is sales enablement for the sales department. My main focus is to ensure the Sales team is fully equipped with the knowledge and tools to help their sales process go as smooth as possible and to manage the operation flow of our sales cycle. I consider myself as the “mom” on the team. I make sure the sales reps are fed properly with the right nutrients and remind them to complete their homework on time. Even though I work closely with the Sales team, I’m also the middle-man between Sales and all other departments such as Technology Enabled Services (TES) and Finance.

    3. What's the greatest lesson you've learned in your professional career (or even personal life) that you would like to share with others?
    The first thing I’ve learned is that everything happens for a reason. Based on the series of events that has happened in my life, I believe that timing is key. Timing does not limit you to one path or schedule, but it makes you realize how many other opportunities are out there that you have not yet tapped and that what you’re doing right now is just a another stepping stone.

    Secondly: count your blessings. The friends that I have made throughout my career are not only people whom I enjoy socializing with. They also inspire and motivate me to keep pushing myself to grow and reach for my goals. “Slow and steady wins the race.” Some things you just can’t rush in life. You can work hard, but most importantly, it is to work smart.

    4. What do you do outside of work?
    I love to cook! I’m always looking for inspiration to make simple, clean, and delicious meals for my husband and I. I love to travel... especially when the travelling involves deeply discounted travel fare. I also like to go on hikes and play team sports whenever I can.

    5. Where do you hope to take your career at this point/what's next for you in your professional career?
    I’m not the type of person to have things set in stone; I like to follow a general guideline. I’m so grateful for the opportunity that Appnovation has given me and at this point, my main focus is to excel in my role and take on any challenges that come my way. I would like to work on projects that involve creativity from scratch, no matter what my profession is.

    *BONUS* What are some fun/random facts about you that many may not know?
    I use to paddle recreational/competitively on a dragon boat team for 5 years. I have medals to prove it!

    Screen Shot 2017-09-25 at 2.52.21 PM.png

    Oct 03 2017
    Oct 03

    Here's an insight into Ed, the man with the 'Cann do' attitude...

    Who are you? What's your story?


    I'm Ed, a welshman born an bred in Swansea. I grew up fiddling with computers from an early age starting with my Commodore +4. After university I decided that Engineering wasn't for me and Web development was where my talent lies so started with a few freelance websites for friends of friends. In my professional career I worked up from being developer for a local print company, a student marketing agency, a design consultancy and then started at Appnovation a little over a year ago.

    What's your role at Appnovation?

    I am a Drupal developer and Team Lead within the Managed Services department of the company. My role gives me the opportunity to work closely with our clients to update, expand and improve their websites to best suit the changing needs of their business. I love that no two days are the same in my role and there's always something new to challenge me and make be think in new ways.

    What's the greatest lesson you've learned in your professional career (or even personal life) that you would like to share with others?

    Never deploy on a Friday... or at the end of your day for that matter. It doesn't matter how certain you are that everything will be perfect there's always the chance that something will go wrong and you'll wish you'd waited. Also Backup, Backup, Backup! You can never have too many backups to ensure your data is safe when the worst happens.

    What do you do outside of work?

    When not working I'm mostly running around after my 2 little ones who are 5 years and 18 months old and keep me very busy. My weekends are mostly spent getting out and about with them on some adventure around the Gower peninsular, be it swimming, cycling, camping or even just a day on the beach. On the rare occasions when they're otherwise occupied I like to get out and ride my motorbike around the Brecon beacons or sit and play guitar.

    Where do you hope to take your career at this point/what's next for you in your professional career?

    Right now I'm enjoying helping to develop and grow the Managed Services department. As it's still a relatively new area of the business it's great to see it expand and be able to help shape what it will become with my input into the systems and procedures that we're putting in place. In the near future I hope to expand my knowledge into new technology areas and improve my management skills to progress within Managed Services and Appnovation as we take on more clients and staff.

    *BONUS* What are some fun/random facts about you that many may not know?

    I'm a massive geek and I'm a regular LARPer (Live Action Role Play) Think Dungeon and Dragons but in a field and with a foam sword instead of the dice.

    I only got my motorbike licence at age 31

    I've played guitar since I was 13 and own 5 guitars but I'm still rubbish.

    Ed 2.jpg

    Sep 28 2017
    Sep 28

    TechPong is an annual heart-racing ping pong tournament for charity organized by Chimp, Unbounce and Science World on October 19th. For the 3rd year, Appnovation will send our best doubles team and solo team to duke it out against other Vancouver companies.

    This year they are expecting 1000 attendees to make it the biggest TechPong yet!

    Each edition of TechPong has its own charity theme. For 2017, all proceeds will be donated towards youth education and STEM (Science, Technology, Engineering and Math) education initiatives.

    Through a nomination period and a vote, our employees chose to help students in our community, the Downtown Eastside, who are enrolled at Britannia Secondary School. 33% of the families enrolled at Britannia earn less than $30,000/year and 27% of the families are single parents. Over 50% of Britannia’s students are not able to pay their student fees.

    The Downtown Eastside is our community. Our funds raised over the next month will be used to encourage students to learn about science, technology, engineering or math through textbook subsidies, field trip subsidies and enrichment opportunities.

    You can help us raise funds for Britannia Secondary School by donating here:

    https://chimp.net/groups/appnovation-techpong-4-0 

    We are aiming to raise $2000 by October 19th.

    Thanks in advance!

    Sep 25 2017
    Sep 25

    Who are you? What's your story?

    I'm Tim Kirby, I come from a creative arts background, and started in multimedia and web site builds in 1996. I worked full time in Macromedia's Director for a couple of years, before moving to hardware and software design a few years later - building interactive digital signage systems that would respond to the touchtones on any phone within milliseconds via an SMS network instruction. One of the first customers was the MIT Campus. It was very ahead of the curve - I got a patent but not much else!

    What's your role at Appnovation?

    I'm a Senior Drupal Developer in Managed Services. I lead Team Detached HEAD. We're at the sharp end - operating client's Drupal sites, ensuring best performance while providing a very stable platform for new releases and features. Currently I'm managing SEO for several clients - Drupal naturally performs very well in Google, we're taking that to the next level with some extra secret sauce.

    What's the greatest lesson you've learned in your professional career (or even personal life) that you would like to share with others?

    Take each day as it comes. Don't quit. Clients put food on the table. Listen to a Project - it will tell you what is needed.

    What do you do outside of work?

    I'm a single Dad to my three boys - young men now actually - 18, 16 and 14. Working remotely for Appnovation allows me to provide a home for them, and be there for them, while pursuing a solid career with Appnovation. We make a lot of stuff at home - we're into 3D printing, making candles, casting moulds, forging and the like. All the boys tinker with tech - Raspberry Pi being the flavour of the month at the moment. 5.

    Where do you hope to take your career at this point/what's next for you in your professional career?

    I'm studying hard on Systems Architecture and Software Methodologies, looking out for the next leap in tech and seeing how we might implement that for clients. We're definately in a sweet spot to identify the new tech and match with clients who would benefit.

    *BONUS*

    What are some fun/random facts about you that many may not know?

    I write songs and play music when I have time. I played at Glastonbury Festival in 2011. My first album released earlier this year. It's kind of alt-folk - next stage I'd like to move towards folk and electronica using my NI Maschine Mk2.

    Screen Shot 2017-09-25 at 8.39.53 AM.png

    Sep 18 2017
    Sep 18

    Who are you? What's your story? 

    Richard Hales - "Talent Acquisition".

    With 13 years in recruitment, working with some top global brands, hiring some of the best talent. I now use that experience and those connections to find the very best people for Appnovation

    What's your role at Appnovation? 

    Working in the UK, I am ideally placed to service Hong Kong, the UK and Belgium in finding the best talent available. I pride myself in going above and beyond to find the "right" person

    What's the greatest lesson you've learned in your professional career (or even personal life) that you would like to share with others? 

    Focus on what you have instead of what you don’t. Don't stress over the things you can't change or influence. Concentrate on elements you can impact through action, always strive for solutions.

    What do you do outside of work? 

    Outside of work?? ... Sleep lol

    Where do you hope to take your career at this point/what's next for you in your professional career as a Talent Acquisition Specialist? 

    I really enjoy having a front row seat in growing the business - finding the right talent. I hope to expand on my general HR toolset and aspire to "Senior Talent Acquisition"

    ***BONUS*** What is one fun/random fact about you that many may not know?

    I once stuffed 48 Maltesers into my mouth...

    Screen Shot 2017-09-18 at 9.34.13 AM.png

    Sep 07 2017
    Sep 07

    Appnovation was recently tasked to redesign J.D. Power’s car and article search functionality. The current car search implementation was based on Drupal views searching against the database, while the article search was a basic Apachesolr (Drupal contrib module) search page. The car and article search functionality was to be based on Apache Solr and allow for full-text and faceted search.

    MULHIVILL BLOG 1.png

    During the discovery phase of the project we realized that there were five fields missing from the model content type that were needed for faceting. The data for these fields was available in custom database tables, populated by the Chrome Data API, but would need to be migrated into the content type to allow Apachesolr to re-index nodes when these values change. Data mapping files were also required to ensure the migrated data fields could be categorized and added as taxonomy terms.

    During the development of the car and article facets, there were some unique challenges that presented themselves:

    -The ‘Year’ facet was only to show eight items, with the eighth item being ‘[year] or Earlier’. For example, if 2018 cars are the most recent, then the last facet item should show results for 2011 or earlier. To achieve this, we needed to programmatically build a custom facet item that would aggregate all items less than or equal to 2011. First we needed to loop through all facet items to get the total result count for all facet items 2011 or earlier.

    To ensure the proper values were being returned from Solr when the facet item was selected, a range query was used. Then we needed to build some logic around detecting when the facet item was active or inactive so that when it was selected we could make its’ checkbox active. At the end of this article there is a helper function that we used to get all active facet items to help us accomplish this task.

    MULHIVILL BLOG 2.png

    -The ‘Ratings & Awards’ facet was to have four items, each one its’ own field on the model content type. One of these fields was a Boolean field, so we decided to base the ‘Ratings & Awards’ facet off of this field’s facet as it then only meant adding custom facet items and not removing anything.

    For the other three fields, we enabled their facets in facetapi so we could access their data. We programmatically loaded the other three facets to get their build info, which we used to create the three custom facet items. Find a helper function below that we used return facet build information from a faceted field.

    Mulhivill Blog 3.png

    One of the most difficult aspects of this project was actually removing existing functionality. Since there was already a site-wide search built on Apachesolr, it was important to keep this intact while removing any remnants of the existing car and article search to keep the codebase as clean as possible.

    Overall this project was a success and is now available in the production environment, take a look:

    http://www.jdpower.com/cars/search

    http://www.jdpower.com/cars/article/search

    We created some useful helper functions to accomplish the tasks listed in this article. I will provide them here for others to use.

    /**

     * Helper function to return all active facet items

     */

    function _appnovation_get_active_facet_items() {

                $adapter = facetapi_adapter_load(APPNO_SOLR_SEARCHER);

                $active_items = $adapter->getAllActiveItems();

                return $active_items;

    }

    /**

     * Helper function to return facet build info for a field

     */

    function _appnovation_get_facet_items_from_facet($field) {

                $adapter = facetapi_adapter_load(APPNO_SOLR_SEARCHER);

                $realm = facetapi_realm_load('block');

                $facet = new FacetapiFacet($adapter, facetapi_facet_load($field, APPNO_SOLR_SEARCHER));

                $processor = new FacetapiFacetProcessor($facet);

                $processor->process();

                $facet->build($realm, $processor);

                $build_list = $facet->getBuild();

                return $build_list;

    }

    Aug 14 2017
    Aug 14

    Meet Tony Nguyen, our Manager of Product R&D from Vancouver, BC.

    1. Who are you? What's your story?
    I'm Tony Nguyen and I manage the Product Research & Development team with the osCaddie R&D being our main project. I'm originally from New Zealand and moved to Vancouver just over three years ago and have been with Appnovation for two of those. I started doing business analyst (BA) work in second year of university in Auckland, doing odd jobs taking meeting minutes, drawing up questionable UML diagrams, etc., then started taking on contracts working in Telco, Banking, Airlines (all over the place, really), etc. Fast-foward eight or nine years and I'm here in Canada at Appnovation working on awesome products! I was originally a contract BA on the R&D project at the very beginning and took over the management of the team a few months ago. Having been part of this from the start has been great to see the ebbs and flows and see it evolve into what we are now.

    2. What's your role at Appnovation? I'm the Manager, Product Research & Development.
    I work with the executive team to discover, conceptualize, and build strategy for potential products. I also oversee the development team based mostly here in Vancouver with some additional team members in the United Kingdom. I also take on the scrum master role, driving the team through our Agile sprint methodology in addition to taking care of the BA work in writing user stories, tasks, epics, etc. On any given day, I'll either be in strategy meetings, working on user stories for the dev team, or taking the team to grab a coffee at Milano (which is by far the best coffee in Gastown!).

    3. What's the greatest lesson you've learned in your professional career (or even personal life) that you would like to share with others?Having been a contract BA / Project Manager for the better part of a decade across a variety of industries, I've found that it's important to find an approach to your role that is structured yet adaptable. Every company works in slightly different ways, but the foundations stay the same. Understanding what the core drivers for a business are, is what's important. This is the funnel you need for everything else to fall into place. Personally speaking, I'd say that it's important to find what makes you happy and/or brings you satisfaction. For me personally, I'm a completionist (that may not be a word) when it comes to work / gaming / anything really. Which is why I enjoy working on products, I'll drive as hard as I can to get something built - searching for that sweet satisfaction of seeing it released to the world (or could just be OCD; haven't figured that one out yet).

    4. What do you do outside of work?
    Too many things! There aren't enough hours in the day! I like to game a fair amount. I've been a gamer since my parents bought me a Commodore 64 which I used to play Flash Gordon on cassette... (showing my age a bit here!). Right now, though, I'm spending probably too much time playing Battlefield 1. (Add me on PSN! and let's PwN some n00bz!) I also like to ski on the weekends. I have snowboarded for years now but thought I'd give skiing a try once I moved here (because, why not?) and I love it now. Also living in Vancouver with such great access to mountains everywhere is so awesome! Most Vancouverites don't know how great they have it! Lastly, I play social flag football in the summer and have tried to pick up hockey recently, although I've realized that being able to skate will definitely help with that. Note to non-Canadians: If a Canadian tells you that they don't know how to skate, they're lying! I'm pretty sure all Canadians are born on ice lakes or rinks.

    5. Where do you hope to take your career at this point/what's next for you in your professional career?
    As a manager of Product R&D, I'm definitely striving to establish and grow our relatively new team into the the greater business. I am also hoping to expand on my own personal knowledge of product development to continually improve and build better products. Once we build and release this first product and it's self-sustaining then it's onto the next big thing. I'm really excited for us to get to the point where we're a well-oiled machine that's churning out great products for the company.

    *BONUS* What are some fun/random facts about you that many may not know?

    1. Appnovation is my very first full-time permanent job! Yes... I have been contracting straight out of university. When I was 15, I quit my very first job as a grocery store checkout guy to go to an Incubus concert... (don't tell my mum.)
    2. I was a 200lb 15 year-old. Great for rugby, not so much for anything else...

    DSC08953.jpg

    Aug 03 2017
    Aug 03

    I was recently going through the d8cards set of exercises to test my knowledge of Drupal 8 APIs, as one does in the dev world...

    Put simply, or as simply as possible, it consists of a set of 21 exercises, each going over a common Drupal task and how it changes from Drupal 7 to Drupal 8. Card number 4, covering the migration API now semi-bundled with core, gave me enough of a hard time that I had to upgrade my entire development environment to solve it. 

    Here is a story of how I debugged a Drupal 8 migration entity, first by setting up a CLI Xdebug environment, then by applying debug thinking to hunt down the cause of a bug that was actually a feature. Follow along by opening the Migration 101 d8card. You may wish to attempt the exercise yourself before continuing.

    The Bug

    Being a stereotypical overoptimistic coder, I assumed I would breeze through the migration by “borrowing” some example code and adjusting a few variables here and there. Everything worked fine for the actors migration, but when attempting the movies, this was the outcome:

    Looks like an obvious problem — the code is attempting to insert the raw value from the source into the destination, without converting it into a taxonomy term id. But, being unfamiliar with Drupal 8 migrations, where can we begin to look for the cause?

    The old way of debugging this problem would involve wrapping the different steps of the migration in var_dump calls and other such print statements, crudely observing the data flow. In Drupal 8, however, migrations are configuration entities written in YML files, therefore can’t be debugged the old-fashioned PHP way. No need to worry, we have something much better: Xdebug and live, interactive debugging, in the best IDE for such hard work, PHPStorm.

    Our immediate challenge: the migrate API for Drupal 8 does not have a web interface for migrations yet. Migrations are meant to be processed through the CLI, using Drush or Drupal console. This means the old trick of passing Xdebug remote connection parameters to web pages is useless; we will need to trigger debugging on a terminal script.

    For our development environments, we favor using the Drupal-VMprovisioning script. It’s fast to set up, it’s easily shared using one configuration file, and it runs on plain old reliable Vagrant.

    It’s also easy to combine with the Drupal-Project composer scaffold, which conveniently installs both Drush and Drupal console into the project’s vendor directory. This means we have the Drush code as part of the same project as the rest of our code, creating the ideal debugging setup.

    Before we can start our debugging session we have to do some necessary setup. PHPStorm is able to run scripts inside a Vagrant VM, but we first need to tell it about our “remote interpreter”.

    Configuring a Vagrant Remote Interpreter

    Open the PHPStorm Preferences, and under “Language & Frameworks > PHP”, you should see this screen:

    We’re going to configure a new CLI interpreter by selecting “…” next to the CLI Interpreter dropdown. This opens the CLI interpreters dialog:

    Create a new Remote interpreter by selecting “+” in the top left and choosing “From Docker, Vagrant, VM, Remote…” in the dropdown.

    The configuration details should reflect the configuration options of our Drupal VM virtual machine. The username and password is typically vagrant/vagrant. Click ‘OK’ to continue.

    Now we need to map the files in our project, located on our host machine, to the files that are being synced to the VM. Next to “Path mappings:” click “…” and select the local and remote paths that you linked in Drupal VM’s config.yml file.

    The final step is verifying that our debugging configuration is still correct. Open the “PHP” toggle and select “Debug”:

    Check ‘Break at first line in PHP scripts’. We’ll use it to validate our configuration worked.

    Close the PHPStorm Preferences....

    Now, I know you want to know more, so tune in next week for Stepping Through Drush....and later, The Art and Science of Debugging....

     

    Jul 24 2017
    tim
    Jul 24

    It's crazy to think that, after the release of Drupal 8 in November 2015, development of the 5th iteration (8.5.x) will be starting in August. The new semantic versioning and 6 month release cycle looks to be working wonders for Drupal Core, keeping it fresh, up to date, and current.

    Are all these releases, however, making it hard for agencies such as ourselves to keep up? 

    Well, let's see if we can answer that...

    As the number of Drupal 7 projects decrease, and the number of Drupal 8 projects increase, we have seen the Drupal market become even more competitive. Every agency is now working to prove they're 'up to speed with Drupal 8', and show that they know why it's the right choice for the client. Appnovation have had Drupal 8 projects switch to Drupal 7 (or be pulled completely) because of the platform not being "ready".

    This has helped us realise that even though the Drupal 8 admin UI is very similar to Drupal 7, it is a very different platform.

    Drupal core has made some pretty big changes under the hood, including using external dependencies such as Symfony, and moving to generally object oriented code. Thankfully, these were pretty predictable, and we could plan for their coming.

    That said, there are some aspects that have come as a bigger surprise:

    • New contrib modules that offer better / different approaches.
    • How we use configuration management in the real world.
    • How these changes integrate into our local development process and remote continuous integration systems.
    • Using composer to manage dependencies.
    • Modules like Default Content, Deploy, Workspaces, and Content Moderation provide better solutions content management solutions.

    Those agencies who have been engaged with Drupal 8 since the start of development in 2011 are now in a much better position to deliver Drupal 8 based projects.

    So what are we doing at Appnovation, to ensure that we step up and become a leading Drupal 8 vendor?

    • Holding company wide meetings every two weeks to share ideas, discuss pain points, and ask questions about Drupal 8.
    • Running our company site on Drupal 8, so we can learn as we go, and practice what we preach.
    • Give back where we can, working on many Drupal core and contrib issues during down time.
    • Working through potential client needs with practice sites.

    We're firmly committed to Drupal 8 and the direction it is going.

    There are many exciting things we see in the pipeline, which are a great fit for many of our existing clients.

    Jun 28 2017
    Jun 28

    It's been 2 years since we set up Appnovation's APAC office in Hong Kong. One of our fastest growing business areas in Hong Kong is within the insurance sector, helping various companies with their agile, dev. ops. and Atlassian transformations and integrations.

    In recent years, insurance companies have faced increased competition from local, as well as global players. During this period Asia, a continent facing significant population, as well as economic growth, has attracted the attention of many major insurance players. With an increased focus on this market, it follows that insurance companies have needed to fight harder to win business from consumers, as well as from rival companies.

    With the emergence of more sophisticated financial digital technologies, consumers now have the ability to draw from a much deeper well of information, in terms of both insurance products, as well as other fiscally related issues. With such a vast number of options, consumers are equipped to learn more on a daily basis, making the competition unrelenting. In order to maximize product differentiation, insurance companies are realizing that they must innovate, and move their digital operations quickly, or risk being left in the wake of others.

    Such innovation, of course, is fluid, varied, and comes in a multitude of different forms. While many such innovations focus on improving the overall customer experience, they sometimes fail to appreciate the incipient elements that underpin their entire operation. For example, historically, the genesis of the customer experience for insurance companies was (and in some cases, still is) only concerned with the initial signup process, quickly tailed by the all-important claims management process.

    Now, however, with so many other opportunities for insurance companies to engage with customers, all elements of customer service must be considered, none of which are truly autonomous. With this greater imperative to innovate, and the almost lightning pace at which organizations often launch new products, insurance companies are becoming acutely aware of the importance of being agile. The concept of agile emerged from the specter of software development. However, in helping various organizations adopt agile, we now consider and appreciate that agile is not purely a software development concept.

    Rather, the fundamental ideas behind agile have much greater, more far-reaching potential outside of IT or software development.

    To summarize, here are the main value points of Agile:

    1. Individuals and Interactions Over Processes and Tools

    2. Working Software Over Comprehensive Documentation

    3. Customer Collaboration Over Contract Negotiation

    4. Responding to Change Over Following a Plan

    When you analyze these values, it is noticeable that these concepts actually apply to strategic management far beyond the realms of software development.

    The first value, for example, around individuals and interactions, is highly applicable to general business management. We’ve all heard the notion that “people are more important than tools and processes” but, in practice, this actually relates specifically to accountability and ownership. Proper ownership and accountability, over goals, works much better than cross checks, verifications tools, and processes.

    The second value of agile is about minimizing time spent writing about what to do, and focusing on what is minimally required which, ultimately, augments our ability to execute tasks and projects. Thirdly, but no less importantly, agile values continuous collaboration with stakeholders. Put simply, stakeholders are important, and it is entirely unacceptable to keep them out of the loop until the product is done. Such is their importance, they should be informed throughout, as communication is key. Finally, agile focuses on our ability to respond swiftly to any and all changes.

    Agile provides a framework around this general direction, but the focus is on being able to respond to changes in a pragmatic, effective and timely manner. For Appnovation’s insurance customers, agile is seen as a way to increase the pace of their own innovation. While agile does start with IT, a lot of our customers see the need to adopt it across multiple departments. In our experience, agile adoption is not a ‘top down’ process. Rather than providing this kind of training to teams, we find that it is much more effective to take a ‘from the ground up’ approach.

    We believe that by integrating team members into the wider corporate team, they can learn new concepts more easily, adopt, and ultimately embrace a new way of thinking more effectively. This is why, on many occasions, our agile adoption program starts with us implanting developers and QA personnel into various teams.

    In short, we believe, and our experience informs us, that agile change by viral influence has a much greater impact than the alternative methodologies.

    Jun 20 2017
    tim
    Jun 20

    On 28th June (23:59 Vienna local time (GMT +2)) session submissions will close for DrupalCon Vienna 2017 and we're looking for more great speakers.

    After volunteering on the Core Conversation track team last year, I am now helping the PHP track team find and select sessions for this year's European conference. As PHP the foundation for Drupal it's great to hear speakers talk about related trends, best practices, and tools. Since the release of Drupal 8 we have "got off the island" and started using components from other platforms and frameworks, and embraced things like Composer, PHPUnit, and PSR. These changes have made the PHP track more important than ever.

    As you'll see in the track description we're looking for sessions in three main topic areas.

    • Tools - Are you a PHPStorm ninja? a debugging master? or have the perfect dev environment?
    • Libraries - We can pull in libraries with Composer, and abstract things into libraries. Can you speak to this?
    • Testing - PHPUnit is the way forward. What have you been doing with it? How do you fully test your code? 

    If you have an idea for a session please submit it and I look forward to seeing you there.

    May 22 2017
    tim
    May 22

    *Cross-posted from Millwood Online

    Over the past month there has been a lot of focus on Drupal, the community. More recently it seems people are back to thinking about the software. Dave Hall and David Hernandez both posted eye opening posts with thoughts and ideas of what needs doing and how we can more forward.

    A one line summary of those posts would be "We should slim down core, make it more modular, and have many distros".

    To a degree this makes sense, however it could cause divergence. Core is not great at all following the same pattern, but contrib is even worse. As part of the Workflow Initiative specifically there is a lot of work going on to try and get the Entity API aligned, get many more entity types revisionable and publishable, using common base classes, traits, and interfaces. If we maintained Node, Block Content, Taxonomy, Comment, etc all as separate projects then there's a chance less of this would happen. Also by doing this we are laying out foundations and setting examples to be followed.

    One solution to this may be to follow Symfony (yet again), they have a monolithic project but then split this up into the various components, which are "read only" repos. It's be pretty awesome if we could do this with Drupal. From there we could make Drupal downloadable without many of the core modules. People with the right skills can create a composer.json file to pull in exactly what parts of Drupal are needed, others could use a form on d.o to select which parts are wanted, which downloads a compiled zip.

    What would be more awesome is if we could abstract more of Drupal out of Drupal. Imagine if the Entity API was a PHP generic library. Imagine if you could create a Laravel or Symfony app with Nodes. This would be really tricky, especially since Dries announced the plans to make Drupal upgrades easy forever, but possible.

    Currently most Drupal sites are still on 7, and here we're talking about what would be Drupal 9? Maybe we need to take step back and look at why sites aren't being upgraded. Dave mentions "A factor in this slow uptake is that from a developer's perspective, Drupal 8 is a new application. The upgrade path from Drupal 7 to 8 is another factor." Although another reason is also why would a company spend the tens of thousands upgrading to Drupal 8? It looks at works (from a users point of view) the same as Drupal 7. Drupal is a CMS, a Content Management System, and the management of content is more or less the same. Yes, with initiatives like Workflow and Media this is changing, but even then similar functionality can be achieved in Drupal 7 with contrib modules. Will Drupal 8 be the version to skip? go straight from 7 to 9?

    As Drupal is now pretty firmly an enterprise platform we need to look at this from a marketing point of view. What is going to sell Drupal 9? Why are people going to upgrade? What do they really want? Is a slimmed down core and more modular application really the selling feature that's wanted?

    Drupal is a CMS, quoting Dave again "do one thing and do it well". We need to focus on making the authoring experience awesome, and the workflows that go along with it awesome too. This should all be done in a consolidated way to make managing Node content, Block content, etc just as intuitive as each other. If during this process we can also make things more modular, and less Drupally, that'd be awesome! 

    Apr 03 2017
    Apr 03

    It's that time of the year again, where all that is Magento finds itself in motion toward Las Vegas for the annual Magento Imagine conference. Our eCommerce Director Tim Laurent is live from Vegas this week, and outlines his expectations and thoughts for the next few days at the conference:

    For the third year in a row, we're at the Wynn hotel--a nice upgrade from years past.

    This year is a bit different with the Partner Summit on Sunday versus at the end of the conference--looking forward to these special sessions with a clear and fresh mind.

    And, like years past, the conference is stuffed with wonderful offerings from deep technical dives to business tracks to Magento announcements. And, not to forget headliners like Serena Williams! Here are a few things that we're particularly excited about:

    • Networking Maximus! Our chance to see everyone that we talk to daily, weekly or on occasion--that we normally don't see face to face--but at this once a year conference.
       
    • Continue to foster our partnerships with Magento, Acquia and other third party service offerings.
       
    • Magento Announcements around CMS, BI and B2B.
       
    • Deep thinking around Enterprise Cloud Edition (ECE).
       
    • A chance to wander the marketplace and discover new offerings or technologies that may be useful for our clients.
       
    • Share stories and lessons learned (stay tuned for more Magento Imagine blog posts!).
       
    • Pickup that pile of Magento swag! 

    We look forward to seeing everyone at Imagine over the next four days!


    Follow us on Twitter (@Appnovation) for live updates from the conference! 

    Mar 28 2017
    Mar 28

    Since founding Appnovation 10 years ago, we've enjoyed both continued growth, and the ongoing evolution of who and what we are as a business. In the early stages of the company, we were a software development company focused around one technology, Drupal, the content management system which drove and defined what we delivered for our clients.

    Today, I'm proud to say that our development stack is much more extensive, and now includes MuleSoft, Magento, Alfresco, HTML5, Atlassian software, and several more. Thanks to our ability to recruit some of the leading experts in these areas, we continue to go from strength to strength in terms of our development and delivery capabilities.

    As we enter another new phase of our company’s evolution, we will fully embrace the notion that open technologies are what's defining and driving the digital development landscape.

    Put simply, it’s all about Open Digital Delivered.

    Open

    Appnovation is proud of openness as one of our core company values. We ensure that it’s evident in how we work with our employees, our clients, our partners and the global community.

    We intend to use our strong open technology foundation as our platform, a position which will enable us to renew our focus on building great enterprise applications for our customers, using the full range and capabilities of the open technology stack.

    Our aim is simple as well as being challenging (as we all know that complacency is no substitute for ongoing endeavor and innovation): to remain the leader in open technologies adoption, and to ensure that we’re there to guide our clients through the full technology lifecycle.

    Digital

    Appnovation has always had a strong UI/UX team. To highlight our ongoing commitment to this area of our business, we’re further strengthening our team. By bringing together our UI/UX, strategy and open technology expertise, we will augment our ability to guide our customers through the Digital Transformation process.

    For several years now, we’ve helped many of our customers move towards enhanced Digital Platforms, with a focus on achieving tangible business goals. Through advanced analytics, customer experience management systems, and enterprise integration frameworks, we have shown our strength in this arena, working with entities as large as the UK government.

    In the coming years, we are looking to further, and rapidly grow our Digital Transformation customer base, helping even more clients to achieve their goals.

    Delivered

    With our strong emphasis on outstanding project delivery, it isn’t surprising that every ‘Appnovator’ is driven by a “we get the work done, and we do it well” attitude. It’s how we started our company, how we continue to grow it, and how it will always be.  

    Quality service delivery is, and will always remain, a core part of our company’s aim and identity, it’s in the Appnovation DNA. Thanks to the launch of our Managed Services offering just two years ago, we have been able to continuously and significantly extend our capabilities in this field.

    Appnovation now boasts services which include ongoing support and maintenance, to ensure that our customers have great application platforms, running 24/7, serving their needs consistently, without exception.

     

    Mar 27 2017
    Mar 27

    By: Aisha Kaliel, Drupal Developer 

    Drupal is one of the world’s most popularly used open source content management systems, with Drupal 8 being the latest and greatest release. Drupal 8 is here with over 200 new and improved features, responsive designed themes, and improved content authoring and multilingual support. It was initially released in November 2015, and was one of the biggest updates in Drupal history. It is now currently on version 8.2.5 and as of January 14th of this year, Drupal has counted just over 1, 000, 000 Drupal 8 sites.

    What has changed in Drupal 8?

    Some of the biggest differences developers may notice working with Drupal 8 is it started to adopt modern PHP concepts and standards, object oriented programming (OOP) and many aspects of the Symphony 2 framework in core. With OOP, it allows for better code re-use and encapsulation, maintainability, and other conveniences that procedural programming doesn’t. Thus, Drupal has a new set of coding standards just for OOP.

    The Drupal 8 backend is now powered by the Symfony2 stack. It is lighter, faster and provides the benefits of partial page caching, higher performance and efficiency, improved multilingual support. But Symfony wasn’t the only technology that was added. Drupal 8 also depends on other great web technologies such as CKEditor, Twig, jQuery, Backbone.js and Guzzle.

    With Twig, Drupal 8 has a brand new way of theming. It is much easier to use, while also being significantly more secure. You can take a look at setting up a Drupal 8 theme with Creating a Drupal 8 Theme with Sass, Singularity & Breakpoint. But that isn’t the only improvement to themes, as Drupal 8 is now mobile first in its approach, all the built-in themes are responsive, including the admin theme.

    Another big part of Drupal 8, is how much more was moved into core that used to be contributed modules. This includes popular modules such as Views, Features, Entity API, Date, Link, Entity reference, CKEditor, Wysiwyg, jQuery Update and many others.

    There are so many other changes, but the last one I will touch on is the configuration management initiative. With the inclusion of a lot of what the Features module did, Drupal 8 can synchronize configurations across development (and production) sites. All configurations, including views, content types, fields, taxonomies, enabled modules and so forth, can be managed by importing and exporting YAML files. This can be done through the UI, with Drush, or even version control.

    There two types of configurations: simple configuration and configuration entities. Simple configuration is similar to using variable_get() and variable_set(), as it stores basic configuration values like boolean values, integers and text, and only has one copy or version. Configuration entities on the other hand, store lists of more complex informational items. For more information on the the new configuration system, start looking at the the Configuration API page on Drupal.

    Check out some of our other great posts about working with the new changes in Drupal 8!

    Mar 27 2017
    Mar 27

    We've built a team of the best in open technologies. Meet Nazli!

    1. Who are you? What's your story?
    My name is Nazli (or as most call me, Naz). I'm one of the core hires for the Montreal office. I'm originally from Turkey but I'm happy to call this cold but amazing city of Montreal a 'home' for the last eight years. I'm shy and very quiet at the beginning but once you get to know me, you'll start to see my fun side.

    2. What's your role at Appnovation?
    I'm a back-end developer here at Appnovation. I started as a Junior back in 2014 and moved my way up to Intermediate. I'm given Technical Lead roles on many projects and I believe I'm always able to find my way with the help of other amazing developers here.

    3. What's the greatest lesson you've learned in your professional career (or even personal life) that you would like to share with others?
    Never stop learning and don’t be afraid to make mistakes. My job requires a lot of constant learning. Nothing makes me happier than reaching my goals, launching that app idea I had for 2 years, learning that language, or capturing that moment with my camera. I had to fail many times to get to my achievements. How would I get there otherwise?

    4. What do you do outside of work?
    I'm into photography, to the point that I own about 10 different cameras (two digital and the rest are analog/polaroid). I spend at least one weekend each month exploring different parts of the city to take pictures. Photography helps me see things from a different angle. I also like playing around with projects for my Raspberry Pi.

    5. Where do you hope to take your career at this point/what's next for you in your professional career as a Developer?
    I'd like to see myself grow into a Senior Developer role at Appnovation. Although I know this comes with experience, I do my best to stay on top of new technologies and I spend at least a day each week focused on learning. I'd also like to know more about front end development so I can provide more value to my team members.

    *BONUS* What is one fun/random fact about you that many may not know?
    I have an obsession with the number 11, like in the movie 'The Number 23'. I count the letters in a sentence and see if it's divisible by 11. Same with table numbers. I don't change my way depending on the outcome, but I just do it. For example, Appnovation: 11 letters.

    IMG_4238 (1).jpg

    Mar 08 2017
    Mar 08

    Agile Team Organization

    Projects go wrong all the time. There are, usually, several reasons why a software team will fail on any given project. There are several statistics available suggesting that somewhere in the range of 68% and 80% of all projects fail. Agile processes have tried to mitigate this from happening often with significant success. From my experience, a well organized team is often one of the early steps to take to help avoid making a project turn into a disaster, or in some cases, to recover when a project is approaching disaster.

    Concepts

    So, how to go about it. The first thing to understand is how each role plays a part of the team. The team size isn't important for the moment, but there is a minimum size that seems to make sense on all of the successful teams I've been apart of. Here are the roles as I would describe them.

    Scrum Master

    With nods to the Scrum process, we will use this term while attempting to be agnostic of a particular process. So, regardless if you happen to be using Kanban, Crystal, XP, or something else, this particular role frequently shows up. This role is the one responsible for holding the team accountable to the particular process in use, for gathering and reporting team metrics, for removing things which block development, and for managing team conflict. There are perhaps a few other things this role should manage, but in general, this list is sufficient. The person in this role should be very knowledgeable about the process the team is using and be it's champion. This person should have enough management authority to be able to remove blocking items and good communication skills to facilitate discussions with other teams or managers when doing so. However, this person should not be in the chain-of-command for anyone else on the team.  We all would like to please our boss, so if our boss is the person in this role, we potentially prioritize our life to makeing sure the boss likes us rather than for the good of the team. The team is more important.

    Product Owner

    This person is the champion of the project itself. This person represents the Stakeholders, those who are paying for the project, understands clearly the requirements and can articulate them. This role is accountable to the team for making sure requirements are well understood and clearly documented. During team demonstrations with the Stakeholders, this role is responsible for being the team champion and helping the stakeholders understand the value being delivered as described by the demonstration. The person in this role should be able to answer questions from the Stakeholders, understand how requirements are changing and be able to turn that information into requirements for the developers if appropriate. This role is often assisted by a similar role, the Business Analyst, or Requirements Analyst who does most of the actual work of documenting the requirements.

    Developer

    This role is the technical person who will be delivering the requirements in working software in an iterative fashion. This role should be versed in all technologies used by the team and be able to deliver working software using any or all of them. 

    Quality Assurance

    This role is responsible for making sure the requirements are met. The person in this role is able to clearly articulate where software falls short of meeting a requirement or where a gap exists in the requirements. Perhaps the software as delivered meets all the requirements as written, but during testing it failed in a way not accounted for when the requirements were written. 

    Organization

    Team size will largely depend on the size of the project, but generally a minimum number is around five or six members. Of the roles mentioned, Developers usually have the higher number on the team, thus 1 Scrum Master, 1 Product Owner, 2 Developers, 1 Quality Assurance. Team size will grow if the project is larger or when more needs to get done sooner. Keep in mind, adding more team members late will slow down the team temporarily, so starting with four developers is better than adding two later. It is also very important to be as cross-functional as possible. This mostly applies to the Developer and Quality Assurance Role. Sometimes it isn't quite possible due to company organization, but the attempt should be made whenever possible. 

    Additionally, the Scrum Master and Product Owner should be able to handle the other role in a pinch. If the Scrum Master cannot be at a meeting, the Product Owner should be able to fill that role and vice-versa. If neither can be at a meeting, one of the developers should be able to fill the role. 

    With a cross-functional team, however, there should be no expectation that any single role can do all roles exceptionally well. A developer is one because that is what they do well, a person in that role should be able to do the role of a Quality Assurance person, but perhaps not as well as the person whose primary role is Quality Assurance. Of the developers, if one is a UX developer and one is a backend developer, the backend developer might be able to wrangle CSS and Javascript, but perhaps not as quickly or as well as the UX developer. It is important to avoid having silos on a team, so encourage the team to take on any necessary work to avoid that. It is also important for the team as a whole to understand that quality of delivery and testing the project is not soley up to the person in the Quality Assurance role.

    Conclusion

    Consider the teams you have worked with that were successful, and more importantly, those which were highly successful. This blog largely comes from my personal experience with a few highly successful teams I have worked on and is in contrast with other teams not built this way which were not successful. Some were out-right failures. The team failed to work together effectively, the project failed, everyone was mad and everyone lost money. The whole point of agile processes is recognition that this kind of thing happens far too often in our industry. Adapting to change, having clear requirements for at least the next iteration, overcoming exactimates and missed deadlines by adjusting for unknown or unforeseen problems when they arise. Every successful team I have been on has delivered real value, and been much closer to the projected cost estimate (sometimes even coming in under it!) than the teams which expected to be able to live on a Gant chart. While effective team organization is not the panacea for all situations, it is certainly a good place to start when ramping up a project or trying to get one back on track.

    Feb 03 2017
    Feb 03

    At Appnovation, ringing in the New Year is always a time we greatly look forward to at our headquarters, as it’s when we introduce bright, talented students from the Lower Mainland to our technology enabled service experts and mentors! Appnovation continues to sustain its position as a proud supporter of local post secondary schools through the ongoing engagement and bridging of gaps between students and value-added work experience.

    Every January, May, and September, we welcome exceptional students to our global teams to inspire and be inspired by our own. Welcome aboard Zachary, Clarence, Zacharie, and Edward! We look forward to growing with you all. Learn more about these future open source experts below.

    Zachary Chua
    Title: New Business Coordinator Co-op
    Program: Business Administration at Simon Fraser University
    Zachary is currently a fourth year student studying Management Information Systems and Operations Management at Simon Fraser University. Aside from his studies, Zachary is heavily involved in events planning and enjoys participating in case competitions. He is a sociable person who loves to meet new people, play basketball, and do spot-on impressions of his friends. Zachary is most excited about the open work environment of Appnovation and is excited to learn about all of the different roles at the company.

    Clarence Lam
    Title: New Business Coordinator Co-op
    Program: Business Technology Management at The University of British Columbia
    Clarence is a business student with a background in tech, having worked with local tech start-ups before. He came to Appnovation for his first co-op because of his interest in the tech world, and is excited to gain first-hand experience working in such a cool company! He can often be found reading a good book or in a squat rack.

    Zacharie Clouthier
    Title: Project Coordinator Co-op
    Program: Business Administration at Simon Fraser University
    Zac is a fourth year Business Administration student at SFU, concentrating in Finance and Operations Management. In his previous co-op term, he worked for MTU Aero Engines, where he developed KPI reporting and updated shipping processes. His interest in the tech industry is what drew him to Appnovation. Outside of work, he enjoys watching movies and stand-up comedy.

    Edward Chang
    Title: Business Intelligence Analyst Co-op
    Program: Commerce at The University of British Columbia
    Edward has been interested in technology ever since he was a kid, naturally leading him to study Business Technology Management at the UBC Sauder School of Business. He worked at the Corporation of Delta in his past work term, and brings with him a surprising joy for working with data. He is currently working in the Marketing/Sales team at Appnovation, helping maintain and leverage data to support the team in making business decisions. In his spare time, he follows his passions in photography, design, and food.

    To view open co-op job requisitions for May 2017, visit our Careers Page. For further information about our co-op program, internships, student placements, and similar, contact [email protected].

    Jan 30 2017
    Jan 30

    Today I joined the 1000+ other members of the Canadian Tech Community in signing an open letter to support our Prime Minister Justin Trudeau's stance that Canada will and must remain inclusive to all nationalities.

    Diversity is our strength. Any action to undermine the progress our world has made towards peace and harmony has no place in the modern society. I have also made a personal contribution to the ACLU and encourage others to do the same.

    Appnovation is a company built on diversity. A ban against individuals based upon race, religion, or country of birth, implemented by any country cannot be tolerated. We will stand behind all of our team members from the affected countries.

    Jan 29 2017
    Jan 29

    Data transformation is the process of converting data or information from one format to another, usually from the format of a source system into the required format of a new destination system. MuleSoft has developed “DataWeave” - a new language and module for querying and transforming data. DataWeave is a full-featured and fully native framework for querying and transforming data on Anypoint Platform.

    In today’s enterprise infrastructure, system and application integration is more and more frequently a mission critical concern. There are number of Enterprise Service Bus (ESB) products available in the market today. These products can help you remove basic dependencies between applications by eliminating the need for one application to be aware of the other's location, but connectivity is not the only issue. In reality, most systems do not speak same language so Data transformation is one of the most important topic in Integration space.

    Data transformation is the process of converting data or information from one format to another, usually from the format of a source system into the required format of a new destination system. MuleSoft has developed “DataWeave” - a new language and module for querying and transforming data. DataWeave is a full-featured and fully native framework for querying and transforming data on Anypoint Platform. Fully integrated with the graphical interface of Anypoint Studio and DataSense, DataWeave makes even the most complex data integration simple.

    The DataWeave language supports a variety of transformations, from simple one-to-one mappings to more elaborate mappings including normalization, grouping, joins, deduplication, pivoting and filtering. It also supports XML, JSON, CSV, Java and EDI out of the box. The DataWeave Language is a powerful template engine that allows you to transform data to and from any kind of format (XML, CSV, JSON, Pojos, Maps, etc). It is fully integrated with Anypoint Studio, making on-ramp and continued development easy. It includes full integration with DataSense, allowing payload-aware development with auto-completion, auto-scaffolding of transforms, and live previews.

    Let’s learn little bit more about the basics of this elegant and lightweight expression language. DataWeave files are divided into two main sections: 1) The Header, which defines directives (optional) and 2) The Body, which describes the output structure. Both sections are delimited by a separator, which is not required if no header is present. The separator consists of three dashes: "---".

     

    Header

    The DataWeave header contains the directives, these define high level information about your transformation. The structure of the Header is a sequence of lines, each with its own Directives. Through directives you can define:

    • DataWeave version

    • Input types and sources

    • Output type

    • Namespaces to import into your transform

    • Constants that can be referenced throughout the body

    • Functions that can be called throughout the body

     

    Body

    The body contains the expression that generates the output structure. Regardless of the types of the input and output, the data model for the output is always described in the standard DataWeave language, and this model that the transform executes. The data model of the produced output can consist of three different types of data:

     

    Let’s take a look at a simple example to understand more about DataWeave. In this example, we will first transform JSON input data to Java object and finally Java object to XML format.

    Step 1. Import JSON Schema

    Employee JSON Schema
    {
      "title": "Employee Schema",
      "type": "object",
      "properties": {
        "emp_id": {
          "type": "integer"
        },
        "first_name": {
          "type": "string"
        },
        "last_name": {
          "type": "string"
        },
        "preferred_first_name": {
          "type": "string"
        },
        "preferred_last_name": {
          "type": "string"
        },"dob": {
          "type": "string"
        },
        "active": {
          "type": "string"
        },
        "addresses": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "address_line1": {
                "type": "string"
              },
              "address_line2": {
                "type": "string"
              },
              "city": {
                "type": "string"
              },
              "state": {
                "type": "string"
              },
              "zip_code": {
                "type": "string"
              },
              "country": {
                "type": "string"
              }
            },
            "required": [
              "address_line1",
              "city",
              "state",
              "zip_code",
              "country"
            ]
          }
        },
        "contacts": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "home": {
                "type": "string"
              },
              "cell": {
                "type": "string"
              },
              "fax": {
                "type": "string"
              },
              "primary_email": {
                "type": "string"
              },
              "secondary_email": {
                "type": "string"
              }
            }
          }
        }
      },
      "required": [
        "emp_id",
        "first_name",
        "last_name",
        "dob",
        "active"
      ]
    }
    

    Step 2. Import XML Schema

    Employee XML Schema
    <?xml version="1.0" encoding="UTF-8"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.example.org/xml_schema_employee/"
      targetNamespace="http://www.example.org/xml_schema_employee/">
      <element name="Employee" type="tns:Employee"></element>
      <complexType name="Employee">
        <sequence>
          <element name="empId" type="integer" maxOccurs="1" minOccurs="1">
          </element>
          <element name="firstName" type="string" maxOccurs="1"
            minOccurs="1">
          </element>
          <element name="middleName" type="string" maxOccurs="1"
            minOccurs="0">
          </element>
          <element name="lastName" type="string" maxOccurs="1"
            minOccurs="1">
          </element>
          <element name="preferredFullName" type="string" maxOccurs="1"
            minOccurs="0">
          </element>
          <element name="dateOfBirth" type="string" maxOccurs="1"
            minOccurs="1">
          </element>
          <element name="isActive" type="boolean" maxOccurs="1"
            minOccurs="1">
          </element>
          <element name="address" type="tns:Address" maxOccurs="unbounded"
            minOccurs="0">
          </element>
          <element name="contact" type="tns:Contact" maxOccurs="unbounded"
            minOccurs="0">
          </element>
        </sequence>
      </complexType>
      <complexType name="Address">
        <sequence>
          <element name="line1" type="string" maxOccurs="1" minOccurs="1">
          </element>
          <element name="line2" type="string" maxOccurs="1" minOccurs="0">
          </element>
          <element name="city" type="string" maxOccurs="1" minOccurs="1">
          </element>
          <element name="state" type="string" maxOccurs="1" minOccurs="1">
          </element>
          <element name="zip" type="string" maxOccurs="1" minOccurs="1">
          </element>
          <element name="country" type="string" maxOccurs="1"
            minOccurs="1"></element>
        </sequence>
      </complexType>
        <complexType name="Contact">
          <sequence>
            <element name="home" type="string" maxOccurs="1"
              minOccurs="0">
            </element>
            <element name="mobile" type="string" maxOccurs="1"
              minOccurs="0">
            </element>
            <element name="fax" type="string" maxOccurs="1"
              minOccurs="0">
            </element>
            <element name="email" type="tns:Email" maxOccurs="1"
              minOccurs="0">
            </element>
          </sequence>
        </complexType>
        <complexType name="Email">
          <sequence>
            <element name="primary" type="string" maxOccurs="1"
              minOccurs="0">
            </element>
            <element name="secondary" type="string" maxOccurs="1" minOccurs="0"></element>
          </sequence>
        </complexType>
    </schema>
    

    Step 3. Create Java Classes

    Employee.java
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    public class Employee implements Serializable {
    
      private static final long serialVersionUID = 830974489967994125L;
      private Integer employeeId;
      private String firstName;
      private String middleName;
      private String lastName;
      private String preferredFullName;
      private Date dateOfBirth;
      private boolean active;
      private List<Address> addresses;
      private List<Contact> contacts;
      public Integer getEmployeeId() {
        return employeeId;
      }
      public void setEmployeeId(Integer employeeId) {
        this.employeeId = employeeId;
      }
      public String getFirstName() {
        return firstName;
      }
      public void setFirstName(String firstName) {
        this.firstName = firstName;
      }
      public String getMiddleName() {
        return middleName;
      }
      public void setMiddleName(String middleName) {
        this.middleName = middleName;
      }
      public String getLastName() {
        return lastName;
      }
      public void setLastName(String lastName) {
        this.lastName = lastName;
      }
      public Date getDateOfBirth() {
        return dateOfBirth;
      }
      public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
      }
      public boolean isActive() {
        return active;
      }
      public void setActive(boolean active) {
        this.active = active;
      }  
      public String getPreferredFullName() {
        return preferredFullName;
      }
      public void setPreferredFullName(String preferredFullName) {
        this.preferredFullName = preferredFullName;
      }
      public List<Address> getAddresses() {
        if (addresses == null) {
          addresses = new ArrayList<Address>();
        }
        return addresses;
      }  
      public void setAddresses(List<Address> addresses) {
        this.addresses = addresses;
      }
      public List<Contact> getContacts() {
        if (contacts == null) {
          contacts = new ArrayList<Contact>();
        }
        return contacts;
      }  
      public void setContacts(List<Contact> contacts) {
        this.contacts = contacts;
      }
    }
    
    Contact.java
    import java.io.Serializable;
    
    public class Contact implements Serializable {
    
        private static final long serialVersionUID = 8191183310915009265L;
        private String homePhone;
        private String cellPhone;
        private String fax;
        private Email email;
    
        public String getHomePhone() {
            return homePhone;
        }
        public void setHomePhone(String homePhone) {
            this.homePhone = homePhone;
        }
        public String getCellPhone() {
            return cellPhone;
        }
        public void setCellPhone(String cellPhone) {
            this.cellPhone = cellPhone;
        }
        public String getFax() {
            return fax;
        }
        public void setFax(String fax) {
            this.fax = fax;
        }
        public Email getEmail() {
            return email;
        }
        public void setEmail(Email email) {
            this.email = email;
        }
    }
    
    Address.java
    import java.io.Serializable;
    
    public class Address implements Serializable {
    
        private static final long serialVersionUID = -4178015379362625254L;
        private String line1;
        private String line2;
        private String city;
        private String state;
        private String zipCode;
        private String country;
    
        public String getLine1() {
            return line1;
        }
        public void setLine1(String line1) {
            this.line1 = line1;
        }
        public String getLine2() {
            return line2;
        }
        public void setLine2(String line2) {
            this.line2 = line2;
        }
        public String getCity() {
            return city;
        }
        public void setCity(String city) {
            this.city = city;
        }
        public String getState() {
            return state;
        }
        public void setState(String state) {
            this.state = state;
        }
        public String getZipCode() {
            return zipCode;
        }
        public void setZipCode(String zipCode) {
            this.zipCode = zipCode;
        }
        public String getCountry() {
            return country;
        }
        public void setCountry(String country) {
            this.country = country;
        }
    }
    
    Email.java
    import java.io.Serializable;
    
    public class Email implements Serializable {
    
        private static final long serialVersionUID = 6412135990330505529L;
        private String primary;
        private String secondary;
    
        public String getPrimary() {
            return primary;
        }
        public void setPrimary(String primary) {
            this.primary = primary;
        }
        public String getSecondary() {
            return secondary;
        }
        public void setSecondary(String secondary) {
            this.secondary = secondary;
        }
    }
    

    Step 4. Write Mule Flow in Anypoint Studio

    Step 5. Write XML to Java Transformation

    DW Transformation (XML to Java)
    %dw 1.0
    %output application/java
    ---
    {
      active: payload.active as :boolean,
      addresses: payload.addresses map ((address , indexOfAddress) -> {
        city: address.city,
        country: address.country,
        line1: address.address_line1,
        line2: address.address_line2,
        state: address.state,
        zipCode: address.zip_code
      }),
      contacts: payload.contacts map ((contact , indexOfContact) -> {
        cellPhone: contact.cell,
        email: {
          primary: contact.primary_email,
          secondary: contact.secondary_email
        },
        fax: contact.fax,
        homePhone: contact.home
      }),
      dateOfBirth: payload.dob as :date { format: "yyyyMMdd"},
      employeeId: payload.emp_id,
      firstName: payload.first_name,
      lastName: payload.last_name,
      preferredFullName: payload.preferred_first_name ++ " " ++ payload.preferred_last_name
    } as :object {
      class : "com.appnovation.dataweave.example.Employee"
    } 
    

    Step 6. Write Java to Json Transformation

    DW Transformation (Java to XML)
    %dw 1.0
    %output application/xml
    %namespace ns0 http://www.example.org/xml_schema_employee/
    ---
    {
      ns0#Employee: {
        empId: payload.employeeId,
        firstName: payload.firstName,
        middleName: payload.middleName,
        lastName: payload.lastName,
        preferredFullName: payload.preferredFullName,
        dateOfBirth: payload.dateOfBirth as :string,
        isActive: payload.active,
        (payload.contacts map ((contact , indexOfContact) -> {
          contact: {
            mobile: contact.cellPhone,
            home: contact.homePhone,
            fax: contact.fax,
            email: {
              primary: contact.email.primary,
              secondary: contact.email.secondary
            }
          }
        })),
        (payload.addresses map ((address , indexOfAddress) -> {
          address: {
            line1: address.line1,
            line2: address.line2,
            city: address.city,
            state: address.state,
            zip: address.zipCode,
            country: address.country
          }
        }))
      }
    }  
    

    Step 7. Input and Output

    Input Data (JSON Format)
    {
      "emp_id": 112233,
      "first_name": "Sagar",
      "last_name": "Chaudhari",
      "dob": "19860307",
      "preferred_first_name": "Sagar",
      "preferred_last_name": "Chaudhari",
      "active": true,
      "addresses": [
        {
          "address_line1": "120 Spanish",
          "address_line2": "A",
          "city": "San Francisco",
          "state": "California",
          "zip": "94100",
          "country": "USA"
        },
        {
          "address_line1": "120 Encanto",
          "address_line2": "B",
          "city": "St Louis",
          "state": "Missouri",
          "zip_code": "63001",
          "country": "USA"
        }
      ],
      "contacts": [
        {
          "home": "111-111-1111",
          "cell": "222-222-2222",
          "fax": "333-333-3333",
          "primary_email": "[email protected]",
          "secondary_email": "[email protected]"
        },
        {
          "home": "555-555-5555"
        }
      ]
    } 
    
    Output Data (XML Format)
    <?xml version='1.0' encoding='UTF-8' ?>
    <ns0:Employee xmlns:ns0="http://www.example.org/xml_schema_employee/">
        <empId>112233</empId>
        <firstName>Sagar</firstName>
        <middleName xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
        <lastName>Chaudhari</lastName>
        <preferredFullName>Sagar Chaudhari</preferredFullName>
        <dateOfBirth>1986-03-07T00:00:00</dateOfBirth>
        <isActive>true</isActive>
        <contact>
            <mobile>222-222-2222</mobile>
            <home>111-111-1111</home>
            <fax>333-333-3333</fax>
            <email>
                <primary>[email protected]</primary>
                <secondary>[email protected]</secondary>
            </email>
        </contact>
        <contact>
            <mobile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            <home>555-555-5555</home>
            <fax xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            <email>
                <primary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                <secondary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </email>
        </contact>
        <address>
            <line1>120 Spanish</line1>
            <line2>A</line2>
            <city>San Francisco</city>
            <state>California</state>
            <zip xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            <country>USA</country>
        </address>
        <address>
            <line1>120 Encanto</line1>
            <line2>B</line2>
            <city>St Louis</city>
            <state>Missouri</state>
            <zip>63001</zip>
            <country>USA</country>
        </address>
    </ns0:Employee>
    

     

    References 

    http://mulesoft.github.io/data-weave/

    https://www.mulesoft.com/integration-solutions/dataweave-integration

    https://docs.mulesoft.com/mule-user-guide/v/3.7/dataweave-reference-docu...

    https://docs.mulesoft.com/mule-user-guide/v/3.7/dataweave-tutorial

     

    Advantages

    • Mapping and transforming with DataWeave eliminates error-prone custom code

    • Rules, lookups, and editing capabilities enable advanced transformations

    • DataSense™ discovers end-point meta-data for intelligent design

    • Delivers both batch and real-time event-driven data integration capabilities

    • Supports XML, JSON, CSV, POJOs, Excel, and more

     

    Jan 23 2017
    Jan 23

     

    "The power of the Web is in its universality.  Access by everyone regardless of disability is an essential aspect."
    - Tim Berners-Lee, W3C Director and inventor of the World Wide Web

    Accessibility should be a key requirement for any website project. Unfortunately, it is often regarded as an add-on with low priority for most businesses and developers.

    The biggest mistake is assuming that the proportion of people with accessibility requirements is low and insignificant, and that focus on accessibility will only help a 'tiny' subset of users. However, this is definitely not the case, and ignoring accessibility is missing an opportunity for all of your users.

    Why is Accessibility Important?

    Almost 1 in 5 people in the US have a disability, and more than half of adults with a disability currently go online (Interactive Accessibility, 2012). Disabilities include little to no use of senses like seeing and hearing, and also difficulty with motor skills such as lifting and gripping. This means that some of your users won’t be able to see or hear what’s going on in a webpage, whilst others will have difficulty navigating it without some sort of assistance.

    BUT, accessibility isn’t only about users with disabilities. To put things into perspective, all human beings have accessibility requirements. We are all limited by our bodies and our minds, and need human interfaces to interact with our computers. Even if you consider yourself to have no disabilities, there will be a point where text and images are too small or do not have enough colour contrast to allow them to be readable.

    Feedback sounds and audio in video clips, are not only inaccessible to those who are deaf and hard of hearing, but also not heard by users with devices on silent or volume turned down.

    Users can also become 'temporarily disabled' due to injury or medication that they are taking, which can hamper their ability to navigate the web. There are also situations where able people are restricted, such as mothers holding their newborns or carers who cannot afford to spend time and focus on complex interfaces.

    The best thing about designing and developing with accessibility in mind is that you will be forced to create websites and apps that are easy to understand and use for everyone (including robots - more on that later).

    Accessibility in Drupal 8

    Drupal 8 has had significant effort put into creating it to ensure that the websites developed with it are universal and accessible. Many improvements to both default settings as well as tools for developers create a strong foundation to create websites for everyone.

    WAI-ARIA attributes have been included to provide semantic meaning to elements where HTML5 does not suffice, allowing for screen readers to be able to distinguish and identify sections and components better.

    Images uploaded by content editors, whether through image fields or WYSIWYG editors, require Alt tags by default, encourage developers to enforce accessible image content.

    Drupal’s Form API sees improvement to radios and grouped checkboxes, which now use fieldsets to improve output from screen readers, as well as error messages which, through an optional, experimental core module, can be placed inline with fields.

    Several tools are available to developers to allow them to improve user experience, including Announce, a means by which direct output can be sent to screen readers to replace more visual cues, and a JavaScript alert for audible announcements so that audio cues aren’t missed by those with hearing difficulties.

    Developers can also help screen readers and power users navigate by taking advantage of the new TabbingManager and declaring the logical order by which users should navigate through the page’s dynamic elements.

    Drupal 8 strongly encourages the integration of libraries so that existing technologies can compliment each other and share their efforts in achieving an accessible world. Examples include Drupal’s replacement of it’s autocomplete functionality with that of jQuery UI, whilst also borrowing their modal dialogs for Views UI.

    Other steps have also been taken towards framework unity, where Hidden / Invisible / On-focus declarations have now been standardized with HTML5 Boilerplate, and work well in Firefox as well as Safari on Macs, iPhones & iPads.

    Not just Web Accessibility

    Drupal 8 does more to make the web more accessible than just focusing on core tent-pole features of "Web Accessibility". Making the web accessible worldwide also means delivering content to people in all locations, in any language, surpassing any technological restrictions there may be.

    New to core Drupal in version 8 are modules for Translation and Localization, as well as performance improvements in the form of faster page loading and responsive websites. Enchancements have been made to site translations and language maintenance, including an incredibly simple interface for translating content.

    With every default theme being made responsive and a strong focus on allowing efficient mobile-first design flows, Drupal 8 is now a great place to start with a project that is accessible to every device, especially in areas where mobile device access is more common than traditional computers, and internet connectivity and power is limited.

    Robots, Cars and Fridges

    Whilst we may not have artificial intelligence yet, nor robots running around doing our bidding, the machines that we have today and will have tomorrow are already learning how to interpret our data to compliment our experience online and improve our lifestyles.

    Search engines like Google are learning to interpret more of our content to help find us the information we want faster, and social networks and news feeds can determine what content we want to see the most.

    With in-car media systems always improving, with large displays and more computational power, it would make sense that whilst a driver is focusing on the road, they could be using accessibility tools to order something from a website without having to look at a screen.

    In the same way, refrigerators which already nowadays can come with screens and the ability to reorder items from your favourite store, could potentially scan other websites when your regular store is out of stock, and suggest alternatives or even make the order for you.

    So the next time you think about accessibility, remember it’s not just about helping the less abled, but also about improving experiences for everyone … even robots.

    Additional Resources

    Jan 18 2017
    Jan 18

    Drupal is the #1 platform for web content management systems. It powers millions of websites in more than 180 languages, with a massive online community with more than 26,000 constantly building and sharing themes and resources. As a big part of Drupal projects, UX is one of the most important aspects of the design process.

    Many people regard web design as decoration; the art of making a website look good. However, design is more about how something works than how it looks. Good design is about both form and function. In contrast with art, good design is not only visually and emotionally appealing but is made for use.

    UX design is about usability

    "Design is not just what it looks like and feels like. Design is how it works." - Steve Jobs

    We built interaction based on what we thought worked — we designed for ourselves. The focus was on aesthetics and the brand, with little to no thought of how the people who would use the website would feel about it. Usability allows people to easily accomplish their goals.

    Here are some of good Drupal websites that I have picked for those lastest design feature - Background Videos And Animations; Hover Animations; Scrolling and Motion Animations.

    Citroën Origins

    websiteurl-CitroenOrigins.jpg

     

    The Wisconsin Institutes for Discovery

    websiteurl-WisconsinInstitute.jpg

     

    Basel.com

    websiteurl-Basel.jpg

     

    Jack Daniel's

    websiteurl-JackDaniels.jpg

     

    Chais d'œuvre

    websiteurl-ChaisDoeuvre.jpg

     

    Jurassic World

    websiteurl-JurassicWorld.jpg

     

    WWF

    websiteurl-WWF.jpg
    Jan 17 2017
    Jan 17

    The What
    Many of us working in the tech sector are very aware of the commonly used phrase, ‘employer branding’. LinkedIn puts it well, stating, “Employer branding is the process and action of promoting a company or organization as an employer of choice to a specific targeted group; one of which the objective is to recruit, motivate, and retain.” To showcase an employer brand, companies highlight the benefits, standards, and values associated with their workplace in recruitment strategies and communications.

    As trends and hot topics change over time, employer branding is becoming outshadowed by what is known as ‘talent branding’. As defined by LinkedIn, “Talent branding is the highly social, totally public version of an employer brand that incorporates talent thinks, feels, and shares about your company as a place to work.” This differs from employer brands, which are set and guided by the company, rather than being influenced from the public.

    To put it simply, there is an increasingly wide spectrum of talent in the marketplace, meaning we have to be seen from the outside… by the talent. This is why our talent brand matters.

    An unfortunate truth, plaguing the workplace, is not enough companies believe that building and nourishing an employer brand is all it takes to see huge business returns. Historically, workplaces view their employees as static human capital. Today, we have a vibrant, engaged, and active talent pool, fueled significantly by millennial values. This talent source is where companies must learn to better understand people, while building a compelling brand.

    The Why
    As Appnovation sustains its position in a period of growth, we value the importance of always staying ahead of trends; never behind. We're making our talent branding objectives a top priority, this quarter and those to come. Talent branding has a massive impact on how any business is perceived internally and externally, and we understand that. This ranges from the broadest of positions in our geographical regions, to the pre-candidates, and to capturing the minds of our own employees. Long story short, talent branding is not something to be left to grow in an organic way; rather, it’s a strategic asset.

    Your talent brand is far more valuable than you realize. LinkedIn has launched a very worthwhile guideline called their ‘Employer Brand Playbook’. The playbook reinforces the value of a strong talent brand and reminds us that with a genuine and powerful plan in place that...

    “You’ll spend less on hiring. Lower your cost per hire by as much as 50%.”

    AND

    “You’ll boost retention. Reduce employee turnover by up to 28%.”

    As mentioned, you can’t expect a talent brand to be implemented and flourish organically; companies have to design a cycle of nourishment to keep it active, engaging, and compelling at all times. Find ways to publish the most eye-catching, intriguing, and innovating messages, while monitoring it, moulding, adding-to and taking away, and repeating. Skipping or neglecting these steps will waste your time, the businesses time, and see no solid ROI. The second you allocate focus away from your talent brand, you will notice your direct competitors using their own campaigns to get in front of your talent pool. 

    The How
    The determination and planning around a talent brand is unique to any business, but as a best practice, the LinkedIn Branding Playbook is any professional’s go to. There are also other great resources available to help you upgrade your talent branding strategy, including this great article on Instagram talent brands.

    The 5 steps to building your talent brand campaign are below. This has been released directly by LinkedIn and referenced from their Playbook.

    1. Get Buy-In
        a.  Start at the top
        b.  Arm yourself with data
        c.  Bring partners to the table
    2. Listen and Learn
        a.  Audit your existing materials
        b.  Conduct research based on who, what, where, when, and how
    3. Craft Your Approach
        a.  Be real
        b.  Be personal
        c.  Be brave
        d.  Be consistent
        e.  Set your goals
        f.  Test drive your messaging
    4. Promote and Engage
        a.  Empower your employees
        b.  Target your messages
        c.  Make your culture shine
        d.  Be visual, and more!
    5. Measure and Adjust
        a.  Explore and apply Talent Brand Index
        b.  Choose your key indicators

    Talent brand is key to making connections within and outside of your business; just remember, as times change, so will your talent brand. Building out and managing your talent brand strategy will always be a work in progress. The reach potential and impact businesses have will quickly correlate with increased hires and reduced retention. I challenge you to re-think how your company portrays their employer brand and how talent brand can bring value overall.

    Dec 22 2016
    Dec 22

    Thinking globally and acting locally is an important part of the holidays. As part of our Corporate Citizenship program, each of Appnovation’s offices participated in charitable giving initiatives selected by our staff.

    A key pillar of our social giving program is to ensure the Appnovation team has a voice in leading new initiatives and opportunities. In the spirit of our AppnoXmas campaign of 2015, this year’s campaigns were entirely different by office location.

    Our Vancouver team kicked off this year’s charitable giving season with a little competition. Held in November, Appnovation participated in TechPong 2016 by raising $1500 for the BC SPCA. Though we didn’t walk away with the grand prize, we undoubtedly won at the photobooth.

    Following TechPong, our team partnered with the Greater Vancouver Food Bank to volunteer at CBC Day, as well as donate roughly $400 and provide non-perishable food items. Food Banks of British Columbia raised over $700K on CBC Day, which featured an open house tour of the Vancouver CBC studio, along with the telethon benefitting food banks across the province.


    A few members of our Vancouver volunteers at CBC Day

    In Montréal, our team partnered with Dans la rue, an organization that works with at-risk and homeless youth in the city. After a hard day of work, our team travelled to the Dans la rue office to give back by preparing a meal for the youth registered in their programming. That evening our team packed 1500 hotdogs, and were able to have a great time listening to music and learning more about Dan la rue’s programming on site.

    Chelsea Assimes, part of Appnovation’s Talent & Culture team, remarks, “We’re an office that understands the value of giving; organizing this event with Dans la rue really let us live our core values of openness and teamwork.”


    Our MTL team prepping hotdogs for Dans la rue!

    Similar to last year, our Saint John team partnered with their local charity of choice, Partners Assisting Local Schools (PALS). Saint John has one of the highest child poverty rates in Canada. The city also has the highest percentage of children in low-income families, ranking last among 57 ‘Cities Reducing Poverty’ communities.

    Our team sent a wishlist with their families’ needs and wants, that included the basics for most of us: socks, underwear, mittens, hats, and pajamas. The SJ team worked together to purchase and wrap these gifts for the family.

    "The holidays are a busy time for all of us, and it's easy to get wrapped up in the gift-giving frenzy, but giving back with our Appnovation family to a family in need is really what the holiday season is about," says Vanessa Burley, Appnovation's Marketing Coordinator. 

     

    The team went above and beyond to make sure their family had the Christmas they deserved. Vanessa and Melissa of our SJ squad braved a snowstorm to fill a cart with all the fixings for a turkey dinner and full Christmas Day breakfast, making sure, this year, the family has a Christmas to remember!


    Handing over the SJ donation to their PALS partner

    Over in the UK our Reading and Cardiff teams chose two different causes. Reading chose to support the organization Dogs for Good. This non-profit makes life changing differences for people with disabilities. Dogs for Good works to support people and communities through the assistance of a trained dog, improving and enriching the lives of both. They offer three main services, Assistance Dogs, Community Dogs and Family Dogs.

    The team donated a box of dog toys and treats to Erica, a Dogs for Good trainer, as well as Danny, one of their talented assistant dogs.


    Reading presenting presents to their new furry friends!

    Our Cardiff team opted to select a cause similar to our Vancouver team’s - The Trussell Trust, a local food bank dedicated to impacting the lives of hundreds of thousands across the UK. Michael Parker, of our MS team reflects: “I was pleasantly surprised that the Appnovators of the UK were all on board with our initiative, raising over £100 in donations.” Michael, and other team members, will be doing a shopping trip with their funds in the New Year. Stay tuned for a separate update on this initiative!

    Rounding out our global offices, our Hong Kong team voted to support the Salvation Army. Sue-Ellen Leung, our talented Office Admin, comments: “We chose the Salvation Army to give back our community. We donated some clothes to the charity in order to keep those in need warm during the festive season. The Salvation Army donates clothes to people in need, such as the elderly, homeless people, ex-prisoners, and welfare recipients.”


    Some of the Hong Kong team's donation to the Salvation Army

    As always, AppnoXmas means fun, festivity, and fulfillment. This annual initiative is a way for our people to connect to causes that matter to them, and introduce others to the spirit of giving. We’d like to send a big thank-you to all of our partners, supporters, and staff members who make initiatives like this possible.

    Check out our Corporate Citizenship hashtag #WeDevelopChange to catch up on all of our activities!

    Pages

    About Drupal Sun

    Drupal Sun is an Evolving Web project. It allows you to:

    • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
    • Facet based on tags, author, or feed
    • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
    • View the entire article text inline, or in the context of the site where it was created

    See the blog post at Evolving Web

    Evolving Web