Jan 04 2018
Jan 04

In our last post, we talked about how great DrupalVM is by providing Drupal developers a robust development environment that can be used with multiple types of applications. And while the installation process is fairly straightforward, it can take some trial and error in updating your config.yml file for the perfect hosting environment. Are you managing multiple virtual machines for multiple client projects? This can take up a significant amount of space on your computer’s resources (RAM and hard drive space). This post will walk you through how we addressed some of these common problems to optimize your DrupalVM environments.

Network Management and Vagrant Plugins

When multiple instances of DrupalVM, you will need to enter a new hostname, machine name, and IP address for each instance. Unfortunately, we can’t have more than one instance using the same hostname like *.drupalvm.dev that points to a local address. The likelihood of you picking the same IP address as another device or service on your network is slim, but what if you never had to worry about that?

This is where we look towards some Vagrant Plugins to help us manage our network configuration. As you should know by now, DrupalVM is built on top of Virtualbox and Vagrant. Virtualbox (VB) is a virtualization software that in a nutshell, runs an operating system (OS) on top of your own OS. Vagrant is a tool that helps orchestrate the building of that OS through a configuration file called a Vagrantfile. As there are almost endless combinations of Vagrant options, we can use Vagrant plugins to help automate part of the configuration. There are three main plugins we use with DrupalVM:
  1. vagrant-auto_network
  2. vagrant-hostsupdater (now included by default)
  3. vagrant-vbguest (now included by default)
As of June 2017, the VBGuest and Hosts Updater are now automatically installed when you setup DrupalVM (unless manually overridden in the config.yml file). VBGuest helped to keep the Virtualbox Guest Additions software up-to-date (which VB uses to talk between the guest and host operating systems), and Hosts Updater automatically updated your local /etc/hosts file with domains configured in your config file by adding a unique hash next to each record. So, if you power off or destroy your instance, it will clean up those host records as well.

My other favorite plugin is vagrant-auto_network, which manages local IP addresses if you have multiple machines running on your computer. Instead of manually adding an IP address (which is sometimes necessary for external tunneling), you can just put in 0.0.0.0 and let Auto Network assign one for you!

Drupal 7 vs. Drupal 8

One of our core products is a distribution called Open Enterprise, a base profile for content marketing that is built on Drupal 7. While the basic hosting requirements between D7 and D8 are minimal, there are a few gotchas that you can work through.

  • Disable composer build (drupal_build_composer_project)
    If you’re using D7, you most likely aren’t using composer - so don’t bother with the build process.
     
  • Disable Drupal build (drupal_install_site)
    If you’re dealing with a shared codebase (like a Github repo or project on Pantheon / Acquia), then put all of your client projects in one direct and link that using synced folders.
     
  • Downgrade PHP (php_version)
    While Drupal 7 core works fine out of the box with PHP 7.x, there can be some deprecation issues with contrib modules. If you run into anything, downgrade this to 5.6.
     
  • Downgrade Solr (solr_version)
    If your project requires Search API Solr and runs on Drupal 7, you will need to downgrade your Solr version to 5.4.1 as the default 5.5.x which is not supported. There are more fixes to this specific issue, but this is the first step.

Resource Management

While DrupalVM is a great tool to mimic production environments and you can get a local Drupal site up and running in a matter of minutes, there can be a resource drawback when running multiple VM instances on your computer.

Every DrupalVM instance is essentially an entire Ubuntu server, which means even without a Drupal site (code, files, database) you’re already using around 4 GB of hard drive space every time you add a new DrupalVM. Then depending on the size of each site, and your VMs can start growing very quickly, and now your 256 GB solid state hard drive is almost to capacity with virtual machines.

One solution to this is to share a single VM instance when you have multiple, similar ongoing projects. This takes a few manual steps in your configuration YAML file.

  1. Use a grouped directory to store all of your similar projects, then sync that to your DrupalVM instance.
    vagrant_synced_folders:
    
      - local_path: /Users/developer/websites
    
        destination: /var/www/websites
    
        type: nfs
    
        create: true
    1. Create a custom variable to use throughout the YAML configuration for this new path.
       
    # Custom path for websites directory.
    
    websites_path: "/var/www/websites”
    1. Using the new variable, set up all your projects under the apache_vhosts variable.
    # Apache VirtualHosts.
    
    apache_vhosts:
    
      - servername: “project.{{ drupal_domain }}"
    
        documentroot: "{{ websites_path }}/project"
    
        extra_parameters: "{{ apache_vhost_php_fpm_parameters }}"
    
    
      - servername: “multisite.{{ drupal_domain }}"
    
        serveralias: “multisite1.{{ drupal_domain }} multisite2.{{ drupal_domain }}"
    
        documentroot: "{{ websites_path }}/multisite/docroot"
    
        extra_parameters: "{{ apache_vhost_php_fpm_parameters }}”
    1. Add your databases to the list (you only need the database name), and for simplicity sake, you can set the primary Drupal database user to have access to ALL databases (i.e., use *.* for privileges).
    # MySQL databases and users.
    
    mysql_databases:
    
      - name: "{{ drupal_db_name }}"
    
      - name: "{{ drupal_db_name }}_project"
    
      - name: "{{ drupal_db_name }}_multisite”
    
      - name: "{{ drupal_db_name }}_multisite1”
    
      - name: "{{ drupal_db_name }}_multisite2”
    
    
    mysql_users:
    
      - name: "{{ drupal_db_user }}"
    
        host: "%"
    
        password: "{{ drupal_db_password }}"
    
        priv: "*.*:ALL”
    1. (optional) Set your SSH Home variable to your custom project path variable.
    ssh_home: "{{ websites_path }}”

    SED Scripting

    While all of this custom management is great to work through, it really does suck to do it over and over again. But my frustrations become your gain, as I’ve written a short bash script hosted on GitHub Gist that takes care of most of the basic legwork for copying and modifying the config.yml file (you can find this script by visiting the link here).

    Be aware of the comment I posted on that page regarding the sed -i option if you’re working on a Mac, and the simplest solution is to install gnu-sed using Homebrew (brew install gnu-sed).

    I hope this has helped simplify your DrupalVM setup process, and if you have your own tips and tricks for using DrupalVM, be sure to add them to the comments below!

    Jan 02 2018
    Jan 02

    Over the past couple years, there has been a lot of improvements in developer tools and workflows for building new Drupal projects. As Drupal has grown over the past few years, we have seen added frameworks such as Twig and Symfony, workflow related tools like Composer and Drupal Console, and even new virtual environments. With added tools came increased complexity in development environments, and sometimes, even more issues if you’re building on more than on type of framework for client projects.

    In the past, we as developers were usually stuck in-between a rock and a hard place when it came to development environments. Either you had the pre-built software that might not have everything you need depending on your clients and hosting options, like Acquia Dev Desktop, MAMP, XAMPP, etc. Or you would have to build your own local server using script management like Homebrew or Macports, and then search the internet to cobble together the right Nginx configuration for Drupal, asking yourself “where are my MariaDB databases?", and dealing with mismatched versions of PHP running at the same time.

    What. a. nightmare.

    New development

    Luckily, there’s been a lot of work put into new development environments for Drupal (that we can also use with other PHP-based content management systems). Most of these development environments have been split into two types - Docker and Vagrant. These tools are simply just different approaches to virtual server management. While the details aren’t really important right now, the main difference is that Docker takes the container approach while Vagrant takes the virtual machine approach (you can read more about container vs. virtual machines). Some of the more recent development environment solutions have been Docker-based (such as Docksal and Kalabox / Lando), we have chosen to work with DrupalVM, built on Vagrant and Ansible (which now includes support for Docker!). Fun fact! Two of the main Drupal hosting companies LevelTen works with use these two different technologies: Acquia is a VM based server solution while Pantheon is built on containers.

    Config Management

    DrupalVM has some of the easiest configuration and plugin options at your development disposal per environment. Not only does DrupalVM come preinstalled with the basic Drupal tools like Drush, Memcache, and Xdebug, but we can also enable modern development tools such as Node.js, Selenium (Behat), and advanced profiling tools like Blackfire and Tideways. All of these can be included simply by uncommenting them in your config and re-provisioning your server.

    Aside from plugins, there’s virtually no reasonable limits to what we can configure in our environment per the configuration YAML file. You can switch between versions of PHP, serve from Apache or Nginx, store in Postgres or MySQL, build our projects using Composer, and update php.ini settings in a breeze.

    Bonus: If you use PHPStorm as your main development IDE, it already supports Vagrant and getting Xdebug running is as simple as hitting a button.

    RTFM

    For me, one of the greatest benefits of DrupalVM is the documentation behind the project. Maintained by Jeff Geerling (geerlingguy), the project documentations answers almost all of your basic needs for getting up and running with DrupalVM, from enabling Solr to switching out MySQL with MariaDB, the documentation is verbose and well-written.

    For those times when the docs just aren’t enough, this is when we’re thankful for open source and GitHub. Since the whole project is hosted on GitHub, there are many open and closed issues we can search through to find the answer to a problem that might have been fixed. In addition, if we do have a problem, GitHub makes submitting new issues easy to submit and collaborate on solutions.

    Getting Started

    Of course, what kind of blog post would this be if we didn’t tell you how to install DrupalVM? Luckily for us, there’s a Quickstart Guide and we don’t have to write this all out. But for the sake of brief knowledge, it’s really three basic steps:

    2. Download or clone the DrupalVM project to your computer.

    3. In your terminal, cd into the project directory and run vagrant up.

    That’s it! After using MAMP for years as an easy-to-manage development environment, it left a lot to desire for added functionality and mucking up my dotFiles switching between PHP CLI versions. DrupalVM can technically support any PHP based CMS site, so if you’re coming from Drupal 7 or WordPress and have never seen YAML before, now’s a great time to learn it and apply those skills in managing your configuration files.

    In a future blog post, we will talk about some improvements and automation you can use to streamline your DrupalVM installation.

    (If you’re a WordPress developer and have used Local Flywheel or Trellis, let us know your thoughts as well!)
    Aug 04 2017
    Aug 04

    Alright, it has been a few weeks. So, what have I been up to? Well, the first couple weeks were all about Drupal basics and learning about all the different tools we would be using. It started off as an information avalanche.

    Real WOrk

    Once we started doing some hands-on work, it clicked a little better. The first task we had was updating websites on Pantheon that didn't have a profile associated with it. This situation gave us the opportunity to some practice in with the Pantheon dashboard and hosting sites locally with Vagrant. This seemed a lot easier in concept than in execution. On the bright side, I now feel pretty comfortable manipulating Vagrant.

    Working with Pantheon and Multisites

    My next task was updating sites in Pantheon that did have a profile. While updating the process of updating these sites was more complicated than the sites without a profile, I found that they were usually quicker. I discovered that most of the modules on a site were stored in the profile. This meant that once you updated the upstream once, it could be applied to all of the sites using it. Usually, after implementing the changes in the upstream, there was only a few if any, modules left to update. It makes a lot of sense to have an upstream for sites that are similar. Even with the added complexity, it makes the process a lot smoother and consistent.

    Learning to Work with A Team

    Learning how a small company operates is probably the single most valuable insight I got from this experience. The way the team communicates with each other, tackles problems, keeps track of time and divides the workload. In all my work experience up until this point, I have been given a project and seen it through from start to finish. Here there is a divide in work. I might be the one to update the modules on site, but someone else checks it and pushes it to live. Working with a large project like Open Enterprise, an in-house Drupal Distribution, really exemplifies this. I'm not sure any one person has total knowledge of the entire thing. I've definitely coming to see the necessity of Git in an environment like this.

    Overall it has been an enjoyable and rewarding experience. I would recommend anyone wanting to get into this line of work to just dive head first. Especially if happen to have someone to guide you as Kyle has done for us. Even more so, if you can get them to pay you while doing so. Thank you LevelTen for showing me how you do what you do.

    Image Source: Designed by Freepik

    Jul 31 2017
    Jul 31

    When I first joined LevelTen, I had no prior experience with Drupal and I knew the internship was going to be a learning experience from the start. Now that I'm in the last week of the program, I didn't realize how much I would learn outside of Drupal. Like how to be a more efficient developer, how to develop proactively in a remote environment, learning the design process from start to finish of a website, and the business aspect of working in web development. Below I describe these learning experiences in a bit more detail.

    A more efficient web developer

    My skills as a programmer have definitely increased. Gaining a stronger proficiency in the following:

    • Advanced Drupal Development
    • Remote development tools like Git
    • Debugging and reverse engineering PHP code in an IDE
    • Testing code consistency with software like Coder
    • Front end development - CSS/Style Guides
    • Agile project development 
    Before joining LevelTen, I didn't utilize the tools available to developers in 2017. Now I'm using graphical interfaces like SequelPro for managing SQL databases, Tower for managing git repositories, and WebStorm as a professional IDE. These tools allow me to be a much more efficient programmer overall. I also had the opportunity to work with agile project tools like PivotalTracker and Trello, these tools will allow me to work more effectively with development teams in the future. 

    Web Design Process

    I realized how important it is to have a proper design process when developing any website. It is even more important when designing a Drupal site, since there are so many pieces involved. This process goes all the way up to the project leads, project managers, etc.

    These individuals work with the client to identify goals for the site and the overall scope. Passing that information down to a site designer, who creates a composition such as a sitemap or a wireframe, and a style guide with all the visual elements, patterns, etc. for the site. That information then gets passed down to the developers. Who then develop, test, and produce the site.
     

    The Business Aspect of Working in Web Development

    I used to wonder why companies aren't using the latest and greatest frameworks, environments, etc. Essentially, the cost has a lot to do with the flow of development, and the environment that is used. A good example of this I can give is with Drupal 8. It has been out for quite a while now, but many companies, including LevelTen are still using Drupal 7. What I learned is that it all boils down to time and cost. As well, as the return on investment when upgrading to a newer framework.

    Also noting that sometimes upgrading to newer frameworks/systems will diminish the amount of open source support provided. Drupal 7 to Drupal 8 is a perfect example. Even with trending frameworks like ReactJS, AngularJS, Bootstrap 3... I've noticed that companies will wait as long as possible because they simply don't have the time, labor, and funds to train/hire developers, and re-design their systems.
     

    A Big Thanks

    I would like to thank the LevelTen team, and especially Kyle Taylor the Senior Developer. I've asked a lot of "nooby" and silly questions over the 8 week program, and Kyle put up with all of it. He has really taught me a lot about the industry, and was like a mentor to me. I look forward to having the opportunity to work with him and the LevelTen team in the future.

    Jul 26 2017
    Jul 26

    Oftentimes, when we receive inbound leads from companies looking for a new website or new website redesign, we get a list of wants and needs and how fast and how much it will cost, but the potential client and we forget the people that will be using the platform the most.

    WHO REALLY  USES THE WEBSITE?

    It is no surprise that marketing teams own the site once it is completed. As I sit here and write this blog, I can assure you that I am the main user of the website. I write blogs and do a lot of the content changes that occur throughout the website. 

    Before CMS (Content Management Systems), most websites were static and never changing brochure sites that when a change was required, more than likely changes had to be made through the IT Department/Developer.

    In recent years, a website has become the storefront for most business, including ours, which serves as a guide to how we work, what services we provide, and educational material as in white papers or blog posts. Marketing and Sales teams now have more changes than ever in order to bring in potential customers, and that involves changing or adding to a once brochure website. 

    What to look for in Content Management Systems

    As mentioned before, websites used to always have to be updated, regarding content, by a developer. Today's popular CMS allow digital marketers take control of the website without having go through another person for changes, especially when some content is timely.

    In today's ever growing sales and marketing integration of teams, CMS and Marketing Automation services have had to learn to work together.

    Handle Content Easily

    If you have to still go through developers to get any kind of content change for your website, then the platform has got to go! Empowering marketing and sales team to do their own work on the site should be high in priority. Think of the workflows and time spent if they could do their work efficiently.

    Integrations for a Holistic Website

    Marketing Automation has grown exponentially in the last couple of years because of their ability to allow marketers know who their target audience is, retain them, and market exactly what they're searching for and eventually make them paying customers. Having a CMS that allows integration with marketing technology is where website builds are trending towards.

    Platforms like HubSpot, Marketo, and Pardot, to name a few, are known to integrate with Drupal CMS and WordPress CMS almost seamlessly. Now, not only will marketers have access to the CMS but also to the Marketing Automation software to build forms and landing pages without the help of developers. 

    Analytics Dashboards Built Right Into the CMS

    Marketers, digital marketers, to be specific, are very aware of analytic metrics that make or break the success of a website. Knowing the traffic to content and the RTC (rate-through-clicks) on CTAs (calls-to-actions) is necessary in order to know when it needs to be changed or left alone.

    It’s very convenient when a CMS has a plugin or module that integrates that allows for a quick and accessible with website metrics without ever having to leave the website because it is built in. One such integration is IntelligenceWP, the WordPress plugin allows for easy Google Analytics setup as well as a built-in dashboard to display you marketing metric success.    

    SEO Friendly

    Nothing is worse than having a website that is beautifully designed but has no traffic or optimized pages for it to rank in the search engines. Drupal and WordPress CMS are both terrific at search engine optimization. Either through modules or plugins, both CMS’s allow for marketers to customize individual pages for optimization based on the content of the page.

    When choosing a platform for your new website, it will benefit the content and digital marketers significantly if they can add meta descriptions, titles, keywords, and redirects by themselves without the help of someone in IT.

    Scalability

    As most websites these days serve as more than a brochure, most often than not, marketing teams have content calendars full of potential blog posts, additional pages, content changes, and adding landing pages. Why would you have a website designed without the ability to grow?

    Choosing a CMS platform should also address the ability that it will withstand 5+ years of content growth without running into problems. Avoid running into the issue of a few years down the road and having to choose a different platform because it was not able to handle the content growth.

    What now?

    Now, you have 5 key components to look for in a CMS when looking for a new platform to use when you decide to build a new website, redesign, or even migrate. Need some more details? We're good at Drupal . We have a blog post on Why You Should Be Using Drupal for Your Website, take a read and then give us a call when you're ready for a new site! 

    Jun 28 2017
    Jun 28

    Meet our last intern: Brandon Reid of our Web & Drupal Developer Internship program! One of his first projects as an intern was to research High Tech Website built on Drupal, so without further ado, here are his findings: 

    For those who aren't familiar with Drupal. Drupal is the #1 platform for web content management among global enterprises, governments, higher education institutions, and NGOs. Drupal is flexible and highly scalable, publishing a single website or shares content in multiple languages across many devices. Technology and business leaders transform content management into robust digital solutions with Drupal as it is backed by one of the world’s most innovative open source communities.

    Let's take a look at some high-tech companies that use Drupal, and go over why they find Drupal to be such a valuable asset for their needs. We will also explore common characteristics across these sites.

    LARGE HIGH-TECH SITES

    As mentioned above, Drupal is used by many global enterprises, governments, etc. Below is a list of five large high-tech fortune 500 companies that use Drupal.

    VALUE PROPOSITION

    Tesla Motors: Feature Management/Customization

    tesla motors

    Photo Source: Tesla Motors

    As you could imagine a site like Tesla's contains a lot of specifications and features for each vehicle, and this content needs to be readily available as content changes regularly. Drupal makes it easy for Tesla to allow their users to customize features and colors on vehicles with the use of certain modules/plugins, and this abundance of content can be managed easily with Drupal's logical backend.

     

    Qualcomm & NASA: "Headless" Drupal Approach/Multisite Integration

    NASA and Qualcomm

    Photo Source: NASA

    NASA and Qualcomm have a lot of reasons for using Drupal that could be discussed in an entire blog itself. These organizations have implemented a "Headless" Drupal approach which gives a multitude of benefits. Such as leveraging the strength and flexibility of Drupal’s back-end to easily architect content models and ingest content from other sources. This also gives the benefit of Optimizing the front-end by building with a client-side, front-end framework, as opposed to a theme.

    Additionally, NASA is using Drupal’s power to integrate with other content stores and applications (multisite implementation), successfully ingesting content from blogs.nasa.gov, svs.gsfc.nasa.gov, earthobservatory.nasa.gov, www.spc.noaa.gov, etc., and aggregating the sourced content for publication.

    SpaceX: Flexibility

    Space X

    Photo Source: Space X

    Similar to Tesla, SpaceX has an extremely large content base that consists of specifications for each rocket/ship project, blog updates of significant events, milestones, news feeds, articles, etc. You can imagine how much information is being pumped through this website. Drupal's logical backend gives SpaceX the flexibility to update and manage this information with ease.

    When comparing Tesla and SpaceX, you will notice since they are sister companies, which they are using the same base theme. It is common for companies to re-use their themes, and make slight modifications to different sites.

    CERN: Content Authoring

    CERN

    Photo Source: CERN

    Of the five sites, CERN's site is probably the most complex. Similar to SpaceX, and Tesla, CERN is managing highly dynamic content that is changing pretty consistently. CERN's content base is extremely large containing users, articles, scientists, projects, live data, publications, etc. Not only does Drupal provide tools and modules to make publications easy for CERN's users, but it also provides easy content authoring for Authors, publishers, etc.

    CERN's site contains a community area for users to communicate through forums and bulletins. Drupal's core allows the ability to create forums, and custom threads on the fly.  Digging deeper into CERNs use with Drupal, I found they also use Drupal for multisite implementation, which allows companies to have multiple sites operating under one code base.

    COMMON CHARACTERISTICS

    We can start to see a pattern with what these companies have in common, and why they choose Drupal. The most common characteristic we see, and why many people choose Drupal in the first place, is for dynamic and content rich websites. Each of these companies is continuously updating, managing, and deleting data from their websites. Drupal give these companies an powerful way to manage and manipulate their rich content structure.

    Another useful feature provided in Drupal is the use of Internationalization. Each of these organizations works on a global scale, and Drupal makes it easy for these companies to detect where their users are located, and translate data with-in the site appropriately.

    Now I have only touched on a few key reasons why these tech companies use Drupal, and you are welcome to explore them yourself. If you find any important features that I missed, or find any other tech companies using Drupal, please comment below and share your discovery!

    Jun 26 2017
    Jun 26

    This summer, LevelTen started the Web & Drupal Developer Internship program and we've brought on 3 up and coming developer interns! In today's post, we introduce you to Jerad Steward, and his experience and research with working in Higher Education Drupal websites:

    Recently I had the opportunity to be paid to look at a number of sites, even though I do that for free on my own time. I obviously jumped on that offer and read through some case studies on why Universities and other higher education seem to gravitate towards Drupal as a solution to their website needs.

    I looked to compare four schools that have case studies posted to drupal.org (d.o). I also have a bit of an inside scoop for UNT as I work there as a student doing Drupal development. That brings the list to 5, University of Minnesota (UMN), University of Oxford, Oklahoma State University (OSU), Stanford law, and of course University of North Texas (UNT).

    The first thing I noticed was that 4 out of the 5 had explicitly stated that open source was a reason for selecting Drupal. Some contributed it to being cheaper than a proprietary while others liked the freedom it gave. I know that UNT uses it because it allows them to keep everything in-house, which allows a combination of both reasons mentioned. By specifically picking or developing each theme and module in the Drupal distribution they can give each site maintainer a cohesive unit with a well-defined workflow. Since minor sites do not have a dedicated developer, keeping the differences between these sites makes working through issue queues much easier.

    Which brings us to the next point: it is easy to use a properly configured Drupal site. Once the school has found a configuration that works for them, they can develop guides one time and have it apply to each site they spin up. UMN, OSU, and UNT all wanted the content management side of things to be straightforward and hassle-free. I can't speak for the other 2, but UNT desires this because often the person who maintains the site has little experience with even using the web, let alone maintaining a website. The interface makes it more like using an office product and less like web development.

    The schools obviously still want it to look good though. Thankfully, it is pretty easy. Out of the box, there are a ton of themes that use responsive frameworks and look good. Since it is all open source, they can easily pick a theme and start building a subtheme on top of it. UMN and Stanford built their theme off of Zen. UNT uses both bootstrap and foundation, depending on the distribution.

    Towards the end, I found one more thing that was something I hadn't thought about before. That would be LDAP. LDAP allows Drupal to use the school's existing account management features without adding complexity. As long as the school maintains their LDAP groups externally, then Drupal will gladly accept those groups. This way the school can have some sort of username/password for each student that can be managed through a single central interface. Drupal will just run the user login information against that instead of a local storage. That is a cool way of making the students feel like they are on one large site instead of a group of identical looking sites.

    It's pretty easy to see why a Higher Ed tends to adopt Drupal eagerly: it's cheap, customizable, and can be easily integrated with other pre-existing services. All this with no real downside. The sites can look and feel as good as the developer makes the site. It is as easy to use as the school has it configured to be.

    Jun 22 2017
    Jun 22

    This summer, LevelTen brought back the Web & Drupal Developer Internship program and we've brought on 3 up and coming developer interns! In today's post, Anima Bajracharya, and her research assignment with of Drupal Travel websites:

    After researching some of the case studies of Travel sites created in Drupal, I found out that Drupal can help businesses across any industry to create rich digital experiences. It is no surprise that more than one million sites trust Drupal today. With benefits such as scalability, free modules, responsive design, flexible APIs and one of the largest open source communities; it has become one of the popular Content Management System (CMS).

    If you are already using Drupal or planning to use Drupal as CMS for your Travel sites, here are two examples of why travel businesses are using it or maybe you can plan another vacation trip.

    1.Let’s go to Fiji!!! ----Fiji.travel

    http://www.fiji.travel/

    The site had to move to Drupal because of the outdated and poorly coordinated collection in the tourism industry. So, the new site created in Drupal helps the users (old/new) with the treasure of information and planning tool that makes the vacation to Fiji a dream come true. In short, the site is user-friendly, responsive, interactive, and multilingual.

    Users can view their itinerary on a map which is great to discover other places nearby. Similarly, the map shows the destination, what makes you happy, and the types of activity available which are perfect for making a variety of plans while in Fiji.

    The key benefit for the industry like tourism is that a set of dashboard pages are created that allow site administrators to check live results on site activity and filter any dates historically. This helps the tourism businesses to track how many new users are coming into the site, how people are saving on their trips and how their trips are being created which is running and growing every year.

    2. Cruise?-----princess.com

    http://www.princess.com/ships-and-experience/onboard-experience/activities/princess-at-sea/

    I found this site very interesting because the website (princess.com) is not created in Drupal, but the entire Princess cruise app ([email protected]) used in the ship is built on Drupal. [email protected] is the industry’s first passenger facing digital experience platform for Princess Cruise and it lets the passengers access information onboard in the ships. It serves to the passengers via wifi which let them access the ships’ schedule of events, stateroom account, itinerary, instant messaging, and personalized cruise planner. It is one of the most interesting and popular hub to the passengers. It makes passengers’ life easier and convenient.

    Hopefully, this will give you some fresh ideas of how Drupal can change your business and how it can save your time, money and customers.

    May 26 2017
    May 26

    The time has come for the LevelTen Team to trek it down to Austin for this year's Texas Camp. Our intention for when we decided to organize the state-wide Drupal Camp last year was for it to move around the state, which is why it is in Austin. We are proud to be Silver Sponsors for the camp and helping co-sponsor the Saturday Night Party!

    There is still time to sign up to attend the camp! Tickets are $50 for Saturday and Sunday sessions. Each attendee will also get drink tickets in their badges for the Saturday Night Party, but don't fret; there will be drink tickets at the bar, you'll just have flag us down by our table to get your free drinks. 

    You can purchase you Texas Camp tickets here: http://bit.ly/texascamp2017

    Once you get through your first day of sessions, the fun isn't over! We'll be hosting along with the Achieve Internet team, the official afterparty for this year's camp! 

    Details of the party:

    When: Saturday, June 3, 2017

    Time: 8 PM - 10 PM

    Where: Clive Bar, 609 Davis St, Austin, TX 78701

    There will be plenty of food trucks on hand for anyone looking to grab something to eat. We can't wait to see everyone there and hang out with the Drupal Community. Check out the Texas Camp Facebook for the latest information: https://www.facebook.com/DrupalCampTexas/

    See you all next Saturday! 

    Jan 25 2017
    Jan 25

    As the first month of the new year comes to an end, the Drupal Community is ramping up for the many DrupalCamps and annual DrupalCon that are sure to happen. As part of our Web Dev Wednesday, we compiled a list of DrupalCamps in the United States everyone should attend. 

    We'll keep this blog post as updated as we can as new camps start updating their websites for this year. 

    We hope to see everyone at TexasCamp, we're a little partial to this particular camp, because we started the tradition last year and our friends from Amazee Labs in Austin are taking over this year to host it in their city! 

    Sep 23 2016
    Sep 23

    If you're using Drupal's Google Analytics module to track visitors to your website, you might assume that the built-in Track downloads option works without a hitch. 

    drupal google analytics track downloads

    However, you are out of luck if you are using the File Entity module (which is a requirement for the Media module). A quick search of the File Entity module issue queue and you'll find a bunch of posts about why this module seems to be incompatible with Google Analytics download click events. 

    Luckily there is a pretty easy workaround. In this post, I'll show you how to add download tracking to files, and how to set up your analytics to track these events. 

    This assumes the following:

    1. You've downloaded, enabled, and configured the Google Analytics module to track your website
    2. You're using the File Entity module for fieldable files
    3. You have a custom theme set up with template.php file so we can modify file download links.

    Identify the Appropriate Google Analytics Tracking Code

    Champion Googler Kyle found this gem online - a gist for tracking downloads:

    <a onclick="ga('send', 'event', 'Downloads', 'Click', 'E-book downloaded', '0');" href="http://mysamplesite.com/wp-content/uploads/2015/12/my-free-lead-magnet.pdf">Download Our Guide to Speeding up Your Site</a>

    But what does this mean? Looking at the Google Analytics Tracking analytics.js documentation we can start to tease this gist apart. From Google's docs:

    Invoking the ga() command queue function with the following function signature will push commands onto the queue to be scheduled for execution once the library is loaded.
    Usage: ga(command, [...fields], [fieldsObject])

    We want to send a hit to Google Analytics every time a user clicks on a link that is a downloadable file. We can see the 'send' command does just this. The usage for this send command is as follows:

    ga('[trackerName.]send', [hitType], [...fields], [fieldsObject]);


    The fields that can be specified by the ...fields parameters vary depending on the hit type. For the Hit type 'event' the ...fields are eventCategoryeventActioneventLabeleventValue

    So now the gist becomes clear. For the send command and a hit type event, the following fields will be sent to Google Analytics:

    eventCategory: Downloads
    eventAction: Click
    eventLabel: E-book downloaded
    eventValue: 0

    This is what the links to download a file look like when using the File Entity and File field:

    <a type="application/pdf; length=32521" href="/file/37/download?token=VY8shESE">Download</a>

    So, we'll need to modify our links to add the ga send command for an event Hit type with the following fields:

    <a onclick="ga('send', 'event', 'Downloads', 'Click', 'PDF downloaded', '0');" type="application/pdf; length=32521" href="/file/37/download?token=VY8shESE">Download</a>

    Modify template.php to add tracking code

    Open up your template.php file in your current active theme. Here we will override the File Entity module's function
    file_entity_download_link(), which itself is overriding Drupal's core theme_file_link() function. Search the File Entity module files for theme_file_entity_download_link, and copy and paste that function into your template.php.

    function theme_file_entity_download_link($variables) {
      $file = $variables['file'];
      $icon_directory = $variables['icon_directory'];
    
      $uri = file_entity_download_uri($file);
      $icon = theme('file_icon', array('file' => $file, 'icon_directory' => $icon_directory));
    
      // Set options as per anchor format described at
      // http://microformats.org/wiki/file-format-examples
      $uri['options']['attributes']['type'] = $file->filemime . '; length=' . $file->filesize;
    
      // Provide the default link text.
      if (!isset($variables['text'])) {
        $variables['text'] = t('Download [file:name]');
      }
    
      // Perform unsanitized token replacement if $uri['options']['html'] is empty
      // since then l() will escape the link text.
      $variables['text'] = token_replace($variables['text'], array('file' => $file), array('clear' => TRUE, 'sanitize' => !empty($uri['options']['html'])));
    
      $output = '<span class="file">' . $icon . ' ' . l($variables['text'], $uri['path'], $uri['options']);
      $output .= ' ' . '<span class="file-size">(' . format_size($file->filesize) . ')</span>';
      $output .= '</span>';
    
      return $output;
    }

    I've also included it above. Replace the theme in the function name with your theme's name (ie the function should now be named MYTHEME_file_entity_download_link). Then we add the tracking code per Google Analytics analytics.js recommendations. We can do that by adding the code to the $uri['options']['attributes'] array:

    /**
     * Overrides theme_file_entity_download_load().
     *
     * This is defined in the file entity module, and itself is overriding the
     * core theme_file_link() function.
     *
     * Override it here so we can add Google Analytics tracking to PDFs.
     */
    function MYTHEME_file_entity_download_link($variables) {
      $file = $variables['file'];
      $icon_directory = $variables['icon_directory'];
    
      $uri = file_entity_download_uri($file);
      $icon = theme('file_icon', array('file' => $file, 'icon_directory' => $icon_directory));
    
      // Set options as per anchor format described at
      // http://microformats.org/wiki/file-format-examples
      $uri['options']['attributes']['type'] = $file->filemime . '; length=' . $file->filesize;
    
      // Add GA tracking for downloads.
      $uri['options']['attributes']['onclick'] = "ga('send', 'event', 'Downloads', 'Click', 'PDF downloaded', '0');";
    
      // Provide the default link text.
      if (!isset($variables['text'])) {
        $variables['text'] = t('Download [file:name]');
      }
    
      // Perform unsanitized token replacement if $uri['options']['html'] is empty
      // since then l() will escape the link text.
      $variables['text'] = token_replace($variables['text'], array('file' => $file), array('clear' => TRUE, 'sanitize' => !empty($uri['options']['html'])));
    
      $output = '<span class="file">' . $icon . ' ' . l($variables['text'], $uri['path'], $uri['options']);
      $output .= ' ' . '<span class="file-size">(' . format_size($file->filesize) . ')</span>';
      $output .= '</span>';
    
      return $output;
    }
    

    Now clear cache and refresh your page - you'll see that all files now have the tracking code for downloads.

    Set up Google Analytics to Report on Downloads

    Lastly we have to navigate the maze that is Google Analytics administration. There are probably lots of ways to skin this cat, but here is a quick way to track downloads using your custom send event. Log in to your Google Analytics account and head over to the Customizations tab:

    Google Analytics dashboard customizations

    Under Custom reports, click the New Custom Report button:

    Google Analytics create new custom report

    Give your custom report a descriptive title, and select Type: Flat Table. Add the necessary dimensions (Page, Event Label, Page Title, Event Action, Event Category) and metrics (Users, Total Events) to your Report Tab as well per the screenshot below:

    Google Analytics PDF Download custom report configuration

    Save your custom report, and then click/download the crap out of your website once the code is updated with the tracking code. In 24 hours, come back to your Google Analytics account, check out your custom report, and you should see all of your clicks and downloads tracked.

    events tracked

    You can see that both clicks of Outbound links as well as Downloads are being tracked. If you only want to see Downloads in this custom report, edit your report and add a custom filter to only track events labeled with PDF downloaded. 

    add filter to only track downloads

    Save and then view your report again. Only the PDF downloads will now be reported. 

    Sep 21 2016
    Sep 21

    For a recent website I worked on, the client wanted search results to be grouped by content type, and also wanted to control which content type results were displayed first, second, and third. While you can get most of the way there in terms of sorting search results using Views, if the desired order of the content types doesn't luckily correspond to some kind of alphabetical sorting of the content type's names, you'll need to do a little configuration and custom module work to make this happen. 

    I will walk you through how to do this using a vanilla Drupal 7 site. (I used Devel to generate dummy content). I also created two additional content types called Checklists and Toolkits, so we'd have more than just the default Basic Page and Article content types that come out of the box with Drupal.  You'll also want to download and enable the Views and Views UI modules. 

    To accomplish this, we will do the following:

    1. Create a new view for better control of how the search results are displayed
    2. Create an exposed filter for our view to use for the actual search
    3. Display our custom search form in a block
    4. Hook into the view's display to re-order the search results per ranked content type

    Part 1: Setting up our View

    Create a new View - I've named mine Search Results. We'll want to show Content of type All, and create a Page. 

    create drupal view

    Click Continue and Edit to complete the View setup. This View will be the page that site visitors land on when they enter search terms into the new search bar we are going to create shortly. You can chose to display whatever fields you'd like here, but for this simple case we'll just show the Content: Title, Content: Body, and Content: Type. You can hide the Content: Type later but it's useful to show it now while we're working so we'll know that future work will be sorting the results as desired. Also remove any Sort Criteria that were created automatically by Views.

    remove sort criteria

    I've linked the title to the original content and trimmed the body field so it's not too long, as well as added an ellipsis and read more link.

    configure body field in view

    Once you've got your fields set up the way you'd like, you should see something like this - right now it's just displaying all content on the site, without any sorting. 

    display all search results

    2. Create exposed filter for Search

    Next we'll create an exposed filter and place it in a block. We'll replace the default Drupal Search block with our custom exposed filter after we've done this. 

    Under Filter Criteria, click the Add button and then select Search: Search Terms.

    exposed filter search terms

    Exposed this filter to users, and click the box next to 'remove search score'. Save.

    configure exposed filter

    Rather than including this exposed filter on this search page only, we want this exposed filter to be available in a block, so we can use it as our default search. Under Advanced, click Exposed Filter in block: No

    exposed filter in block

    Select Yes, and then save. At this point your exposed filter will disappear from the Views preview below, as it is no longer part of the page, but is in a separate block. Save your view and then head over the the Block configuration. 

    3. Replace Drupal's default search block with our new exposed filter

    Under Structure > Blocks, set the Search form block to -None-, and set your new exposed filter block to display in whichever region you'd like. In this case I'll just put it in the Sidebar first.

    disable default search

    display exposed filter for custom search

    If you visit your home page, you should see your new search form. Test it out and make sure if you enter a term you get sent to the custom search results page we just built with views. 

    check search results page

    You'll see it's returning results fairly randomly, with the different content types all mixed in with each other. If you don't care what order the content types are ordered by, you could use the built in Views Sort Criteria to sort by content type. But that's kind of limiting - it only lets you chose ascending or descending. So your choices right now are either Ascending:

    Article
    Basic Page
    Checklist
    Toolkit 

    or Descending:

    Toolkit
    Checklist
    Basic Page
    Article

    Let's say we needed to return our search results in the following order:

    Checklist
    Toolkit
    Article
    Basic Page

    We'll need a custom module for that.

    4. Hook into the view's display to re-order the search results per content type

    We'll use hook_views_pre_render() to accomplish this. First, let's take a look at what's going on under the hood for this hook. So, create yourself a custom module - I've called mine search_customization, and create the necessary .info and .module files. Enable your module, and then we'll add our first statement to the .module file. I'm using the Devel module to dpm() out variables for display on the screen. 

    /**
     * Implements hook_views_pre_render().
     *
     * Using a view to display search results, group search results by content type
     * and also order results per content type ranking.
     */
    function search_customization_views_pre_render(&$view) {
      dpm($view, 'view');
    }

    Head back to your website, clear cache and refresh the page to see the view object. First, we'll only want to modify our search View, so let's get the View's name.

    get views name

    Modify the code so it will only be run when this specific view is loaded on the page

    function search_customization_views_pre_render(&$view) {
      if ($view->name == 'search_results') {
        dpm($view, 'view');
      }
    }

    Here's the rough outline of what we're going to do next:

    1. Get the result of the view
    2. Set up some kind of ranking for the content types
    3. Group the results per content type
    4. Sort the grouped results per our ranked content types
    5. Set the views results reordered per our ranked results

    Go back to the website and look for the view->result in your dpm() statement. It will list all of the results that found.

    results array

    In our custom module we'll get the results array and initialize an empty array.  We'll use this empty $grouped_results array later to save our results grouped by content type.

    function search_customization_views_pre_render(&$view) {
      if ($view->name == 'search_results') {
    
        // Get array of results from view object.
        $results = $view->result;
    
        // Initialize empty array that we will use to save results
        // grouped by content type.
        $grouped_results = array();
        
        dpm($view, 'view');
      }
    }

    If you inspect any of the individual results in view->result, you'll see they're each objects that have all of the information we included in our custom view - the title, content type, and body. 

    views result object

    Now we'll loop through the $results array using a foreach, and each time an individual result object in our $results arrays is encountered, we will get the content type of that result. We'll place that result in our $grouped_results array, which groups results per the ranking of the content type. A little confusing to explain, so here's the code:

    function search_customization_views_pre_render(&$view) {
      if ($view->name == 'search_results') {
    
        // Get array of results from view object.
        $results = $view->result;
    
        // Initialize empty array that we will use to save results
        // grouped by content type.
        $grouped_results = array();
    
        // Each $result is an object within the $results array.
        foreach ($results as $result) {
          $content_type = $result->node_type;
    
          // Rank content types in order to be sorted.
          // Ranking closest to 1 will be listed first.
          // Ranking with highest number will be listed last.
          switch ($content_type) {
            case 'checklist':
              $ranking = 1;
              break;
            case 'toolkit':
              $ranking = 10;
              break;
            case 'article':
              $ranking = 20;
              break;
            case 'page':
              $ranking = 30;
              break;
            default:
              $ranking = 200;
          }
    
          // Add result to new array where results are grouped by ranking.
          $grouped_results[$ranking][] = $result;
        }
    
        dpm($view, 'view');
      }
    }

    If we print out our $grouped_results array, hopefully this will be more clear - I did this via dpm($grouped_results). You'll see that this array now has 4 rows, one for each of the rankings we assigned to the 4 different content types. And that each of these rows is actually an array of results objects. 

    ranked results

    However, the rankings aren't ordered per ranking number. We'll do that next - reorder the $ranked_results array per our ranking with a simple ksort

    function search_customization_views_pre_render(&$view) {
      if ($view->name == 'search_results') {
    
        // Get array of results from view object.
        $results = $view->result;
    
        // Initialize empty array that we will use to save results
        // grouped by content type.
        $grouped_results = array();
    
        // Each $result is an object within the $results array.
        foreach ($results as $result) {
          $content_type = $result->node_type;
    
          // Rank content types in order to be sorted.
          // Ranking closest to 1 will be listed first.
          // Ranking with highest number will be listed last.
          switch ($content_type) {
            case 'checklist':
              $ranking = 1;
              break;
            case 'toolkit':
              $ranking = 10;
              break;
            case 'article':
              $ranking = 20;
              break;
            case 'page':
              $ranking = 30;
              break;
            default:
              $ranking = 200;
          }
    
          // Add result to new array where results are grouped by ranking.
          $grouped_results[$ranking][] = $result;
        }
    
        // Sort results by ranking.
        ksort($grouped_results);
        
        dpm($view, 'view');
        dpm($grouped_results, 'grouped_results');
      }
    }

    Now if we inspect the $grouped_results array the results are ordered per ranking. 

    order results per ranking

    Now that our results are grouped and ranked by result, we'll want to pull those results objects out of their groupings and save them as an un-grouped array (still ordered by ranking) that we will use to override the default views results. We'll make a new empty $ranked_results array to save our ranked results. We'll then use a foreach loop to go through each of the ranking arrays in our $grouped_results. Within our ranking arrays, we'll use a second foreach loop to save the results object into our new $ranked_results array. Again, super confusing to explain, so here's the code and we'll dpm() out some stuff to make this more clear.

    function search_customization_views_pre_render(&$view) {
      if ($view->name == 'search_results') {
    
        // Get array of results from view object.
        $results = $view->result;
    
        // Initialize empty array that we will use to save results
        // grouped by content type.
        $grouped_results = array();
    
        // Each $result is an object within the $results array.
        foreach ($results as $result) {
          $content_type = $result->node_type;
    
          // Rank content types in order to be sorted.
          // Ranking closest to 1 will be listed first.
          // Ranking with highest number will be listed last.
          switch ($content_type) {
            case 'checklist':
              $ranking = 1;
              break;
            case 'toolkit':
              $ranking = 10;
              break;
            case 'article':
              $ranking = 20;
              break;
            case 'page':
              $ranking = 30;
              break;
            default:
              $ranking = 200;
          }
    
          // Add result to new array where results are grouped by ranking.
          $grouped_results[$ranking][] = $result;
        }
        
        // Sort results by ranking.
        ksort($grouped_results);
        dpm($grouped_results, 'grouped_results');
    
        // Now initialize new array that will save search results in order per ranking
        // but without results being grouped by ranking.
        $ranked_results = array();
    
        // Reorganize $grouped_results so $results are no longer grouped
        // just listed in order of ranking.
        foreach ($grouped_results as $ranking) {
    
          dpm($ranking, 'ranking');
    
          foreach ($ranking as $result) {
            $ranked_results[] = $result;
          }
        }
        dpm($ranked_results, 'ranked_results');
        dpm($view, 'view');
      }
    }

    Refresh the page and let's take a look at the arrays that we're dealing with now. You'll see in addition to our $grouped_results array, we now have 4 $ranking arrays. This comes from the first foreach loop, where we went through our $grouped_result array, that has 4 arrays, each array being results objects grouped by ranking per the content type. 

    ranking arrays

    In our next foreach loop we are taking each of the results objects from our ranking array and placing them into a new $ranked_results array. This simply serves to take the results out of 4 different arrays, each array containing results of a different content type, and puts them into a new array where results aren't grouped by content type ranking, but are now ordered per the ranking. You can see this in the $ranked_results array - this is now a simple array of results, ordered per content type ranking. This is instead of the $grouped_results array, which was an array of arrays. 

    new ranked results array

    Now we just have one last thing to do. Our $view->results array has the results not ordered per content type ranking. We will set the $view->results array to our new $ranked_results array and we'll be done! Here is the final code (of course you will want to remove the dpm() statements for your real module).

    function search_customization_views_pre_render(&$view) {
      if ($view->name == 'search_results') {
    
        // Get array of results from view object.
        $results = $view->result;
    
        // Initialize empty array that we will use to save results
        // grouped by content type.
        $grouped_results = array();
    
        // Each $result is an object within the $results array.
        foreach ($results as $result) {
          $content_type = $result->node_type;
    
          // Rank content types in order to be sorted.
          // Ranking closest to 1 will be listed first.
          // Ranking with highest number will be listed last.
          switch ($content_type) {
            case 'checklist':
              $ranking = 1;
              break;
            case 'toolkit':
              $ranking = 10;
              break;
            case 'article':
              $ranking = 20;
              break;
            case 'page':
              $ranking = 30;
              break;
            default:
              $ranking = 200;
          }
    
          // Add result to new array where results are grouped by ranking.
          $grouped_results[$ranking][] = $result;
        }
    
        // Sort results by ranking.
        ksort($grouped_results);
        dpm($grouped_results, 'grouped_results');
    
        // Now initialize new array that will save search results in order per ranking
        // but without results being grouped by ranking.
        $ranked_results = array();
    
        // Reorganize $grouped_results so $results are no longer grouped
        // just listed in order of ranking.
        foreach ($grouped_results as $ranking) {
    
          dpm($ranking, 'ranking');
    
          foreach ($ranking as $result) {
            $ranked_results[] = $result;
          }
        }
    
        dpm($ranked_results, 'ranked_results');
    
        // Set views results array to new ranked results array.
        $view->result = $ranked_results;
        dpm($view, 'view');
      }
    }

    Refresh the page and you can see the results are now ordered per our ranking: checklists, then toolkits, then articles, then basic pages.

    final results

    Sep 06 2016
    Sep 06

    It seems as if Pokémon GO has totally engrossed our lives in one way or another. As the first augmented reality game with mass appeal across the globe, it swiftly became the most popular game in history in less than week. This explains why it's hard to go down any street without seeing someone furiously swiping at their screen, throwing Pokéballs. Here at LevelTen, we hardly go a day without talking about our most impressive Pokemon, the most effective XP strategies, and the best areas for Pokéstops.

    Culturally, the game has reignited the nostalgic passions of young adults everywhere. It's forced people to get out of their homes, see their local attractions, and get some exercise in the process. Pokémon GO has brought people together in a new way and has even gained the attention of individuals outside of the first-generation Pokémon age-group. Naturally, it didn't take long before businesses began capitalizing on all of the buzz. Here is a list of some of our favorite ways businesses have embraced the Pokémon craze.

    LOCATION, LOCATION, LOCATION

    Small restaurants and businesses with the privilege of being in prime hunting grounds are jumping on the Pokémon bandwagon by promoting their locations as local Pokéstops or battling gyms. There is even an instagram page @pokemongo_marketing, which showcases these clever marketing schemes.

    starbucks pokemon

    For businesses fortunate enough to be near a Pokéstop, they can anchor their promotions by encouraging their employees to set Lure Modules, to lure Pokémon and customers. According to the New York Post, L'Inizio Pizza Restaurant saw a 75% increase in business when the manager invested just $10 on a Lure Module.

    NICHE START-UPS

    Entrepreneurs have gone so far as to even start businesses in the name of all that is Pokémon Go. Our very own Senior Developer, Kyle Taylor, figured out how to turn a profit with Pokémon by using his DrawAttention technology to produce high-quality team mascot laptop stickers. Basically, Kyle took the unity that people feel within their Pokémon Go teams (#teamvalor) and monetized it in a fun and different way.

    team mystic

    Team Mystic

    team valor

    Team Valor

    Another great example is Pokémon Go City Tours in Austin, TX. The name speaks for itself. This successful start-up is providing 3-hour guided tours through 5 of Austin's hottest Pokémon hunting grounds. It helps Pokémon Go players and travelers alike blend their passions into one awesome adventure, and frankly, I wish we were in Austin so our team could sign up.

    DIGITAL PROMOTIONS

    Honestly, with social media, the promotional opportunities are endless. At this point, who hasn't seen someone post a screenshot of a Pokémon sitting on top of someone's desk?

    Pokémon has provided businesses with such an easy way to instantly connect with their audience. LevelTen decided to join the epidemic by creating two Pokémon themed animations for our #webdevwednesday segments that were pretty decent hits in the Drupal community and helped catapult our social following. For each animation, we took Druplicon and turned it into a Pokémon.

    The first Pokémon animation was a spin-off of the original Pokémon’s cartoon segment called “Who’s that Pokémon,” unveiling Druplicon as the mystery Pokémon. It served primarily as a way to add something fun and creative to the social pages. It swiftly became popular with thirteen retweets and one-hundred and five likes on Instagram, which had been our highest engagement between both social outlets at that point.

    [embedded content]

    Our second Pokémon animation featured a Pokémon battle between a junior developer and Druplicon. Since Drupal is renowned for being an extremely advanced and complicated platform, Druplicon wins the fight after just one hit. It was also a little more purposeful as it links to a blog written by our Junior Developer. This one even got a retweet from the founder of Drupal himself, Dries Buytaert, which definitely made us a group of proud Pokémon hunting nerds.

    [embedded content]

    So, there you have it. Thanks to Pokémon Go, you can have fun combining your gaming and work passions, while strengthening your brand's equity and personality. I know I'm personally excited to see what else businesses are going to come up with by joining in on all of the Pokémon fun.

    Sep 02 2016
    Sep 02

    If you guys didn't already know, we're in the middle of the Results Oriented Web Roadshow! You can take a closer look at Tom's adventure across the country here. Our next stop is this upcoming Tuesday, September 6 in Chicago at Timothy O'Toole's Pub!

    What you can expect:

    Learning:

    We will be giving a short presentation that focuses on the essential techniques to improve your web efforts. The tips will range from the strategic to tactical, everyone should leave with actionable new ideas for making their website more impactful.

    Networking:

    You will get to hang out with like-minded people from both the Drupal and Marketing world of Chicago. Share insights, techniques, and just about everything else in between with a drink in hand and food to sample.

    Don't let your Labor Day weekend end early! Extend it to Tuesday after work!

    Did I forget to mention that this event is free? Well, it is! You can register below:

    See you guys there!

    Aug 30 2016
    Aug 30

    Are you looking for a job in the tech world? Have you ever worked at a company that practiced Agile Methodology? Then this is the job for you! 

    Who We Are:

    We’re a small web development and marketing agency near Southern Methodist University in Dallas, Texas. We like the occasional ice cream socials and NERF gun battles, but most of all, we enjoy making Drupal websites and helping client's businesses grow. 

    The Position:

    PT Technical Production Coordinator

    THE BASIC JOB ENTAILS:

    • Turning client requests into stories / tasks for estimations
    • Performing QA and verifying tasks
    • Tracking progress of client projects
    • Reporting to account managers the status of projects and hours billed.

    IDEAL CANDIDATE QUALITIES:

    • Proactive. We’re a small agency that moves fast, so you need to be on your toes!
    • Responsive. Communication is crucial for our team to work effectively, so keeping up with statuses and conversations is important.
    • Organized. We’re always bringing in new clients, and these clients may have one or multiple projects with us, so organization is key to maintaining productivity.
    • Technical (or want to be technical). This quality really helps to translate client stories into actionable tasks for the production team and helps you when running QA, so you know what you’re looking for.
    • Fun! We’re definitely a light-hearted group who is (hopefully) fun to be around, but we need some organization help.

    We use a few different tools internally, so it would be great to have experience with these tools, or similar, but not necessary:

    • Scrum / Agile project management (This is a big one!)
    • Pivotal Tracker
    • Basecamp
    • Harvest
    • Bitbucket / Atlassian tools
    • Drupal (or Wordpress)
    • Basic HTML/CSS knowledge

    If you think this is something you are up for, then what are you waiting for?

    Apply Now!

    Please include a resume & any relevant technical experience with any submissions. If interested, we'll contact you for a phone interview. Thanks!

    Aug 15 2016
    Aug 15

    You might have read a blog a couple of weeks ago that announced we were going on the road on The Results Oriented Web Roadshow. Well, guess what? It finally happened! Tom McCracken hopped on an RV to travel around the country to talk Drupal and Content Marketing. Don't believe us? Watch this clip:

    [embedded content]

    Want further evidence about this ROW Roadshow traveling? Check out these shots from the road:

    RV_livinBreck_MTBTrail

    CadillacRanch2016

    Have you ever wanted to learn more about Drupal? Or how your website is the cornerstone to bringing in more business?  Then, come to one our events for FREE just by using the code MARKETING (all caps) for any city listed below. Pass the information with friends, colleagues, and company. We look forward to seeing you guys!

    Don't forget to submit those websites! Why? Well, during the ROW Roadshow, we're offering the opportunity to have your website evaluated by leading experts in web design and digital marketing. Our end goal is to make you successful! 

    See you on the road!
     

    Aug 10 2016
    Aug 10

    On Sunday, I trucked out of Dallas in a 38’ RV with a mess of AV equipment, a Jeep named Daisy and a pair of mountain bikes in tow. So without further ado, I'm excited to announce that LevelTen has officially kicked off its four thousand mile journey through twenty-plus cities across the United States. I know what you're thinking: What would possess me to leave my home and business for three months?

    The Reason for R.O.W. Season 

    I believe we are at a pivotal time for the Web. We are witnessing a fundamental change in the way people are approaching websites and digital marketing. For the past two decades, web experts have emphasized the importance of getting a website. By now, we all know this isn't exactly revolutionary knowledge. So, I've hit the road to spread a new message. I'm coming to a city near you to show you how to get what you are really looking for: ROI. Or to put it more simply, results.

    Organizations of all types are waking up to the fact that most traditional websites produce a surprisingly paltry amount of real, measurable results. Let's face it, the majority of today's websites are just not going to make the cut anymore. The precious few visitors that found your URL on a business card or an advertisement are not going to be thrilled to see an online brochure, providing nothing but an endless sea of sales pitches.

    Out with the old, in with the new

    What businesses need is a different kind of online presence. Over the past year, we have done an extensive amount of market research and found that an increasing number of organizations are trying to transform their online efforts to drive better results. 

    Increasingly, management teams are judging websites not by if they look pretty and provide good information, but by how much they produce in tangible ROI. At the same time, web and marketing teams are scrambling to evolve their thinking to integrate novel strategies, methodologies and tools to do just that. 

    There always seems to be a small handful of online leaders in every niche that have done a remarkable job at bringing it all together, capturing a dominant online market share in the process. Now, there are a lot more organizations asking how they can be like those leaders – how can they get real returns from the digital world.

    Fortunately, LevelTen has set out on a mission to provide the nation with the ultimate guide to building websites that actually attract visitors, generate contacts, and proceed to nurture them to increase sales and other vital key performance indicators. Essentially, the realm of digital marketing is in the process of transitioning, and I am travelling in order to offer business owners, marketers, and web developers advice on how to excel through it.

    Staying Ahead of the game

    Over the next few years, I believe we will see this trend cross the chasm from a few progressive visionaries to all enlighted stakeholders. No longer will people say "you need just a website." You need a different kind of website, with a different approach.

    I believe we are seeing the end of the traditional website and the emergence of the something new: The Results Oriented Website. As the spokesman for the R.O.W. Roadshow, I'll be taking over 17 years of web experience on the road to enable others to take hold of the future and I'd love to meet you along the way! 

    If you’d like to learn more about the ROW Roadshow, please check out the website and our Sponsorship Kit.

    If you’d like to help by becoming a sponsor, please let us know!

    Aug 08 2016
    Aug 08

    When developing custom modules, it is often helpful to the end-user to print out various messages to alert them to errors or explain what has just been done. Drupal does this all the time - for example, after saving a new node, a green notice is printed to the page letting the author know the article has been saved:

    If it's been a while since I've had to do this, I always have to quickly check the Drupal docs explaining the drupal_set_message() function for how exactly to format the message, and how to use variables and links. Well, summarized here is a handy cheat sheet that covers most of the scenarios I typically encounter.

    Printing out a simple message

    For a message like the 'new article' has been created, we just need a simple message, no variables, no links.

    Right:

    // Message without any links.
    drupal_set_message(t('Here is our translated string without any links.'), 'status');

    Note we are running this through the t() function. This means that the string will be available for translation if needed at a future date.

    Wrong:

    // Message without any links.
    drupal_set_message('Here is our translated string without any links.', 'status');

    If we had just done this, the string wouldn't be available for translation.

    Printing a message with links

    If we want a link in our message, for internal paths we can use the relative URL, but external paths use absolute URLs.

    // Message with external link.
    drupal_set_message(t('Here is an external link to <a href="http://google.com">Google.</a>'), 'status');

    Make sure to use the double quotes in the anchor, rather than single quotes. If you use single quotes it will interpret that as the end of the string to be translated. 

    Printing a message that contains variables

    Now we're getting to the fun part. Often for custom messages we will want part of the message to change depending on what happened. That's where we can use variables. In this example, we'll print the current month.

    We're using the '@' notation to let the t() function know we are passing it a variable.

    // Get the month using the PHP date() function.
    $month = date('F');
    // Message with variable.
    drupal_set_message(t('Message with a variable: The current month is @month.', array('@month' => $month)), 'status');

    Why use '@'? Because Drupal makes sure nothing harmful can be put into that variable by passing it through the check_plain() function. More on this next. 

    What's the deal with '@', '%', and '!'

    The Drupal docs concerning the format_string() function cover this in more detail, but here are the basics.

    The '@' is what you typically default to if you don't need any special formatting or HTML, because the '@' will pretty much completely sanitize your variable. This is for the first example above where we want a linked variable. ( I know in these cases we don't need to use variables, since we are just using simple strings. But just imagine a simple extension of this example where the @link-text variable may change depending on what has just happened.) 

    // Example using '@'.
    drupal_set_message(t('Message with a linked variable: Check out this Tumblr <a href="http://foodonmydog.tumblr.com">@link_text</a>.',
        array(
          '@link_text' => 'Food on my dog',
        )
      ), 'status');

    If you want to get fancy and have some of your text italicized, you use the '%' notation. In this example 'Cat Cosplay' will be italicized. 

    Right:

    // Example using '%'.
    drupal_set_message(t('Message with a linked italicized variable: Check out this Tumblr <a href="http://cat-cosplay.tumblr.com">%link_text</a>.',
      array(
        '%link_text' => 'Cat Cosplay',
      )
    ), 'status');

    Wrong:

    drupal_set_message(t('Message with a linked italicized variable: Check out this Tumblr <a href="http://cat-cosplay.tumblr.com">@link_text</a>.',
      array(
        '@link_text' => '<em>Cat Cosplay</em>',
      )
    ), 'status');

    If we tried the wrong example above, this is how it compares to the right way to do it. If we stick with the '@', the HTML is just printed as plain text. The '%' notation formats the text as italics for us using the drupal_placeholder() function. 

    Lastly, if we need to use other HTML markup in our message we can use the '!' notation. Use this with caution! As the Drupal docs note, this text will be

    'Inserted as is, with no sanitization or formatting. Only use this for text that has already been prepared for HTML display (for example, user-supplied text that has already been run through check_plain() previously, or is expected to contain some limited HTML tags and has already been run through filter_xss() previously).'

    Here is where how to make the word 'standing' bold. 

    // Example using '!'.
    drupal_set_message(t('Message with a variable that contains limited HTML tags: Check out this Tumblr <a href="http://goatsstandingonthings.tumblr.com">!link_text</a>.',
      array(
        '!link_text' => 'Goats <strong>standing</strong> on things',
      )
    ), 'status');

    This is a really simplistic example, and in general it's probably best to default to just use the '@' and '%' for formatting - let Drupal do the security work for you!

    Jul 19 2016
    Jul 19

    By now, you may have heard that we’re putting on a show: the ROW Roadshow, to be exact!

    ROW stands for Results Oriented Websites, and it means just what it says. We think that all of our clients – and everyone in the United States! – should have a meaningful web presence, with a website that produces real results and helps them grow their company.

    The ROW Roadshow is our way of taking that message to the people. We’ll be visiting 20 cities over the course of 3 months, and we’d love for you to be a part of it.

    row roadshow cities

    We’ll be hosting and a seminar in every city we visit. The seminar will cover the fundamentals of modern digital marketing, a demonstration of the Drupal CMS and its best marketing tools, and live website valuations.

    THE ROW ROADSHOW SEMINARS

    1. Fundamentals of modern digital marketing: inbound marketing strategies and content marketing strategies
    2. Demonstration of Open Enterprise Pro, our Drupal distribution, and how Drupal modules can help marketers work more efficiently and effectively
    3. Live valuations of example websites submitted by seminar attendees.

    We Need Your Help!

    The website valuations are one of the most important parts of the ROW Roadshow. There’s no better way to demonstrate how digital marketing practices play out in real life. So take 30 seconds right now and submit your site for a free valuation.

    Thanks so much! We can’t wait to see you on the road this fall!

    If you’d like to learn more about the ROW Roadshow, please check out the website and our Sponsorship Kit.

    If you’d like to help by becoming a sponsor, please let us know!

    Jul 14 2016
    Jul 14

    As is always true for Drupal, there are many different ways to accomplish the same end goal. For a recent, project I was tasked with building related content blocks, where nodes tagged with the same taxonomy term as the current node being viewed needed to be displayed in blocks. I initially set this up using Views Blocks and contextual filters, but adding lots of blocks via the Block configuration has always seemed a little suspect to me, so I thought I should try accomplishing the same thing using Panels.  I'll walk you through how I accomplished the same goal - related content blocks - using two different methods: blocks via views, and content panes via panels. Let's get started.

    Download and enable

    1. Views, Views UI
    2. Panels
    3. Chaos tools, Page manager, and Views content panes
    4. Pathauto

    I also used Devel node generate to create dummy taxonomy terms and content. 

    Set up Content Types and Vocabularies

    Configure Page and Article fields

    Since this is a vanilla site, we only have two content types - Articles and Pages. These both have three fields - Title, Body, and Tags. The Article content type also has an image field, which doesn't really matter for this demo but it does make it easier for us to tell the Article nodes apart from the Page nodes when viewing nodes from the front end. For this demo, our goal is that whenever someone is viewing any Page node, there should be a block that lists Article nodes that are tagged with the same taxonomy term as the Page node being viewed. 

    Configure Page and Article paths

    We will also set up Pathauto for pages. This is important for this example as we will be getting information about taxonomy terms from paths. Go to admin/config/search/path/patterns and for the Basic page paths, set the path to [node:field_tags]/[node: title].

    I then went to the Bulk Generate tab to create aliases for all content. To confirm this is working, I viewed a Page node, and could see the taxonomy terms were listed in the path:

    Creating related content blocks with Views

    Add View block

    First we'll add a new View block that will list all of the Article nodes filtered by taxonomy term. To do this, go to admin/structure/views/add. I've named my View 'Related Content Block', showing Content of type Article, and created only a block (I'm not creating a page). Continue & edit. 

    I'm also going to add the image as a field just to make things look prettier, as well as some teaser text. To do this, click on Add Fields, and select Content:Image, Content:Body, and Content:Tags. Add to all displays and configure however you like. I usually uncheck 'Create a label', and for the Body field I'll Rewrite Results to 'Trim this field to a maximum length'. For the Image field Image style I'll pick the Thumbnail style so the images aren't huge in the small block. Once that's done I can see in the Preview that all articles are listed, with the title linked to the full article node, some teaser text from the body, a small image thumbnail, and the tags.

     ​

    Add contextual filter

    To filter the article nodes by term, we will need to add a contextual filter (under Advanced)

    Since we want to filter by the taxonomy term of the current page node, select Content: Has taxonomy term ID and apply. If you want to learn more about what contextual filters are and how they work, there is some good documentation on drupal.org. Paraphrasing from these docs:

    Instead of setting a filter value manually, [with contextual filters] the value is fetched from variables sent programmatically to the view. A regular filter could give you all nodes written by a specified user. A contextual filter for a node author would be able to display all nodes written by the currently viewed user, or the same user who wrote the currently viewed node. The concept is that contextual filters prepare a view for filtering, but the filter value is not yet determined. When the view is eventually called, it is also provided with data used to complete the contextual filters.

    Since we are creating a views block, we will need to provide the default value for the filter. If this was a page, the default value would be provided automatically by the path, but as it's a block it's dumb so we need to give it to it manually. Select the Taxonomy term ID from URL, and check of 'Load default filter from node page'. This will give us more options to limit the terms to the Tags vocabulary (not really important for this example, but could be useful for more complex sites with multiple vocabularies), and for Multi-value handling, select Filter to items that share any term. This just makes the related content block more general - rather than looking for Article nodes that share all of the taxonomy terms of the Page node being viewed, we will look for Article nodes that have any shared term. Hit Apply. 

    Confirm contextual filter is working

    Once you apply these filters, you'll see that the article nodes all disappear from the Views preview. This is because we now need to preview with a contextual filter. Since in this case our contextual filter is 'taxonomy term id' or 'tid' for short, we'll want to get some tids and see what happens when we enter those tids in the preview area for the view. To get a tid, go to your vocabulary (in this case it's at admin/structure/taxonomy/tags since our vocabulary is simply called 'tags') and edit any term. Check the URL for the tid - it will be something like 'taxonomy/term/9/edit' - so 9 is the tid for the term 'dukugutepu' in our case.

     

     ​Now if we preview with contextual filter 9, we will see that only articles tagged with dukugutepu are listed. 

    Configure Views block to display on Page nodes

    Great - our related content block is working, now we'll use the Block Configuration page to add this block to all Page nodes. Make sure to save your view before leaving the page, and then head over to admin/structure/block. Configure your related content block so it displays somewhere on the page by adjusting the Region Settings, and then under Visibility settings only show block for Basic page content types. I also named my block 'related articles'. 

    Now if you view any Page node, the Related Articles block will display (in my case in the Sidebar) and will list all content tagged with the same taxonomy term as the Page currently being viewed. 

    Creating Related Content Pane with Panels

    Here we are going to create a region of related content that from the front end looks quite similar to the related content block we just created. From the back-end though, the set up process is pretty different. 

    Create View

    We will start off by creating a View that will use contextual filters to filter content by taxonomy term ID, but how we use the contextual filters and then display the content on the Page nodes is quite different from the previous example. So go to admin/structure/views/add and create a new view, showing all content of type Article. To distinguish this view from the one we just made, I'll call this Related Content Pane, and uncheck both Create a page and Create a block - we won't be doing either of these here. Click Continue & edit. 

    Add fields as you like here - I'm going to do the same thing I did for the other View, add an image, some teaser text from the Body, and the tags. The preview at this point should look the same as the initial preview from the Views block we created previously - it should list all Article nodes with the fields as you have configured them. 

    Configure contextual filter

    Next add a contextual filter 'Content: Has taxonomy term ID'. This is where things get different. Since we will be using Page Manager and Panels, we don't need to provide a filter value when it is not available - the filter will be provided via the context of the page (this will make more sense when we get into Panels, shortly). Instead, leave it selected as 'Display all results for the specified field'. Under When the filter value is available, you can specify validation criteria, like validating that we are looking at the correct vocabulary.

    After you apply this filter, you should still see all of your Article nodes listed in the preview, since you told it to display all when contextual filter isn't available.

    Add Content Pane

    Now we're going to use Page Manager and Panels to build the 'block' of related content. In your new view, click Add, and select Content Pane (if you don't see this as an option, make sure you have enabled the Page manager and Views content panes modules that are part of Ctools.)

    After you do this, you will see some more options available in that center column of your Views admin, under Pane Settings. 

    This is where we will configure the related content pane. Click the Edit link for Argument input - this is how we set up the contextual filter to accept a a taxonomy term ID. For 'Content: Has taxonomy term ID source' select 'From context' (again, we'll see how this is used when we set up the Panel), and the Required context is the Term ID (listed under Taxonomy term in the dropdown). Apply your settings and make sure you've saved your view. 

    Configure Page content type display using Page Manager

    Under Structure in your admin menu you should have a Pages link (at admin/structure/pages). There are already a bunch of Pages configured for us, so we will enable the Node template for use on our Page content types. Once it's enabled we can edit it.

    The Summary page for the Node template nicely explains what is going on here:

    When enabled, this overrides the default Drupal behavior for displaying nodes at node/%node. If you add variants, you may use selection criteria such as node type or language or user access to provide different views of nodes. If no variant is selected, the default Drupal node view will be used. This page only affects nodes viewed as pages, it will not affect nodes viewed in lists or at other locations. Also please note that if you are using pathauto, aliases may make a node to be somewhere else, but as far as Drupal is concerned, they are still at node/%node.

    Add new variant

    Click on Add a new variant, and give it a good name. For this example I'm going to tweak the display of Page nodes, so I'll call mine Page template. The variant type is Panel, and we will first add some selection rules so select that box. Click on create variant. 

    This will bring us to the next screen where we configure the selection rules. We only want to apply this to Page nodes, so select Node:type and click the add button. Select basic Page and save.

    You should see Node: type, Node being viewed as type 'basic page' is listed now as a selection rule. This means the settings in this variant will only be applied when viewing basic page nodes. We're not done yet though, click Continue. This brings us to layout selection. We will keep it simple and just use a one column layout, but there are lots of options here. There is also a contrib Panels Bootstrap Layouts module that can be helpful if you are using a Bootstrap-based theme. Pick a layout and continue. We won't get into the details of configuring layouts here, so keep continuing through until you can click on the Create variant button, then click Update and save to save all of this. 

    If you go back and view any of your Page nodes, you'll now see that all of the content is gone. This is because we haven't added any of the fields to the Page template variant - it's analogous to managing the display of fields via the content types. 

    Add fields to Page template variant

    To add the fields, click on the gear in whichever column you want to display the fields and select Add Content. (I kept it simple here and only have one column.).

    Under Node, select the Fields you want to add - in this case I will add Field: Body and Field: Tags.

    Configure these as you'd like. I'm going to use the Default formatter and hide the Label for both. 

    You should now have the body and tags listed for display, and if you refresh a Page node you will now see those fields again. 

    Configure Contexts

    Last thing to do is add the related content pane. Remember way back when we were making the Content Pane with Views, we did the somewhat mysterious step where we configured the Content Pane argument to get the Taxonomy Term ID source 'From context'? Here is where the context thing figures in. Under the Page template variant, select Contexts. Under Relationships, select the Taxonomy Term from Node and click the Add relationship button. 

    You can leave everything as is on the next screen (although you might want to change the identifier if you think it's long/not clear) and then click Finish. 

    Add View pane

    Now that we have added our Context, we can go add the Content Pane we created via views to our Content (under Variants->Page template->Content within our Node Template). If you try to add the View pane without configuring the Context, you won't see the View panes option. Back in the Content vertical tab, click the gear to add content.

    Under View panes, select the Related Content Pane we created previously. 

    There aren't really any options on this next configuration screen, since the only Context that is available for the Content:Has taxonomy term ID is the one we just created - Taxonomy term from Node. Hit finish and the Update and save. 

    Now if you go back and view any Page node, you will see the new related content pane, displaying Article nodes tagged with the same taxonomy term as the Page node currently being viewed. Neat!

    Panel Panes vs Views Blocks - which to use?

    This really depends on your use case. If you have a simple site that doesn't ask a lot in terms of configuring fields or displays, Panels might be overkill. It does take a lot more configuration to set up - in this demo, it was a lot quicker to throw together a Views block and set it to display on Pages nodes through the Block configuration. However, if you want total control and flexibility when it comes to how you display your content types, Panels may be the way to go. In the above example, let's say I wanted to have the Page node's title, then list related content, and then list the Page node's body (not a great real-life example, but play along), this wouldn't be possible using Blocks. We only would have the option to display a block in a sidebar, above the content, or below the content (without getting really crazy with template files and the like). This would be easy with Panels though - all we'd have to do is re-order the display of the fields in the Content area of the Panel and it's done.

    Panels is also very powerful when it comes to adding contexts for filters etc - it kind of takes the capabilities of the Display Suite and Context modules and roles them into one great data and logic management system. It also unifies the display and configuration of a content type's fields as well as any other related content in one place. It can get confusing to manage a site if you have complex logic for displaying blocks via Context and then also in-depth configuration of fields via Display Suite. So, like all things Drupal, the answer is 'It depends'.

    If you want to learn more about Panels, there is a whole page on Drupal.org dedicated to video tutorials concerning panels. In particular, the series by Johan Falk at Wunderkraut called Learn Page Manager (Page Manager is the foundation of Panels) is really great. 

    Jul 08 2016
    Jul 08

    Hey, let’s put on a show!

    My colleague Felipa and I felt like we were in a Judy Garland-Mickey Rooney movie. “Let’s put on a show!” said Tom, the CEO here at LevelTen, and we all jumped in to clear out the barn and save the orphanage.

    Tom’s a very clever guy. He’s been building websites for over 20 years, he regularly speaks about how to make your website really work for you, and he’s even written a book about it. When he said he wanted to take his message across the country, we were absolutely on board.

    What’s the ROW Roadshow?

    ROW stands for Results Oriented Websites, and it’s the driving force behind what we do at LevelTen. When we decided to start offering marketing services to our clients last year (in addition to the custom Drupal websites we’ve become expert at churning out), we needed a new philosophy to reflect our new expertise.

    We decided on Results Oriented Websites because that is the one constant goal across our organization: whether you’re a developer writing code, a marketer creating a content strategy, or even our phenomenal intern Lauren (who most recently made a really great beginner’s guide to UX strategy), the goal is to create websites and digital experiences that drive real results for our clients. After all, there’s no point in cheering about thousands of new website visitors if none of them actually turn into new sales.

    It’s simple: we want to help people genuinely move the needle in the new digital landscape. We think that integrating your marketing efforts with an impressive, responsive website is the best way to do that. So Tom’s going to take his message of Results Oriented Websites out to the masses.

    OK, so what are we actually doing here?

    The first thing we needed to do was nail down the scope of the project. Tom’s initial idea was to take an RV across the country, giving his presentation (as well as doing demos and evaluating audience members’ websites) in about 20 cities. That’s a great starting point, but which cities? On which days? Where would he speak, and who would he speak to?

    Felipa and I, as inbound marketing specialists, are great at making online connections with our audience through extraordinarily well-written blog posts like this one. We weren’t entirely sure where to start when we needed to help make connections between people in real life. That’s OK – read on to see what we learned.

    Lions, Tigers, and Buyer Personas, Oh My.

    We decided to start with what we know, which means that Step One is audience research. I know, I know; this is nobody’s favorite part of the process. (Actually, hold on a sec – if audience research and buyer personas is your favorite part of the process, we might have an opening for you.) But it’s as true for public speaking as it is for blogging: you can’t communicate effectively until you know who you’re talking to and what they need.

    We started with a survey to gauge interest, asking people the topics, format, and time of day they were most interested in. And then we sent that survey just about everywhere we could think of. Felipa emailed it to our entire email list (sorry, everyone!) and created an AddThis popup on our website’s home page.

    results oriented web pop by addthis

    While we didn’t get as many responses as we would have liked, the survey feedback definitely gave us enough information to start planning the Roadshow, so that counts as a success. (And hey, the survey’s still open, if you’d like to help out!)

    Scheduling. More scheduling. Then even more scheduling.

    Next came the most administratively complex part: the scheduling. Tom gave us a list of the cities he wanted to visit and the approximate dates he would be there. Obviously, any speaking engagement is going to be more effective if you can join with a group of people who already meet to talk about something related, so we dove into more research to find groups we could piggy-back off. DrupalCamps, Meetup groups, LinkedIn groups, HubSpot HUGs, the list goes on.

    Not gonna lie – this was the hardest, most time-intensive part of the process. There are just too many moving pieces! But with enough elbow grease, we created a comprehensive schedule that coordinated with as many local groups as possible.

    Branding the Campaign.

    We decided to do this “ROW Roadshow” speaking tour in the style of a political campaign. Because Tom is going to be driving around the country in an RV, we thought it would be really fun and eye-catching to dress up the RV like a campaign bus, bringing our message to the people.

    results oriented web campaign bus

    Add in a mini-site [coming soon] to help support the campaign in, and we’re off!

    Wait and see how it goes!

    Now that the bulk of the work has been done, Felipa and I can sit back and relax with a smile and a cool beverage get back to everything else we’re supposed to be working on. But we’re very excited to see the results of the campaign and how many people we can help with their website issues!

    wait and see judy garland and mickey rooney

    Jun 22 2016
    Jun 22

    When LevelTen gets into talks with potential clients or even current clients, our first thought is to recommend businesses to Pantheon hosting for scalable websites. When we first began looking for partners to host and manage our Open Enterprise Pro CMS, a Drupal distribution, Pantheon was a clear choice. Our company philosophy is built around providing infinitely scalable content management and marketing solutions that are simple enough for nontechnical people to manage and maintain their websites. That’s also what we found in Pantheon’s platform.

    LevelTen leverages Pantheon’s hosting platform for developing all of our website projects. Well, our developer Kyle Taylor says, "Compared to others [hosting platforms], Pantheon gave us everything. We have dev sites we can work with, dev to production workflow, an intuitive GUI, a competitive price for production, and great performance when under pressure."

    We have several client projects on Pantheon and the feedback we received from our customers has been very positive. Pantheon’s user interface took a rather complex development operations workflow and made it absurdly simple, for even the in-house marketing and sales team to understand it.

    Here are the 6 strategic advantages your business gains from our partnership with Pantheon:

    1. You contact LevelTen and want to learn how Open Enterprise CMS can improve your business – We can spin up and customize a demo specific to your needs in a matter of minutes. There's no wait time, no complicated set-up. We can bring your vision to life.
    2. When you choose our CMS as your solution – Pantheon allows us to very quickly create a development environment and spin up an instance of Open Enterprise so that we can begin work immediately. No, we aren't talking dev time, yet, even our Project Manager can spin-up the instances. Pantheon and Open Enterprise are that simple.
    3. Security and updates are important to a website. So, when you need immediate access to all support updates and patches - Open Enterprise platform is connected to Pantheon in a way that when we make updates and improvements to our CMS platform upstream, those updates are immediately pushed out to all of our customers’ websites. This process significantly reduces LevelTen’s support overhead and allows us to provide additional value and cost savings to you.
    4. Testing new updates and features is important to keep a website from breaking. When you need to test your updates to ensure they work before pushing to live, Pantheon comes with separate development, test and production environments that allow you to very easily test a push all updates from one environment to another.
    5. The Speed of websites is crucial for visitor retention. You need to ensure your site loads quickly – Pantheon is specifically tuned for Drupal websites and provides recommendations for optimizing your site's performance.
    6. You trust Pantheon and LevelTen to keep your website live and running. Dedicated and knowledgeable account and sales managers like our Kendall Westbrook and Sophie Jelen from Pantheon, are professional, respond quickly and always are very helpful.

    Pantheon has allowed LevelTen to grow exponentially by streamlining our development and support process for Open Enterprise Pro. I know our developers are excited about Pantheon’s features for multidev, change management, and tagging; providing us with more flexibility and organization, especially as we ready ourselves to release the next generation of Open Enterprise Pro.

    May 26 2016
    May 26

    What do you get when you put two Project Managers in one hotel room for a week at DrupalCon? A lot of work, a lot of laughter, and a lot of learning. Don’t worry, we didn’t kill each other… yet.

    With our days spent in sessions and nights spent on Bourbon Street or answering client emails (not at the same time), DrupalCon New Orleans was a truly illuminating experience. I came to LevelTen a year ago not even knowing what “Drupal” was -- and in the past year I have truly come to understand the power behind the Drupal platform and the community.

    My Three Big Takeaways from DrupalCon 2016:

    1. You are not alone in your frustrations.

    2. You don’t know what you don’t know.

    3. Knowledge is power.

    You are not alone in your frustrations.

    From a Project Management standpoint, this was incredibly helpful to understand: someone else has been through exactly what you’ve been through -- and they didn’t die, either.

    In On Inheriting Someone Else's Mess: Lessons Learned from a Rescue Project, Marcus Iannozzi from Message Agency explored the difficulties of taking on someone else’s project. I particularly related to his concept of “wounded trust”: when a client who has had a bad experience worries, not only that you won’t deliver, but that you are actively trying to take advantage of them. Sound familiar? From an inside sales perspective, I deal with this often.

    Perhaps the most illuminating part of this session actually came from the Q&A portion. Someone asked if, knowing what he knows now, Marcus would take on this project again. Without hesitation, he said “No.”

    Takeaway: Hindsight is always 20/20.

    In Becoming a TPM: Dos and Don'ts of Technical Project Management, Jessi Fischer (Pantheon) and Anne Stefanyk (Kanopi Studios) showed an impressive display of cat GIFs as the basis of a comparison of Technical Project Management to herding cats. They discussed that the key to good TPM is to communicate effectively with a non-technical audience and employ strategies for risk mitigation. Don’t leave your developers out to dry, and take responsibility for the team as a whole.

    Takeaway: When you put cats in a presentation, I am 1000% more likely to pay attention.

    In How To Grow Support To Become A Cornerstone Of Your Business, John Ouellet and Katy Pool from Kalamuna touched on both good and bad clients, while also discussing how to structure support contracts to function as a lead-in to larger projects. Have a tough client? They suggest either learning how to say no, implementing another team member as the PM, or parting ways with the client.

    Takeaway: The dreaded “support” contract can be beneficial for your business if you have the right team and the right framework.

    You don’t know what you don’t know [and I didn’t know any of this].

    In a BoF covering Event Organization & Sponsorship called “Mo Money, Mo Sponsors,” focusing particularly Drupal and other tech Camps, representatives from Pantheon, Acquia, and FFW seemed to agree on one thing: if you want to get your camp sponsored, you need data. This includes who will be attending your event and their demographics, but also a marketing plan that covers how you will be attracting new people to your camp.

    Takeaway: Pantheon doesn’t care if you put their name on a shirt or a poster. Offering face time with potential clients or new hires is one of the most valuable things you can offer.

    In Recruiting and Retaining Dedicated Volunteers, Stephanie from Amazee Labs covered how to find, train, and retain a great volunteer staff. She made a great Stone Soup analogy that boiled down to this: individually, people may not have much to give as far as talents, availability, or interest, but if you maximize on their desire for something great, you can create it.

    Takeaway: Offload enough responsibility on your volunteers so that you can jump in if something goes wrong without causing something else to break.

    Knowledge is power.

    In GE Energy Connections & FFW: Delivering Business Results Beyond Clicks, Conversions and Revenue, Brent Bice (Agency) and Holly Bounds (Client) teamed up to offer both agency and client perspectives on moving to Drupal. Holly was gracious enough to speak with me for a few minutes afterwards from a sales point-of-view on how they were convinced to move to Drupal and to work with FFW. She mentioned that one of the big pieces that FFW was able to offer was knowledge: for example, teaching her the difference between a configuration and a customization allowed her to prioritize what they needed and cut costs where configurations were sufficient.

    Takeaway: The modern client wants to feel empowered, even if you’re doing all the work. Taking the time to teach them certain things can have a large ROI.

    My first year at DrupalCon was one for the books -- and not just because of the Pantheon party, or the beignets, or getting soaked in the rain with my teammates. Connecting with hundreds of like-minded people in person really reinforced the community foundations of Drupal for me, and helped me to better understand both the current state of Drupal shops, and the opportunities that we have to grow and change in the future.

    Check out the rest of our DrupalCon[densed] 2106 series! No matter who you are, we've got your perspective covered.

    May 25 2016
    May 25

    My role as a principal at LevelTen means that I spend a lot of time overseeing Accounting, Operations, and Marketing. So for my visit to DrupalCon 2016, I wanted to spend as much time as I could talking with other C-level people to see what struggles we have in common and what solutions we've come up with.

    Throughout the sessions, summits, and socializing, there were a few key themes that kept coming up over and over from people who run Drupal shops. With that in mind, this post is less of a DrupalCon 2016 takeaway than a preliminary analysis of the economics of Drupal as it evolves in Drupal 8 and beyond.

    Offshoring: The U.S. Perspective

    As with any business, attention to the bottom line is always a topic of hot discussion among agency principals. One recurring theme seems to be the idea of offshoring of development work (and increasingly other work).

    Let’s face it, Drupal has its origins across the pond, so the concept of offshoring has always been in its roots, so to speak. As Drupal grew, healthy collaboration from anywhere in the world became a standard within the community. Geographic boundaries were never a problem when it came to the sharing of information, modules, and other technical hurdles.

    What did NOT come as straightforward was the outsourcing of the actual development work (or project management work) to places outside of the country a company was conducting business. Historically, outsourcing seemed to be frowned upon within U.S. agency circles, but now, it seems to be the standard practice for larger agencies, even if only to test the waters. (For the record, I am not a protectionist, but I can appreciate the long term economic implications suggested by those who don’t like this trend.)

    Either way, it is a new economic reality for any U.S. agency wishing to compete: some competitors will be leveraging workforces outside the U.S. We can talk about maintaining a competitive advantage all day, but the economics of capitalism will drive companies to seek economic advantages abroad if they exist.

    Business Summit: One Size Does Not Fit All

    Susan Rust did an excellent job of leading the Business Summit, where many takeaways for agency principals were discussed. There were way too many great conversations to pack into this writing, so I suggest that, if at all possible, you should really attend one of these summits yourself -- maybe at DrupalCon Baltimore?

    One issue Susan raised, which I also think needs to be addressed, is the separation of agencies by size in these summits. Considering all the varying sizes of companies working with Drupal, one size does NOT fit all when it comes to operational challenges (or solutions). It is both inspiring and comforting for all to listen to the successes and challenges of all size shops; however, the idea that a 15-person company like LevelTen will employ the same solutions as a 100-person shop and a 2-person shop would be naive. I reiterate Susan’s call to modify the format in some way to accommodate all business summit participants, but sub-segment by agency size.

    Drupal Economics: Drupal is Going Upstream

    For those developer types, “upstream” has nothing to do with Git. In business parlance, "upstream" has to do with looking at larger industry sectors that, most times, serve other industries downstream. When we say that Drupal is going upstream, we mean that Drupal is evolving to be a good solution for large enterprise-level businesses, as opposed to small or mid-size businesses.

    I saw a lot of people during the course of the week get caught up in the question of whether Drupal "can" be for everyone. Of course it can. The real question is "Who is Drupal best suited for at this time?," and an honest assessment is needed to answer it. It seems clear that Drupal is going upstream, becoming a preferred web platform for large enterprises. If you think Drupal is still best suited for small or medium businesses, I would love to hear why.

    Now that we have established that Drupal is in fact going “upstream,” I would like to share what that means for the economics of Drupal:

    1. Project sizes are getting larger, even as websites are commoditized.

    Websites are fast becoming a commodity (if they are not already there, here in 2016). Look no further than ads for free websites with a minimal purchase, or inexpensive SAAS platforms for the masses. With this commoditization comes downward pressure on prices (price per unit of output), even as the industry matures. The successful companies look to larger projects to sustain the increased revenue requirements needed to support growth initiatives in an industry where the price per unit of output is decreasing.

    2. Drupal shops are looking for economic advantages (see my point about outsourcing, above).

    With increased revenue comes increased expenses and decreased profits as a percentage. Business owners often combat this with lower cost structures to prop up profits, which is generally regarded as a short term fix.

    Lowering costs is not a sustainable model for growth unless, that is your competitive advantage (side note: contrary to Michael Porter’s acclaimed Competitive Advantage Theory (which I generally subscribe to), certain industries that exhibit rapid change, and lots of new alternatives or substitutes, will find that being the cost leader is the least desired strategy). Instead, the majority of Drupal shops are looking for other ways to increase their margins, whether that is through outsourcing, moving to a recurring-revenue retainer model, or other ways of restructuring the company.

    3. Consolidation in the industry is coming.

    Lastly, in an environment this competitive, Drupal companies are increasingly looking to consolidation through mergers and acquisitions of competitors to maintain growth. In this scenario, only a few survive the onslaught -- unless you have a true differentiation in the marketplace, and even then, it will be tempting to sell out to a competitor at some point.

    This is not a doomsday prediction for the economics of Drupal, but rather, a reminder of the economic forces of goods and services that have increasing demand, and how companies attempt to capitalize on this need during the growth phase.

    As Drupal becomes more powerful and more popular, these tensions are going to arise for more and more people, from solo freelancers to small shops to big players like our friends at FFW. At LevelTen, we plan to keep doing everything we can to keep bringing Drupal solutions to the people that need them.

    Check out the rest of our DrupalCon[densed] 2106 series! No matter who you are, we've got your perspective covered.

    May 24 2016
    May 24

    DrupalCon New Orleans was the third DrupalCon I’ve attended, and it never ceases to amaze me how much Drupal has changed over the years, and how much time and effort the community puts in -- not just into core and contrib, but also into building out third party tools, scripts, and methods that will benefit other agencies and freelancers. It really is a privilege to be a part of a community that is so incredibly committed to the values of open source and always willing to share their experience along the way.

    Aside from the #prenote, catching up with old friends, and some of the weirdest parties you’ll ever attend, DrupalCon is the time of year for those who don’t always pay close attention to core updates and community conversations to catch up on the current trends in the Drupal community, learn about what’s going on, and learn how to actually use these new tools being developed.

    Without further ado, this is a recap of the best trends and tips I took away from DrupalCon, from a developer's point of view.
     

    1. Drupal 8

    With the release of Drupal 8 late last year, and with DrupalCon Los Angeles having a strong showing of sessions prepping us for Drupal 8, it’s no surprise that this topic spanned across a majority of the sessions. Of course, the lingering question remained for every freelancer and agency: “When are we going to move to Drupal 8?” Last year, there was quite a bit of hesitation while the business community waited for D8 contrib to catch up. This year, it seemed like the resounding answer is “NOW."

    BigPipe loading principle demo gif Of course, it’s not just new Drupal 8 sites that are being built, but migrations from Drupal 6 or 7, so a lot of effort has been going into core migration and the Migration Tools module. With that, the underlying gist is this: if you haven’t set sail to Drupal 8 yet, at least start helping us build the boats to get over there.

    2. TWIG (theming)

    When I first started working in Drupal, I went from a site builder to a front-end developer (I’ve also been known to write a module or two). Since I spend the majority of my days writing CSS and theme functions, I thought I should focus a lot of my attention on new theming developments and front-end tools (Drupal 8 or otherwise).

    MortenDK’s talk, “Drupal8 Theming - Am I doing this right?” was by far one of the best sessions I attended. While he talks like a Danish pirate, Morten explained just about everything in theming, from how & why to use Twig, to the quirks of building a D8 theme (always start with a core base theme, Stable or Classy), to the disappearance of the theme() function. One big takeaway from Morten’s session was hearing his passion come through about the importance of theming support and development in Drupal 8. Often, front-end functionality is less favored than content administration and better OOP support. In case you’re wondering, this is what Drupal looks like without a front-end. Think about it.

    3. Paragraphs

    At LevelTen, we leverage the Bootstrap framework across all of our projects as a solid foundation for our clients' themes, and in turn, we develop a lot of tools and modules that help us work better Bootstrap components. Other than a number of block enhancements, a lot of our focus is empowering productivity for our clients through the WYSIWYG. This means leveraging the CKEditor Widgets API and building out templates clients can use to create advanced Bootstrap components, like carousels and jumbotrons.

    The plus side to this model is that everything is in one field, so when we create summaries or export the content, we’re only dealing with a single body field. The downside is that since it is still HTML in a WYSIWYG, there is an opportunity for clients to potentially break these components by messing with the source code and removing necessary attributes, closing tags, and so on.

    Throughout a number of sessions, I saw multiple demos and sites using the Paragraphs module. If you’re unfamiliar with Paragraphs, it essentially lets you create types of paragraphs, or collections of fields, that can be added in any order (if you’ve used the Field Collection module, this should feel familiar). Each paragraph type can then be configured using view modes and custom templates, creating clearly defined templates for your clients' content. While the downside is that it’s another field you have to add to your content type, the upside is that it makes it very, very difficult for a client to break the site while putting in content.

    I will admit, as a developer who is constantly trying to build a better experience for editors to create compelling and creative content, this is very enticing.

    So what now?

    DrupalCon New Orleans was an awesome event, and I’m pretty excited about the future of Drupal. While I couldn’t mention everything in here, I will say that there were some great talks from Acquia / FFW about Personalization and an awesome talk about style guides and patterns from Phase2. At this point, I’m fairly eager to get my hands dirty with a Drupal 8 site working on Twig templates and learning more about Symfony.

    Who know, maybe I’ll even start porting some of my own modules over to Drupal 8.

    If you're a developer who went to DrupalCon New Orleans 2016, what was your favorite take-away from the sessions?

    Did you catch our Drupal Con[densed] 2016: The Best Content Marketing Sessions blog? Read all about it here.
    May 24 2016
    May 24

    As a beginning developer who spent the majority of the last three months learning front-end javascript frameworks and the MEAN stack, I was anxious to get re-acquainted with Drupal, all of its ‘isms, and the storied community behind it. But besides tired feet, a hangover, and a backpack stuffed with free swag, what would I take away from it all?

    Looking back, it’s tough to capture all the remarkable insights from such interrelated sessions and do them justice in a single blog post, but I did come across several ideas from the con that stuck with me in one way or another. So without further ado, here are some DrupalCon 2016 takeaways from the eyes of a (junior) Junior Front-End Developer.

    Don’t Just Design a Page: Create a Design System

    In probably my favorite session of the conference, Road Runner Rules: More What You’d Call Guidelines for Design Systems, presenter Micah Godbolt was able to use linguistics as an extended analogy to explain how Design Systems combine sets of design rules and assets to define how to express the visual language of a project.

    Similar to Brad Frost’s Principles of Atomic Design, Micah demonstrated how the simple components of a Design System (the phonemes of our visual language) build on one another and work together to form more complex pieces (the syntax) that communicate ideas and intention to the user. By deconstructing a client’s site redesign comp into its individual components, he was able to demonstrate how a design project can easily go from daunting to doable by thinking in terms of these individual rules and components.

    But of course, the icing on the cake was the inclusion of Chuck Jones’ Road Runner Rules as an example of thoughtful design rules. With rules like “No outside force can harm the coyote—only his own ineptitude or the failure of the Acme products” or “The Road Runner cannot harm the coyote except by going beep-beep," it became clear how rich, engaging, and repeatable experiences can be created by crafting simple, well-thought-out guidelines that work together to serve the project.

    CSS Principles: A Much Needed Re-Introduction

    While explaining how design systems incorporate certain rules of thumb, the Road Runner Rules session also provided a much-needed re-introduction to some more foundational principles for writing better CSS: namely, the "single source of truth" principle and the "single responsibility" principle, which together read like two sides of the same coin when it comes to CSS.

    The "single source of truth" principle refers to the structuring of classes so that an element ideally receives styles from a single source in the CSS. By avoiding elements receiving styles from multiple locations, we end up with more readable, maintainable CSS.

    The flip side of this is the notion of the "single responsibility" principle, which (in this context) means aiming for a single use case for every class so that classes and styles aren’t applied in different, conflicting contexts.

    In addition to these principles, I found the quick primer on object-oriented CSS (separation of structure and skin, separation of container and content) to be equally helpful in reminding me what clean CSS looks like, and exactly how un-clean some of my early CSS turned out to be (yuck).

    If Possible, Ditch Your Ipsum and Build With Content

    In two separate sessions, I was reminded of how valuable building pages with real content can be, as opposed to starting with random bits of lorem ipsum. In Jeff Eaton’s Recoupling: Bridging Design and Structured Content, I was introduced to the idea of what he calls naive decoupling, which represents the negative outcomes that can come from an uncoordinated siloing of content and design. This can ultimately strip meaning from content, or ignore things like editorial curation and aggregation.

    The idea to build with content when possible was reiterated in Brett Meyer’s entertaining presentation, Content Strategy in Popular Culture. Brett also provided excellent examples of well-modeled content, including Pearl Jam’s website, where all live performances of each song are catalogued. For instance, thanks to great content modeling, you can look up all 517 times they’ve played Jeremy live. That’s pretty cool, even if they’re not exactly your jam.

    With Web Accessibility, Beware the Edge-Case Myth

    Being a newcomer to the world of web accessibility issues, I was astonished by some of the facts presented by Helena Zubkow in her presentation, Web Accessibility 101: Principles, Concepts, and Financial Viability.

    I hadn't realized that web accessibility measures have so much impact. For instance, in talking about the myth of the edge-case when it comes to web accessibility, she noted that there are 38.3 million severely disabled people in the U.S. -- which is close to twice the population of the state of New York! Just imagine telling a client, “We have the website ready for launch! But it doesn’t work in New York.” The ridiculousness of that statement should provide some much-needed perspective in situations where the term “edge-case” may get thrown around.

    I was also excited to check out the two web accessibility tools she recommended. The first is the Wave toolbar, which gives you visual feedback on your site’s web accessibility and how to fix accessibility errors. The other is HTML5 Outliner, a tool that grabs your headlines and allows you to check your headline hierarchy, which is crucial for assistive technologies. All in all, this was a great presentation that reminds us that we make the internet for everyone. Period.

    Grey Matter Matters! Douse Your Brain in H20 for Clarity and Focus

    Finally, I wanted to share a fun fact from Michael Schmid’s Community Keynote; Your Brain Health is More Important than your Standing Desk, where he discusses brain health and personal workflow strategies that he’s found to be successful.

    You’ve probably heard the generic “drink more water!” advice before, but here’s some science Michael came across to persuade those of us who haven’t yet adopted the "drink more, pee more, feel better" philosophy. We know that our bodies are 60% water, but I didn’t know that our brains are made up of even more water -- around 85%. More interesting, though, are the findings that suggest that a dehydration level of only 1% leads to a 5% decrease in cognitive ability, and a 2% level of dehydration leads to losing focus and decreases short-term memory function. Yikes, thanks for dropping some science on us all, Michael! At the very least, we can all have dehydration take the fall anytime we forget to… wait, what was I saying? Brb watercooler.

    Even now, as I continue to look back on the conference and review my notes, at least one thing becomes clear: the worst part about DrupalCon is having to choose between so many great sessions with competing time slots (well, that and the wi-fi). Luckily, videos of most all the presentations can be found here, meaning we can enjoy all the aha moments from the conference we can handle. Check them out!

    read other blog posts in the drupal con[densed] series:

    May 24 2016
    May 24

    DrupalCon New Orleans was the third DrupalCon I’ve attended, and it never ceases to amaze me how much Drupal has changed over the years, and how much time and effort the community puts in -- not just into core and contrib, but also into building out third party tools, scripts, and methods that will benefit other agencies and freelancers. It really is a privilege to be a part of a community that is so incredibly committed to the values of open source and always willing to share their experience along the way.

    Aside from the #prenote, catching up with old friends, and some of the weirdest parties you’ll ever attend, DrupalCon is the time of year for those who don’t always pay close attention to core updates and community conversations to catch up on the current trends in the Drupal community, learn about what’s going on, and learn how to actually use these new tools being developed.

    Without further ado, this is a recap of the best trends and tips I took away from DrupalCon, from a developer's point of view.
     

    1. Drupal 8

    With the release of Drupal 8 late last year, and with DrupalCon Los Angeles having a strong showing of sessions prepping us for Drupal 8, it’s no surprise that this topic spanned across a majority of the sessions. Of course, the lingering question remained for every freelancer and agency: “When are we going to move to Drupal 8?” Last year, there was quite a bit of hesitation while the business community waited for D8 contrib to catch up. This year, it seemed like the resounding answer is “NOW."

    BigPipe loading principle demo gif Of course, it’s not just new Drupal 8 sites that are being built, but migrations from Drupal 6 or 7, so a lot of effort has been going into core migration and the Migration Tools module. With that, the underlying gist is this: if you haven’t set sail to Drupal 8 yet, at least start helping us build the boats to get over there.

    2. TWIG (theming)

    When I first started working in Drupal, I went from a site builder to a front-end developer (I’ve also been known to write a module or two). Since I spend the majority of my days writing CSS and theme functions, I thought I should focus a lot of my attention on new theming developments and front-end tools (Drupal 8 or otherwise).

    MortenDK’s talk, “Drupal8 Theming - Am I doing this right?” was by far one of the best sessions I attended. While he talks like a Danish pirate, Morten explained just about everything in theming, from how & why to use Twig, to the quirks of building a D8 theme (always start with a core base theme, Stable or Classy), to the disappearance of the theme() function. One big takeaway from Morten’s session was hearing his passion come through about the importance of theming support and development in Drupal 8. Often, front-end functionality is less favored than content administration and better OOP support. In case you’re wondering, this is what Drupal looks like without a front-end. Think about it.

    3. Paragraphs

    At LevelTen, we leverage the Bootstrap framework across all of our projects as a solid foundation for our clients' themes, and in turn, we develop a lot of tools and modules that help us work better Bootstrap components. Other than a number of block enhancements, a lot of our focus is empowering productivity for our clients through the WYSIWYG. This means leveraging the CKEditor Widgets API and building out templates clients can use to create advanced Bootstrap components, like carousels and jumbotrons.

    The plus side to this model is that everything is in one field, so when we create summaries or export the content, we’re only dealing with a single body field. The downside is that since it is still HTML in a WYSIWYG, there is an opportunity for clients to potentially break these components by messing with the source code and removing necessary attributes, closing tags, and so on.

    Throughout a number of sessions, I saw multiple demos and sites using the Paragraphs module. If you’re unfamiliar with Paragraphs, it essentially lets you create types of paragraphs, or collections of fields, that can be added in any order (if you’ve used the Field Collection module, this should feel familiar). Each paragraph type can then be configured using view modes and custom templates, creating clearly defined templates for your clients' content. While the downside is that it’s another field you have to add to your content type, the upside is that it makes it very, very difficult for a client to break the site while putting in content.

    I will admit, as a developer who is constantly trying to build a better experience for editors to create compelling and creative content, this is very enticing.

    So what now?

    DrupalCon New Orleans was an awesome event, and I’m pretty excited about the future of Drupal. While I couldn’t mention everything in here, I will say that there were some great talks from Acquia / FFW about Personalization and an awesome talk about style guides and patterns from Phase2. At this point, I’m fairly eager to get my hands dirty with a Drupal 8 site working on Twig templates and learning more about Symfony.

    Who know, maybe I’ll even start porting some of my own modules over to Drupal 8.

    If you're a developer who went to DrupalCon New Orleans 2016, what was your favorite take-away from the sessions?

    Check out the rest of our DrupalCon[densed] 2106 series! No matter who you are, we've got your perspective covered.

    May 24 2016
    May 24

    As a beginning developer who spent the majority of the last three months learning front-end javascript frameworks and the MEAN stack, I was anxious to get re-acquainted with Drupal, all of its ‘isms, and the storied community behind it. But besides tired feet, a hangover, and a backpack stuffed with free swag, what would I take away from it all?

    Looking back, it’s tough to capture all the remarkable insights from such interrelated sessions and do them justice in a single blog post, but I did come across several ideas from the con that stuck with me in one way or another. So without further ado, here are some DrupalCon 2016 takeaways from the eyes of a (junior) Junior Front-End Developer.

    Don’t Just Design a Page: Create a Design System

    In probably my favorite session of the conference, Road Runner Rules: More What You’d Call Guidelines for Design Systems, presenter Micah Godbolt was able to use linguistics as an extended analogy to explain how Design Systems combine sets of design rules and assets to define how to express the visual language of a project.

    Similar to Brad Frost’s Principles of Atomic Design, Micah demonstrated how the simple components of a Design System (the phonemes of our visual language) build on one another and work together to form more complex pieces (the syntax) that communicate ideas and intention to the user. By deconstructing a client’s site redesign comp into its individual components, he was able to demonstrate how a design project can easily go from daunting to doable by thinking in terms of these individual rules and components.

    But of course, the icing on the cake was the inclusion of Chuck Jones’ Road Runner Rules as an example of thoughtful design rules. With rules like “No outside force can harm the coyote—only his own ineptitude or the failure of the Acme products” or “The Road Runner cannot harm the coyote except by going beep-beep," it became clear how rich, engaging, and repeatable experiences can be created by crafting simple, well-thought-out guidelines that work together to serve the project.

    CSS Principles: A Much Needed Re-Introduction

    While explaining how design systems incorporate certain rules of thumb, the Road Runner Rules session also provided a much-needed re-introduction to some more foundational principles for writing better CSS: namely, the "single source of truth" principle and the "single responsibility" principle, which together read like two sides of the same coin when it comes to CSS.

    The "single source of truth" principle refers to the structuring of classes so that an element ideally receives styles from a single source in the CSS. By avoiding elements receiving styles from multiple locations, we end up with more readable, maintainable CSS.

    The flip side of this is the notion of the "single responsibility" principle, which (in this context) means aiming for a single use case for every class so that classes and styles aren’t applied in different, conflicting contexts.

    In addition to these principles, I found the quick primer on object-oriented CSS (separation of structure and skin, separation of container and content) to be equally helpful in reminding me what clean CSS looks like, and exactly how un-clean some of my early CSS turned out to be (yuck).

    If Possible, Ditch Your Ipsum and Build With Content

    In two separate sessions, I was reminded of how valuable building pages with real content can be, as opposed to starting with random bits of lorem ipsum. In Jeff Eaton’s Recoupling: Bridging Design and Structured Content, I was introduced to the idea of what he calls naive decoupling, which represents the negative outcomes that can come from an uncoordinated siloing of content and design. This can ultimately strip meaning from content, or ignore things like editorial curation and aggregation.

    The idea to build with content when possible was reiterated in Brett Meyer’s entertaining presentation, Content Strategy in Popular Culture. Brett also provided excellent examples of well-modeled content, including Pearl Jam’s website, where all live performances of each song are catalogued. For instance, thanks to great content modeling, you can look up all 517 times they’ve played Jeremy live. That’s pretty cool, even if they’re not exactly your jam.

    With Web Accessibility, Beware the Edge-Case Myth

    Being a newcomer to the world of web accessibility issues, I was astonished by some of the facts presented by Helena Zubkow in her presentation, Web Accessibility 101: Principles, Concepts, and Financial Viability.

    I hadn't realized that web accessibility measures have so much impact. For instance, in talking about the myth of the edge-case when it comes to web accessibility, she noted that there are 38.3 million severely disabled people in the U.S. -- which is close to twice the population of the state of New York! Just imagine telling a client, “We have the website ready for launch! But it doesn’t work in New York.” The ridiculousness of that statement should provide some much-needed perspective in situations where the term “edge-case” may get thrown around.

    I was also excited to check out the two web accessibility tools she recommended. The first is the Wave toolbar, which gives you visual feedback on your site’s web accessibility and how to fix accessibility errors. The other is HTML5 Outliner, a tool that grabs your headlines and allows you to check your headline hierarchy, which is crucial for assistive technologies. All in all, this was a great presentation that reminds us that we make the internet for everyone. Period.

    Grey Matter Matters! Douse Your Brain in H20 for Clarity and Focus

    Finally, I wanted to share a fun fact from Michael Schmid’s Community Keynote; Your Brain Health is More Important than your Standing Desk, where he discusses brain health and personal workflow strategies that he’s found to be successful.

    You’ve probably heard the generic “drink more water!” advice before, but here’s some science Michael came across to persuade those of us who haven’t yet adopted the "drink more, pee more, feel better" philosophy. We know that our bodies are 60% water, but I didn’t know that our brains are made up of even more water -- around 85%. More interesting, though, are the findings that suggest that a dehydration level of only 1% leads to a 5% decrease in cognitive ability, and a 2% level of dehydration leads to losing focus and decreases short-term memory function. Yikes, thanks for dropping some science on us all, Michael! At the very least, we can all have dehydration take the fall anytime we forget to… wait, what was I saying? Brb watercooler.

    Even now, as I continue to look back on the conference and review my notes, at least one thing becomes clear: the worst part about DrupalCon is having to choose between so many great sessions with competing time slots (well, that and the wi-fi). Luckily, videos of most all the presentations can be found here, meaning we can enjoy all the aha moments from the conference we can handle. Check them out!

    Check out the rest of our DrupalCon[densed] 2106 series! No matter who you are, we've got your perspective covered.

    May 18 2016
    May 18

    As a marketer, a Drupal newbie, and the newest LevelTen employee, I was super excited for DrupalCon.

    Historically, there has not been a lot of overlap between the Drupal world and the marketing world. One one level that makes some sense: companies who need a Drupal web solution are often large enterprise-level organizations who have the resources for an in-house marketing team.

    But it’s clear after my week at DrupalCon 2016 that more and more agencies and web developers are recognizing that they need to offer some kind of content or content strategy services to their clients. Every session that touched on content was packed, with people sitting on the floor or leaning against a wall. It’s clear that the Drupal community is starting to embrace content as a marketing tool, not just a static website component.

    What I Learned at DrupalCon as a Marketer

    Here are the most important things I learned at DrupalCon New Orleans:

    • My “comfortable shoes” are not actually comfortable.
    • If I go to an “advanced” session, I will understand each and every word that is said, but I will not be able to understand any single sentence.
    • I will always and eternally be excited by the prospect of a free t-shirt.

    Whoops, sorry, those were the most unimportant things I learned. Valuable to me, yes, but slightly less valuable to you.

    The truth is that I learned a ton at a bunch of different sessions. I’m going to touch on my three favorite sessions, and then dive into the Tuesday keynote, which I thought was really powerful.

    My Three Favorite Sessions

    Content-Driven UX, by June Parent, Senior Digital Strategist at ImageX, and Bjorn Thomson, Senior Solutions Architect at ImageX

    This was a really great talk on how and why content should come first and then shape everything about your website. The presenters went into a lot of detail and step-by-step instruction on how to do a content audit. They actually presented a “Content-Driven Framework” that I hadn’t seen before – Audience, Messaging, Interaction, Optimization, Distribution, Measurement – that I’m going to use in my next Marketing Strategy Plan. They also claimed that there is really no practical difference between content and UX any more, and by the end of the presentation, I agreed with them.

    Content Strategy in Popular Culture, by Brett Meyer, Chief Strategy Officer at ThinkShout

    This was hands-down the most entertaining session I attended, and the rest of the LevelTen team agreed. Brett Meyer gave us a look at content strategy through the lens of nerd culture: for example, why is Captain America: Civil War so successful, while Batman V. Superman failed by comparison? Because Marvel has tapped into what its users really want, and is delivering more of it – and that’s what we have to do for our clients as well. Similarly, is it okay to repackage and reuse content? Sure, if that’s what your audience wants – just look at The Force Awakens.

    The Ultimate Super Duper Guide to Content Quality, by Courtney Clark, Senior User Experience Designer at Forum One, and Kristina Bjoran, Project Manager & UX Designer at Forum One

    The session delivered on its promise. The presenters worked step-by-step through the components of quality content: Structure, Presentation, Clarity, Keywords, Voice, and Organization. Each section iterated on the same example of content to take it from “meh” to “marvelous”. It was a little surface-level for me, as a full-time content strategist, but a great introduction to the elements of content quality for those who have just started in the field or are just beginning to learn about it.

    The Life-Changing Tuesday Keynote

    DrupalCon New Orleans 2016: Tuesday Keynote: Sara Wachter-Boettcher

    Everybody Hurts: Design for Kindness

    Guys, I was more than a little bit blown away by this keynote. As a female marketer in a place like DrupalCon, which is heavily male and heavily developer-focused, there’s always going to be a little voice in the back of my head assessing how I fit in with the group overall. Am I too girly? Am I talking about emotions too much? Am I just plain talking too much? Do I need to make more effort to be “one of the guys”? Don’t get me wrong: I LOVE hanging out with Drupal developers and the Drupal community. But I find that I’m often watching myself to make sure I don’t rock the boat.

    This presentation blew all that thinking away. Sara Wachter-Boettcher is a speaker, content strategist, and feminist, and she took the stage and started talking unapologetically about feelings.

    Specifically, Sara talked about how the UX we create makes our users feel. When, for example, we ask our users to self-select into pre-determined categories at the beginning of using an app, what does that do to the people who don’t fit into any of the categories we’ve decided on for them? When Facebook rolls out “Year In Review” and grabs your most-liked photo and puts it in the middle of celebrating cartoon characters, what does that do to a person whose most-liked photo was a picture of his six-year-old daughter who died that year?

    Sara explained that so many times, as we sit in a conference room making UX decisions, we dismiss these situations as “edge cases.” Sara said that there’s no such thing as an “edge case” – we should look at these situations as “stress cases,” and do our best to ensure compassion in our digital design for every single user.

    Thoughtless UX is everywhere, and we simply do not know what any given person has gone through or is going through. Every single field in a form could be a potential trigger connecting people to their loss, their grief, their trauma, their anger.

    That was groundbreaking enough, but what really struck me was the examples Sara used. She talked about how the question “Have you ever been sexually assaulted?” on a doctor’s admittance form opened up emotional turmoil for her. She talked about how period-tracking apps disenfranchise women who don’t fit into the app’s strictly-defined demographics. She stood up in front of 3,000 mostly-male mostly-developers and talked honestly and openly about the need for more empathy in what we do every day.

    I would not have had the courage to give that talk in front of that audience. If I was in Sara’s position, I would have been sure that talking about the failings of a period-tracking app would be unprofessional, and that making a plea for more compassion would have been dismissed as too girly. By giving that talk, Sara also spoke to me personally: These things are important, she was saying in the back of my mind; It’s OK to talk about these things.

    I went to the book signing after Sara’s talk to tell her how much it had meant to me. I burbled on as I tried to explain that she had just normalized talking about “girl stuff” in the context of web development, that I felt so much more empowered to talk about the issues that are most important to me regardless of the gender of the audience, that it had been the most powerful feminist experience of my life. To be honest, I think I embarrassed her, but I’m not very good at giving compliments, so that’s not entirely unexpected.

    Sara’s keynote made me feel more empowered to express the entirety of who I am, not just the parts of me that fit in with the Drupal developer crowd, and it was a very powerful gift.

    May 18 2016
    May 18

    As a marketer, a Drupal newbie, and the newest LevelTen employee, I was super excited for DrupalCon.

    Historically, there has not been a lot of overlap between the Drupal world and the marketing world. One one level that makes some sense: companies who need a Drupal web solution are often large enterprise-level organizations who have the resources for an in-house marketing team.

    But it’s clear after my week at DrupalCon 2016 that more and more agencies and web developers are recognizing that they need to offer some kind of content or content strategy services to their clients. Every session that touched on content was packed, with people sitting on the floor or leaning against a wall. It’s clear that the Drupal community is starting to embrace content as a marketing tool, not just a static website component.

    What I Learned at DrupalCon as a Marketer

    Here are the most important things I learned at DrupalCon New Orleans:

    • My “comfortable shoes” are not actually comfortable.
    • If I go to an “advanced” session, I will understand each and every word that is said, but I will not be able to understand any single sentence.
    • I will always and eternally be excited by the prospect of a free t-shirt.

    Whoops, sorry, those were the most unimportant things I learned. Valuable to me, yes, but slightly less valuable to you.

    The truth is that I learned a ton at a bunch of different sessions. I’m going to touch on my three favorite sessions, and then dive into the Tuesday keynote, which I thought was really powerful.

    My Three Favorite Sessions

    Content-Driven UX, by June Parent, Senior Digital Strategist at ImageX, and Bjorn Thomson, Senior Solutions Architect at ImageX

    This was a really great talk on how and why content should come first and then shape everything about your website. The presenters went into a lot of detail and step-by-step instruction on how to do a content audit. They actually presented a “Content-Driven Framework” that I hadn’t seen before – Audience, Messaging, Interaction, Optimization, Distribution, Measurement – that I’m going to use in my next Marketing Strategy Plan. They also claimed that there is really no practical difference between content and UX any more, and by the end of the presentation, I agreed with them.

    Content Strategy in Popular Culture, by Brett Meyer, Chief Strategy Officer at ThinkShout

    This was hands-down the most entertaining session I attended, and the rest of the LevelTen team agreed. Brett Meyer gave us a look at content strategy through the lens of nerd culture: for example, why is Captain America: Civil War so successful, while Batman V. Superman failed by comparison? Because Marvel has tapped into what its users really want, and is delivering more of it – and that’s what we have to do for our clients as well. Similarly, is it okay to repackage and reuse content? Sure, if that’s what your audience wants – just look at The Force Awakens.

    The Ultimate Super Duper Guide to Content Quality, by Courtney Clark, Senior User Experience Designer at Forum One, and Kristina Bjoran, Project Manager & UX Designer at Forum One

    The session delivered on its promise. The presenters worked step-by-step through the components of quality content: Structure, Presentation, Clarity, Keywords, Voice, and Organization. Each section iterated on the same example of content to take it from “meh” to “marvelous”. It was a little surface-level for me, as a full-time content strategist, but a great introduction to the elements of content quality for those who have just started in the field or are just beginning to learn about it.

    The Life-Changing Tuesday Keynote

    DrupalCon New Orleans 2016: Tuesday Keynote: Sara Wachter-Boettcher

    Everybody Hurts: Design for Kindness

    Guys, I was more than a little bit blown away by this keynote. As a female marketer in a place like DrupalCon, which is heavily male and heavily developer-focused, there’s always going to be a little voice in the back of my head assessing how I fit in with the group overall. Am I too girly? Am I talking about emotions too much? Am I just plain talking too much? Do I need to make more effort to be “one of the guys”? Don’t get me wrong: I LOVE hanging out with Drupal developers and the Drupal community. But I find that I’m often watching myself to make sure I don’t rock the boat.

    This presentation blew all that thinking away. Sara Wachter-Boettcher is a speaker, content strategist, and feminist, and she took the stage and started talking unapologetically about feelings.

    Specifically, Sara talked about how the UX we create makes our users feel. When, for example, we ask our users to self-select into pre-determined categories at the beginning of using an app, what does that do to the people who don’t fit into any of the categories we’ve decided on for them? When Facebook rolls out “Year In Review” and grabs your most-liked photo and puts it in the middle of celebrating cartoon characters, what does that do to a person whose most-liked photo was a picture of his six-year-old daughter who died that year?

    Sara explained that so many times, as we sit in a conference room making UX decisions, we dismiss these situations as “edge cases.” Sara said that there’s no such thing as an “edge case” – we should look at these situations as “stress cases,” and do our best to ensure compassion in our digital design for every single user.

    Thoughtless UX is everywhere, and we simply do not know what any given person has gone through or is going through. Every single field in a form could be a potential trigger connecting people to their loss, their grief, their trauma, their anger.

    That was groundbreaking enough, but what really struck me was the examples Sara used. She talked about how the question “Have you ever been sexually assaulted?” on a doctor’s admittance form opened up emotional turmoil for her. She talked about how period-tracking apps disenfranchise women who don’t fit into the app’s strictly-defined demographics. She stood up in front of 3,000 mostly-male mostly-developers and talked honestly and openly about the need for more empathy in what we do every day.

    I would not have had the courage to give that talk in front of that audience. If I was in Sara’s position, I would have been sure that talking about the failings of a period-tracking app would be unprofessional, and that making a plea for more compassion would have been dismissed as too girly. By giving that talk, Sara also spoke to me personally: These things are important, she was saying in the back of my mind; It’s OK to talk about these things.

    I went to the book signing after Sara’s talk to tell her how much it had meant to me. I burbled on as I tried to explain that she had just normalized talking about “girl stuff” in the context of web development, that I felt so much more empowered to talk about the issues that are most important to me regardless of the gender of the audience, that it had been the most powerful feminist experience of my life. To be honest, I think I embarrassed her, but I’m not very good at giving compliments, so that’s not entirely unexpected.

    Sara’s keynote made me feel more empowered to express the entirety of who I am, not just the parts of me that fit in with the Drupal developer crowd, and it was a very powerful gift.

    May 18 2016
    May 18

    As a marketer, a Drupal newbie, and the newest LevelTen employee, I was super excited for DrupalCon.

    Historically, there has not been a lot of overlap between the Drupal world and the marketing world. On one level that makes some sense: companies who need a Drupal web solution are often large enterprise-level organizations who have the resources for an in-house marketing team.

    But it’s clear after my week at DrupalCon 2016 that more and more agencies and web developers are recognizing that they need to offer some kind of content or content strategy services to their clients. Every session that touched on content was packed, with people sitting on the floor or leaning against a wall. It’s clear that the Drupal community is starting to embrace content as a marketing tool, not just a static website component.

    What I Learned at DrupalCon as a Marketer

    Here are the most important things I learned at DrupalCon New Orleans:

    • My “comfortable shoes” are not actually comfortable.
    • If I go to an “advanced” session, I will understand each and every word that is said, but I will not be able to understand any single sentence.
    • I will always and eternally be excited by the prospect of a free t-shirt.

    Whoops, sorry, those were the most unimportant things I learned. Valuable to me, yes, but slightly less valuable to you.

    The truth is that I learned a ton at a bunch of different sessions. I’m going to touch on my three favorite sessions, and then dive into the Tuesday keynote, which I thought was really powerful.

    My Three Favorite Sessions

    Content-Driven UX, by June Parent, Senior Digital Strategist at ImageX, and Bjorn Thomson, Senior Solutions Architect at ImageX

    This was a really great talk on how and why content should come first and then shape everything about your website. The presenters went into a lot of detail and step-by-step instruction on how to do a content audit. They actually presented a “Content-Driven Framework” that I hadn’t seen before – Audience, Messaging, Interaction, Optimization, Distribution, Measurement – that I’m going to use in my next Marketing Strategy Plan. They also claimed that there is really no practical difference between content and UX any more, and by the end of the presentation, I agreed with them.

    Content Strategy in Popular Culture, by Brett Meyer, Chief Strategy Officer at ThinkShout

    This was hands-down the most entertaining session I attended, and the rest of the LevelTen team agreed. Brett Meyer gave us a look at content strategy through the lens of nerd culture: for example, why is Captain America: Civil War so successful, while Batman V. Superman failed by comparison? Because Marvel has tapped into what its users really want, and is delivering more of it – and that’s what we have to do for our clients as well. Similarly, is it okay to repackage and reuse content? Sure, if that’s what your audience wants – just look at The Force Awakens.

    The Ultimate Super Duper Guide to Content Quality, by Courtney Clark, Senior User Experience Designer at Forum One, and Kristina Bjoran, Project Manager & UX Designer at Forum One

    The session delivered on its promise. The presenters worked step-by-step through the components of quality content: Structure, Presentation, Clarity, Keywords, Voice, and Organization. Each section iterated on the same example of content to take it from “meh” to “marvelous”. It was a little surface-level for me, as a full-time content strategist, but a great introduction to the elements of content quality for those who have just started in the field or are just beginning to learn about it.

    The Life-Changing Tuesday Keynote

    DrupalCon New Orleans 2016: Tuesday Keynote: Sara Wachter-Boettcher

    Everybody Hurts: Design for Kindness

    Guys, I was more than a little bit blown away by this keynote. As a female marketer in a place like DrupalCon, which is heavily male and heavily developer-focused, there’s always going to be a little voice in the back of my head assessing how I fit in with the group overall. Am I too girly? Am I talking about emotions too much? Am I just plain talking too much? Do I need to make more effort to be “one of the guys”? Don’t get me wrong: I LOVE hanging out with Drupal developers and the Drupal community. But I find that I’m often watching myself to make sure I don’t rock the boat.

    This presentation blew all that thinking away. Sara Wachter-Boettcher is a speaker, content strategist, and feminist, and she took the stage and started talking unapologetically about feelings.

    Specifically, Sara talked about how the UX we create makes our users feel. When, for example, we ask our users to self-select into pre-determined categories at the beginning of using an app, what does that do to the people who don’t fit into any of the categories we’ve decided on for them? When Facebook rolls out “Year In Review” and grabs your most-liked photo and puts it in the middle of celebrating cartoon characters, what does that do to a person whose most-liked photo was a picture of his six-year-old daughter who died that year?

    Sara explained that so many times, as we sit in a conference room making UX decisions, we dismiss these situations as “edge cases.” Sara said that there’s no such thing as an “edge case” – we should look at these situations as “stress cases,” and do our best to ensure compassion in our digital design for every single user.

    Thoughtless UX is everywhere, and we simply do not know what any given person has gone through or is going through. Every single field in a form could be a potential trigger connecting people to their loss, their grief, their trauma, their anger.

    That was groundbreaking enough, but what really struck me was the examples Sara used. She talked about how the question “Have you ever been sexually assaulted?” on a doctor’s admittance form opened up emotional turmoil for her. She talked about how period-tracking apps disenfranchise women who don’t fit into the app’s strictly-defined demographics. She stood up in front of 3,000 mostly-male mostly-developers and talked honestly and openly about the need for more empathy in what we do every day.

    I would not have had the courage to give that talk in front of that audience. If I was in Sara’s position, I would have been sure that talking about the failings of a period-tracking app would be unprofessional, and that making a plea for more compassion would have been dismissed as too girly. By giving that talk, Sara also spoke to me personally: These things are important, she was saying in the back of my mind; It’s OK to talk about these things.

    I went to the book signing after Sara’s talk to tell her how much it had meant to me. I burbled on as I tried to explain that she had just normalized talking about “girl stuff” in the context of web development, that I felt so much more empowered to talk about the issues that are most important to me regardless of the gender of the audience, that it had been the most powerful feminist experience of my life. To be honest, I think I embarrassed her, but I’m not very good at giving compliments, so that’s not entirely unexpected.

    Sara’s keynote made me feel more empowered to express the entirety of who I am, not just the parts of me that fit in with the Drupal developer crowd, and it was a very powerful gift.

    Check out the rest of our DrupalCon[densed] 2106 series! No matter who you are, we've got your perspective covered.

    May 17 2016
    May 17

    So, you've built your Drupal Commerce site and are now setting up Search. You probably aren't going to use Drupal core's search since it won't give you enough control over what and how search results are returned. You are going to set up your own search server and index using Search API.

    In this example, I am using Solr Search with Acquia Search for Search API. It doesn't matter how you have your index and server set up - as long as you can index your Commerce Products and Product displays, the custom module that I will describe shortly should work. For my setup, I have downloaded and enabled the following modules.

    • Search API - provides a framework for easily creating searches on any entity known to Drupal, using any kind of search engine. 
    • Commerce Search API - provides Commerce-specific Search API integration.
    • Search Views - integrates Search API with Views, enabling users to create views with searches as filters or arguments. This is included as part of the Search API module. 
    • Solr Search - provides a Solr backend for the Search API module.
    • Acquia Search for Search API - allows Search API Solr to connect to the Acquia Search service. It requires the Acquia Connector module and a valid subscription.

    The whats and hows of getting Search API set up on Acquia are described pretty well in Acquia's docs on using the Search API Module so I'm not going to run through them here. I'm also going to assume you've got Commerce Search API set up and that you have successfully indexed your products and any other desired fields associated with your product displays. Commerce Guys have a good screencast on how to set up Commerce Search if you need more help. So, you should see your Server and Index set up at admin/config/search/search_api

    search api index and server

    ​as well as your fully indexed product displays at admin/config/search/search_api/index/product_display:

    drupal commerce product display indexed 

    When editing the product display fields (as provided by the Commerce Search API module at admin/config/search/search_api/index/product_display/fields), you will likely have selected fields such as SKU (in my case, field_pd_sku is the Product Display product reference field):

    drupal commerce product display sku field

    and also how the Commerce Product SKU property relates to the Product display product reference field:

    drupal commerce product display product reference field

    Congrats -  getting this far is a big accomplishment! But let's say that you want users to be able to search SKUs both with and without dashes - not an unreasonable request. Luckily this is pretty easy to implement with a small custom module. This excellent blog post on adding a custom field to Search API Solr index was key to me figuring out how to do this. In this example the custom module is called gls_search (you'll want to change the name to something more appropriate to your project), but I'll assume you're all set on making a custom module in terms of generating the .info and .module files (if not, read this drupal.org document on creating a custom module). In the gls_search.module file, first we will implement a 
    hook_entity_property_info_alter():

    /**
     * Implements hook_entity_property_info_alter().
     */
    function gls_search_entity_property_info_alter(&$info) {
      $info['commerce_product']['properties']['sku_without_dashes'] = array(
        'type' => 'text',
        'label' => t('SKU without dashes'),
        'getter callback' => 'gls_search_sku_without_dashes',
      );
    }
    

    So, what's going on in this function? We are using a hook provided by Entity API to create an additional property of the product display - in this case, sku_without_dashes.  This hook allows modules to alter metadata about entity properties. If you have debugging set up, it can be useful to understanding what exactly this means. Try adding the above hook, and then view the fields that are being indexed in your product display at /admin/config/search/search_api/index/product_display/fields. If you start your debugger, clear cache, and put a break statement in your new function, you'll see the following. Alternatively if you don't have debugging set up, add a dmp($item) using the devel module. This hook is only called when clearing cache as far as I can tell. 

    If you inspect the $info array that we are altering in our function, you will see that the new property, sku_without_dashes has been added at the bottom. This is just metainfo about the commerce_product, so it won't contain the values for the various fields (like title, sku, description etc).

    info array

    If you just added this function alone, you would see that this property has now been added to the list of available fields at admin/config/search/search_api/index/product_display/fields:

    skus without dashes field in search index

    However, there is no data associated with this field - next we need to write the getter callback function to create the SKUs without dashes:

    /**
     * Getter callback for sku_without_dashes property.
     */
    function gls_search_sku_without_dashes($item) {
      // Get SKU for a given product.
      $sku = $item->sku;
    
      // Check to make sure SKU has dashes.
      if (strpos($sku, '-') !== FALSE) {
        // Cleanup SKU to remove dashes.
        $sku_without_dashes = preg_replace('/-/', '', $sku);
        // Return SKU without dashes.
        return $sku_without_dashes;
      } // If SKU doesn't contain dashes, return original SKU.
      else {
        return $sku;
      }
    }
    

    I hope the comments clarify what is going on here, but I'll walk through the individual steps quickly. First, we will use the information that is contained in the $info array to access our SKU:

    // Get SKU for a given product.
    $sku = $item->sku;
    

    Next we make sure we are only doing this if the SKU already has dashes - if it doesn't have dashes, we will get an error. The strpos PHP function finds the first position of a character in a given string. This function returns FALSE if the character isn't found, so that's why we want to check to make sure there is a dash. 

    // Check to make sure SKU has dashes.
    if (strpos($sku, '-') !== FALSE) {
    

    So, if a dash is found, we will look through the SKU and remove all occurences of the dash using the PHP function preg_replace. This function performs a regex search and replaces any found occurrences, but in our case it's very simple since we are only looking for a '-'. 

    // Cleanup SKU to remove dashes.
    $sku_without_dashes = preg_replace('/-/', '', $sku);
    

    We'll then return our SKU without dashes now that we have reformatted the SKU. 

    // Return SKU without dashes.
    return $sku_without_dashes;
    

    Finally, we will return the unaltered SKU if no dashes were found in the first place. 

    } // If SKU doesn't contain dashes, return original SKU.
    else {
      return $sku;
    }
    

    OK, now we need to add this field to our search index, and set it to Fulltext. Once you have done this, you will need to re-index your site to include this new field. Then try searching with and without a dash in the same SKU - hopefully it works for you.

    add sku without dashes field to search index

    May 12 2016
    May 12
    Felipa Villegas is the Marketing Coordinator at LevelTen Interactive. A writer by trade, Felipa loves to make the written word work by delivering high quality, engaging content to audiences. She leads the LevelTen marketing team in executing demand generation, SEO, Analytic Data Mining and Copy...Read More >>
    May 10 2016
    May 10
    Felipa Villegas is the Marketing Coordinator at LevelTen Interactive. A writer by trade, Felipa loves to make the written word work by delivering high quality, engaging content to audiences. She leads the LevelTen marketing team in executing demand generation, SEO, Analytic Data Mining and Copy...Read More >>
    Apr 06 2016
    Apr 06

    If you were at the first-ever statewide DrupalCamp in Texas this weekend, that's awesome! As part of the team that helped organize this camp, I loved what we were able to accomplish. We organized TexasCamp to bring together the Drupal community from all over the state of Texas to teach, learn, connect, and collaborate.

    It was all Drupal everything, especially in the week leading up to the event! As part of the team, we spent months of planning and finding the right venue (only to have to change it a month before the camp). The logistics that went into planning an event this large was enough to drive us a little insane. 

    I don't think I've ever spent so much time with my co-workers as I did last week, but it was worth it. We put together an event that was meaningful and helpful to all of those that believe in Drupal and the Open Source community. 

    Kendall Westbrook, or Kwest as we like to call her, was the genius behind booking Michael Meyers, VP of Developer Relations for Acquia. If you didn't catch his keynote, you can watch it below. His keynote speech was pretty inspiring and gave everyone on the team validation on why being involved and contributing back to the Drupal community is important. 

    [embedded content]

    Instead of posting endless pictures here on the blog documenting what happened at TexasCamp, you can look through the Flickr slideshow below. 

    TexasCamp 2016

    We'll let you all in on a little secret: talks of TexasCamp 2017 are already happening. Can't wait for next year to see all the Drupal Nerds come together again! In the meantime, we'll see you all at DrupalCon New Orleans in May!

    Mar 24 2016
    Mar 24

    An alphabetical list of tags is one great way to organize content for a large website with lots of nodes that are tagged with taxonomy terms. In Drupal, this is also referred to as a 'glossary' type view. This is particularly useful for an e-commerce site where someone might want to browse an alphabetical list of manufacturers, or look through an alphabetical list of product categories. 

    For a better idea of what I'm talking about, here is what we are going to build in this tutorial:

    what we're going to build

    The Views module for Drupal comes out-of-the-box with a glossary view - check it out at admin/structure/views and search for Glossary (it's disabled by default). If you edit this view, you can see that it's a not-so-pretty list of all content, organized alphabetically. 

    We are going to take the basic idea of this view and extend it to our taxonomy. We'll also group the taxonomy terms by the first letter to make the page prettier. This tutorial assumes that you already have your taxonomy set up with your terms, and that you've tagged your nodes with the appropriate terms. 

    1. Create a new view

    Add a new view at admin/structure/views/add. We'll just call it A-Z list of terms. We will be showing taxonomy terms of type 'phapro' (this is taxonomy created by Devel generate - just select your desired taxonomy here). We'll also want to create a page - give it a title and path, and tell it do display in Grid format. Enter '0' for the number of terms to display - this will then display all terms. I've also created a menu link so it will be easier to find while we're working on it. When you've got it set up the way you'd like, hit Continue & edit. 

    2. Group terms alphabetically

    To group the terms alphabetically in nice tables, we first need to create a list of taxonomy terms that shows only the first letter of the terms. We will use this list to group the terms nicely in tables where each table only lists terms that start with that letter of the alphabet. First, add a field: Taxonomy term:name.

    Give it a nice label for now (we will remove this label later). Otherwise it will get confusing since we have two fields that are using the same information. I've called it 'Grouping' since that's all we're going to use it for. Make sure to Exclude from display. 

    Under rewrite results, trim to a maximum length of 1, and uncheck 'trim on word boundary' and 'add ellipsis'. 

    Now we can use this field to group our terms into tables where each table lists all terms that start with that letter of the alphabet. Under Format Grid - Settings, select Grouping Field 'Grouping' or whatever you named your new field that only displays the first letter of the taxonomy term. Apply to all displays.

    Now you should see that your terms have been nicely grouped by the first letter.

    grouped terms

    3. Create a Views page for each letter of the alphabet

    We also want to build a page that displays all taxonomy terms that begin with any given letter of the alphabet, with a path something like this: http://[my site].com/a-z-list-of-terms/[letter of the alphabet]. Thankfully Views will take care of this for us using the power of contextual filters. Contextual filters take information from the path and use it to filter the view, which is exactly what we want - we want views to take the [letter of the alphabet] from the path and use it to filter taxonomy terms by that letter. Under Advanced, add a Contextual Filter: Taxonomy term: Name. When the filter value is not in the URL, leave it as Display all results - we don't want Views to do any filtering if there is no [letter of the alphabet] in the path.

    filter not in url

    Under More, select Glossary Mode, and Character limit 1. Apply. 

    contextual filter glossary mode

    4. Create A-Z list

    Next we're going to create a block that will display the list of first letters in a cute list above the grouping grids. This will allow users to click on any given letter and be brought to a page that lists all terms that start with this letter (these are the pages we just built using a contextual filter in step 3). 

    Add a block to your view. Under Advanced, add a Contextual Filter (edit: if there already is a Contextual filter listed for your views block that was carried over from the views page we just created, delete the contextual filter from your views block. We are going to make a new one now).  For all of the work on this block, be sure you have For This block(override) selected, as we don't want/need to add this to the page we just finished building. 

    apply to this block only

    Select Taxonomy term: Name, and Apply (this display). When the filter value is not available, you'll want to 'display a summary', sorted by alphabetical, unformatted, and display items inline. It's up to you if you want to display the record count with link. I think it looks cleaner without the record count. With the record count you'll get something like A (1) B (2) C (10). This is telling Views that when there is nothing to filter by (ie, there is nothing in the path that relates to the taxonomy term alphabetical listing) display a summary of all results. 

    filter not available

    Scroll down past this once you're done and then also Specify Validation criteria under 'When the filter value is available' and select the basic validator, hide view. 

    filter available

    Lastly, expand the More section, and select Glossary mode, character limit 1, Case (Upper case), and Case in path (Lower case). Here we are just telling the glossary mode to limit to the first letter of our term. If we didn't do this, our listing would look something like this (which we don't want, we just want the alphabet):

    without glossary mode

    Make the listing uppercase (so it will be a list like A B C E G etc, rather than a b c e g). For the path, make it lowercase, since it's fairly standard to keep paths all lowercase. Apply.

    glossary mode more

    Now we should have a partial list of the alphabet. Note it's only displaying part of the alphabet since our taxonomy doesn't have terms that start with every letter of the alphabet. 

    alphabetical list

    5. Add the alphabetical list to the page with alphabetically grouped terms

    Now we just want to embed our alphabetical list on our page with the grouped terms so people can click on any given letter to be brought to a page that only lists terms starting with that letter. Go back to our Views Page display, and click the Add button for Header.  

    views page and block

    Select Global: View area, and Apply (this display).

    add header to view

    Select the View Block that we created in step 4 and Apply.

    insert view

    We should now see in our View preview the alphabetical listing as well as the grids of terms listed by letter. Save and check the view out on your site. 

    view glossary page

    The last thing you'll probably want to do is remove the 'Grouping: b' from each of the grids. We did this, so it was easy to distinguish the 2 Views fields that were the same. Edit the view and then edit the Taxonomy term: Name (Grouping). Uncheck the Create a label box, and then Apply. You'll see your terms are now grouped only by one letter of the alphabet, but you'll also see why it could be confusing to set up the View initially if there wasn't a label to distinguish the two fields from each other in the view configuration.

     remove label 

    (Confusing):

    fields with same name

    6. Enjoy

    Explore your page a little bit if you want a better understanding of why we set up the View the way we did. 

    If you click on any given taxonomy term, you will be brought to a page that lists all nodes tagged with that term.  This is default Drupal behavior, and comes from the fact that in the view for our Taxonomy term field, we have selected 'link this field to its taxonomy term page'. 

    taxonomy term page

    If you click on any letter that is displayed in the block at the top of our view, you will be brought to a page that lists only taxonomy terms that start with that letter of the alphabet. Check out the path here - http://[my site/a-z-list-of-terms/[letter of alphabet]. This page is built from the Views Page we created where we added a contextual filter that used the Glossary mode. 

    glossary page

    Hope this was helpful!

    Feb 04 2016
    Feb 04

    LevelTen Interactive is proud to present TexasCamp 2016 on April 1 - 2 at the Fort Work in Dallas, Texas.

    TexasCamp is two days of DrupalCamp, intended for Drupal admins and users, sitebuilders, themers and developers. Expect sessions from beginner to expert level, with the brightest minds in the Drupal world attending and presenting.

    You can attend TexasCamp for only $50! Or become an Individual Sponsor for just $75!

    Buy A Ticket

    Coming to the camp from out of town?

    Make time in your schedule for the after party on Saturday night, which will feature networking opportunities and great entertainment.

    Want to submit a session?

    In order to submit a session, you have to have bought a ticket and registered on the TexasCamp website. 

    The deadline for submitting a session is March 14, 2016!

    We can't wait to see you at the first ever statewide DrupalCamp in Texas! Help us reach our goal to have a successful Drupal community event.

    For more information visit the texascamp.org website.

    Follow our social media channels:

    Twitter:
    @DrupalTexasCamp

    Facebook:
    TexasCamp

    Jan 06 2016
    Jan 06

    It’s really early into the New Year, but there are plenty of events in the Drupal Community that have already been scheduled for 2016. If you are new to Drupal, these camps are a great way to engage with the community and learn more.

    Drupal is an open-source content management system that powers more and more of the web every year. The White House, Stanford, Yale, House of Representatives, Weather.com and many other high-performing traffic heavy websites are delivered through Drupal. 

    GLADCamp 2016 (Greater Los Angeles Drupal Camp)

    January 21st, 2016 - https://gladcamp.org 

    DrupalCamp NJ 2016

    January 29th, 2016 - https://www.drupalcampnj.org

    SANDcamp 2016

    February 24th-27th, 2016 - http://sandcamp.org

    DrupalCampNYC 2016

    February 27, 2016 - https://www.eventbrite.com/e/drupalcampnyc2016-registration-19937683147

    Drupal Camp Utah 2016

    March 4th- 5th 2016 - https://2016.drupalutah.org

    Florida DrupalCamp 2016

    March 5th, 2016 - https://www.fldrupal.camp

    MidCamp 2016

    March 17th-20th, 2016 - http://2016.midcamp.org

    TexasCamp 2016

    April 1st-2nd, 2016 - http://texascamp.org

    You might recognize some of the annual camps above, but one you might notice is fairly new. That is because LevelTen decided to put together the first ever Texascamp 2016 on April 1st-2nd, 2016. The location will be at the Addison Conference and Theatre Centre.

    More information will be made available in late January 2016. If you have any questions about sponsoring or call for papers, please email us at [email protected]. We hope to make TexasCamp a successful Drupal Camp.

    Oct 28 2015
    Oct 28

    In my 'spare time,' I manage and moderate a fairly large community of people who are traveling (by car, truck, motorhome, or motorcycle) North, Central, and South America. Powered by Drupal, of course, the site works as a wiki in addition to having active forums. We strive to make the website as open as possible. Unfortunately, we were having a hard time finding a good balance between protecting the forums, comments, and wiki-type pages from advertisers and related spammers, and locking down the site so user registration took too long. Eventually we settled on manual approval of new user accounts. As administrators, we could make a highly educated guess about whether or a not a new user's account was legit based on a field we added to the user registration form. The field asked new users to 'Tell us about your trip' - people who wrote 'I'm driving a Toyota Tacoma from Seattle to Argentina' were clearly legit. New users who wrote 'I think it's great' were real people trying to sneak their way in so they could start spamming. The problem is that when I go on vacation or forget to check the website, the new user registrations pile up. Most people have an expectation that after creating a new account on a website they will be able to use that site pretty quickly. We didn't want to lose users because of a delay in their registration. 

    Isn't Spam already solved for Drupal? (Not really)

    Drupal has an exhaustive list of all of the anti-spam modules that are already available, but none of them looked like they were going to solve our problem. These modules are grouped into several categories:

    • CAPTCHA / Honeypot - Our website already had Mollom working to catch spambots 
    • Content Focused Modules - While maintaining fairly open user registration, we wanted to catch spam users before they started to general spam content
    • User Focused Modules - Email validation and other similar modules were failing because very persistent trolls and spammers would actually spend the time to validate their email addresses and then spam away. Also, IP-based modules weren't the greatest since we are a website that does attract a very global audience. 

    It's possible that some combination of these modules would have solved the problem we were having with advertisers and spammers trolling our forums and comments. However, I thought I would use this as a learning process for me to finally get around to developing my own custom Drupal module from scratch. I envisioned a system where trusted users can upvote or downvote new users who haven't yet been approved. If a new user receives enough votes from the community, their status would be moved from blocked to active, and they could proceed with the forums, comments, and wiki-type edits. This would take the pressure of site administrators to go through the list of users awaiting approval. 

    desired solution to our spam problem

    First I laid out the general scenario and how I wanted to solve this problem:

    A. User Registration:

    1. A new user registers for an account and they are set to ‘blocked’.
    2. The system adds the new user to the list of users that have to be approved (what we will refer to as the approval queue).

    B. Administrative Tasks:

    1. Administrator can view the approval queue and either upvote or downvote the users. 
    2. Administrator can set the number of votes (X) required to either approve the new user or leave them blocked as spammers. 
    3. Administrator can select the field displayed on the user registration form that they want to display to people when they are voting to help them decide if the user is legit or a spammer (in our case, 'Tell us about your trip). 
    4. Administrator can vote new users up or down.  If the admin votes ‘real person’ the system records 1 up-vote. If the admin votes ‘spammer’, the system records 1 down-vote.
    5. If a new user receives X up-votes, their account is moved from blocked to active. If a user receives X down-votes, the user is removed from the list of users that have to be approved. Either way, after receive X votes the new user is removed from the approval queue. 

    C. User Approval:

    1. When a trusted user logs into the system they are displayed information about a new user awaiting approval (displays ‘tell us about yourself’ field for the user awaiting approval).
    2. The logged in user can either indicate that they think the new user awaiting approval is a real person or a spammer. If they say ‘real person’ the system records 1 up-vote. If the trusted user votes ‘spammer’ the system records 1 down-vote.
    3. If a new user receives X up-votes, their account is moved from blocked to active. If a user receives X down-votes, the user is removed from the list of users that have to be approved. Either way, after receive X votes the new user is removed from the approval queue. 

    Ways to approach this

    There were a bunch of different approaches I considered when thinking through how to achieve this setup. I looked at the Entityqueue module, but it seemed like it would be simple to make a table of users to store the 'approval queue' I imagined, rather than work with the Entity API and EntityQueue contributed module. I also thought I could use some combination or Rules, Actions, and Triggers, but again once I started fooling with these, it seemed like I was going to write a lot of custom code to hook into those. I thought it would be simpler and more lightweight to use Drupal's core hooks. I also considered using the Voting API, but this seemed a little heavy for what I hoped to keep a fairly simple solution. Of course there are a million possible ways to skin this cat, but since I was also looking to use this as a learning experience, I decided to build from the ground up. 

    How I built a Community User moderation module

    The sandbox user moderation project is available on Drupal.org if you want to try it out yourself, but I'll walk you through the hooks and concepts I used to build my custom user moderation module. 

    Step A-1: Set new users to 'blocked' on registration

    Easy, handled already through Drupal core User settings (admin/config/people/accounts) and Login Toboggan (admin/config/system/logintoboggan). Visitors can register for accounts but administrator approval is required.

    Step A-2: Add new user to approval queue on registration

    In the user_moderation.install file, I used hook_schema() to create a simple {user_moderation} table that stores user IDs, upvotes, and downvotes. Using hook_user_insert() the new user is added to the {user_moderation} table when they register for an account. 

    Step B-1: Administrator can view the approval queue

    Hook_menu() to create the administrative link with a page callback to build a page that has the table listing all users in the approval queue, their user ID, their 'tell me about yourself entry' and how many upvotes and downvotes they have received. Much of this code was inspired by the Examples Tablesort Example module. 

    drupal user moderation custom module

    Steps B-2 and B-3: Administrator can set number of votes required and field to display to voters

    Hook_menu() to create the administrative link with a page callback to drupal_get_form() to build the settings form. I used Drupal's handy variable_get() and variable_set() (and of course variable_del() in the user_moderation.install file) to set the number of votes (the cutoff value) required to either approve a user or remove them from the approval queue (and leave them in the 'blocked' state). I then used field_info_instances() to get an array of custom user registration fields to select from on the administrative screen. A quick validation function just checks to make sure the administrator has entered an integer greater than 0 for the number of votes field. 

    drupal custom module configuration page

    Step B-4 and B-5: Administrator can vote new users up or down

    This may not be totally needed, but I thought for testing purposes it would be easiest to build the voting functionality into the administrator's table. Once I got the voting working, it would then be easy to extend this into a block for trusted users to vote. 

    Within the administrative user moderation table, I created links that were 'user-moderation/%/%', where the first argument is the user ID, and the second argument is either 'upvote' or 'downvote'. I then used a hook_menu() for the path 'user-moderation/%/%' and passed those page arguments into page callback that was my custom voting function, user_moderation_vote(). I retrieved the votes variable set by the administrator, and then the logic is as follows:

    If the user receives a downvote, add 1 to the downvotes column in the {user_moderation} table, or remove the user from the {user_moderation} table if they've received more than the cutoff number of votes. So first check to see how many votes they have, and if they've hit the cutoff, remove them from the approval queue and you're done. If they haven't hit the cutoff, give them another downvote. The logic works the same for upvotes. If the user receives an upvote, add one to the upvotes column in the {user_moderation} table or remove the user from the approval queue if they've received more than the cutoff number of votes. The only difference here is that after checking to see if the user has hit the cutoff number of upvotes, in addition to removing them from the approval queue, use the user_save() function to move their account from 'blocked to 'active'.

    Step C-1: Trusted users are displayed information about blocked users awaiting approval

    I created a block using hook_block_info() and hook_block_view() to display the 'tell us about your trip' field (selected in the configuration options for this custom module), as well as links to upvote or downvote the user. These block functions contain a callback that gets the first user in the approval queue, and displays only that user's information. 

    drupal user moderation custom module voting block

    Some Additional UX Improvements

    To make this as unobtrusive as possible, I used AJAX for the voting in the block, and JQuery to hide the block after the user has voted, so they aren't always being asked to vote as they traverse the site. (The Examples module AJAX example was instrumental for this). I also set a cookie when the user votes so the trusted user will only be displayed this block again after they have closed their browser. 

    I'm going to try this module out on Drive the Americas this week once I've done some final proofreading - hopefully; this will take pressure off me, as the main site administrator, when it comes to approving new users. We'll see! 

    You can download view the sandbox User Moderation project at https://www.drupal.org/sandbox/kristin.brinner/2595185.

    Sep 25 2015
    Sep 25

    Dries Buytaert, founder of Drupal, gave a keynote address at DrupalCon in Barcelona on September 22, 2015.  He answered what he called “three uncomfortable questions” about the state and future of Drupal, and announced that the long-awaited release of Drupal 8 is imminent, planned for October 7, 2015. The speech is available online, however, we've made it easier on you, with the following summary notes on DriesNote:

    Is Drupal losing momentum? 

    Basically, yes, but it will get it back.  Users are waiting for the release of Drupal 8, as it has been 5 years since the release of Drupal 7.

    • The Obsborne Effect:  the announcement of a coming new release slows adoption of the current version.  When the new release comes out, a significant spike is expected, as occurred when Drupal 7 was released in 2010.
    • Release of Drupal 8 has taken years longer than expected due to work simply not going as planned.  Unplanned and abandoned work slows the process.  Dries stated, “We can only go as fast as our slowest feature.”
    • Drupal 8 is getting more stable with 15,000+ patches contributed by 3,000+ contributors, and 1,300+ critical bugs resolved.  The last feature to complete is Twig, so Drupal 8 release is planned for October 7, if no new critical issues are discovered.

    “We will fix the way we work.” 

    1. Create feature branches, and break-up feature branches.

    2. Only merge branches when they are shippable, so that the main branch is always shippable.

    3. Date-based releases will enable Drupal to be released even if every feature is not ready.  Features and patches can be added into later releases.

    4. Cross-functional teams improve continuity and follow-through.

    5. Core committers and leadership will take on the role of orchestrating and prioritizing merges.

    Can Drupal compete?

    Yes!  People are concerned with growth and feature development of WordPress.  However, Drupal and WordPress can’t be compared, as they serve different audiences.  There are also many other rising competitors.

    • Drupal is dominant for larger, more complex websites.
    • Drupal is advanced in its ability to scale and content modeling tools.
    • Drupal focuses on the developer.
    • To improve the User Experience (UX), Drupal needs to:
    1. Focus on the non-coders: builders, authors, and editors.

    2. Improve the UX, making it easier to use and more seamless.

    3. Let people test the UX throughout the development process, at several points prior to release.

    4. Focus on the 80% of the world that does not use a content management system, and convince them that Drupal is right for them.

    “We’re in a good position, but we still need to get better at UX.  If we do, there’s a big upside.”

    Is Drupal technologically relevant?

    Are frameworks a threat, and how should Drupal respond to them?

    • With traditional CMS (Drupal) a UI provides content to the server, which builds the layout, adds the content, and sends it to the client.  Advantages of traditional CMS include:
      • Editorial tools, such as toolbar, preview, page layout, and edit-in-place.
      • Faster performance with BigPipe.
    • With client-side apps (Backbone.js, AngularJS, React, Ember) which are gaining popularity, decoupling occurs, so the app renders the layout and requests content from the server.  Advantages of client-side apps include:
      • Optimistic feedback.
      • Non-blocking user interfaces.
      • Application-like experience.
    • Progressive decoupling (which will be a part of Drupal 8) can achieve the advantages of both traditional CMS and client-side apps.
      • Drupal sends the layout and maintains layout tools.
      • Drupal bundles some of the more cacheable content with the layout, sending the fast content first.
      • The app requests more content.

    Drupal 8 offers the options of traditional, progressive decoupling through page-building tools, and decoupled by feeding Drupal data to client-side apps.

    Problem: REST APIs in Drupal 8 require multiple round-trips, and  developers lack control over the amount of data collected, resulting in a poor developer experience.

    Solution in-progress:  GraphiQL, an alternative to REST, allows one API call for only the specific data desired.  This results in a better developer experience for query building.

    Progressive decoupling and GraphiQL put Drupal ahead of competitors.

    Takeaways:

    1. Drupal 8 needs to be released, and momentum will come.
    2. Drupal needs to move to a more sustainable development and release process.
    3. Drupal needs to put non-coders first to increase impact.
    4. Drupal will be the go-to platform for sites and apps.

    What did you think of Dries Buytaert’s talk?  What do you think about the changes coming with Drupal 8?  What features do you hope to see developed?

    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