Jun 28 2018
Jun 28

Distributed systems face incredible challenges — Photo by Dennis van Zuijlekom

With Drupal 8 reaching its maturity and coupling/decoupling from other services — including itself — we have an increasing demand for Drupal sites to shine and make engaged teams thrive with good DevOps practices and resilient Infrastructure. All that done in the biggest Distributed System ever created by humans: the Internet. The biggest challenges of any distributed system are heterogeneity of systems and clients, transparency to the end user, openness to other systems, concurrency to support many users simultaneously, security, scalability on the fly and failure handling in a graceful way. Are we there yet?

We envision, in the DevOps + Infrastructure track, to see solutions from the smallest containers that can grow to millions of services to best practices in the DevOps world that accomplish very specific tasks to support Drupal and teams working on it and save precious human time, by reducing repetitive and automatable tasks.

Questions about container orchestration, virtualization and cloud infrastructure arise every day and we expect answers to come in the track sessions to deal with automation and scaling faster — maybe using applied machine learning or some other forms of prediction or self management. See? We’re really into saving time, by using technology to assist us.

We clearly don’t manage our sites in the same way we did years ago, due to increased complexity of what we manage and how we are managing change in process and culture, therefore it’s our goal at Drupal Europe to bring the best ideas, stories and lessons learned from each industry into the room and share them with the community.

What’s your story?

How is your platform scaling? How do you solve automated testing and continuous integrations? How do you keep your team’s happiness with feature velocity and still maintain a healthy platform? How do you make your website’s perceived performance even faster? What chain of tooling is running behind the scenes and what is controlling this chain? Are you using agentless configuration management or are you resorting to an agent. Are you triggering events based on system changes or do you work with command and control.

Be ready to raise, receive and answer some hard questions and but most of all, inspire people to think from a different angle. What works for a high-high traffic website might not be applicable for maintaining a massive amount of smaller sites. We want operations to inspire development on reliability and for development to inspire operations on any kind of automation. We want security to be always top of mind while still have an impact on business value rapidly and efficiently. And that is just the beginning…

About industry tracks

Drupal Europe’s 2018 program is focused on industry verticals, which means there are tons of subjects to discuss therefore when you submit your session be sure to choose the correct industry track in order to increase the chance of your session being selected.

Please help us to spread the word about this awesome conference. Our hashtag is #drupaleurope.

To recommend speakers or topics please get in touch at [email protected].

About the Drupal Europe Conference

Drupal is one of the leading open source technologies empowering digital solutions in the government space around the world.

Drupal Europe 2018 brings over 2,000 creators, innovators, and users of digital technologies from all over Europe and the rest of the world together for three days of intense and inspiring interaction.

Location & Dates

Drupal Europe will be held in Darmstadtium in Darmstadt, Germany — which has a direct connection to Frankfurt International Airport. Drupal Europe will take place 10–14 September 2018 with Drupal contribution opportunities every day. Keynotes, sessions, workshops and BoFs will be from Tuesday to Thursday.

Drupalcon Nashville — Photo by Amazee Labs

Jun 20 2018
Jun 20
Jeff Geerling @flickr

With Drupal 8 core now in full swing and the contrib space rapidly maturing, it is an excellent time to get more deeply involved with one of the world’s largest open-source development communities. The Drupal + Technology track is focused on educating developers on the latest techniques and tools for increasing the quality and efficiency of their projects.

The Drupal + Technology track is the place for Drupal experts actively working on and contributing to Drupal to share their knowledge and help attendees to grow their Drupal skills.

We expect deeply technical sessions that inspire developers to see what is possible with Drupal. We welcome sessions sharing knowledge about integrating Drupal with bleeding-edge technologies (blockchain, IoT, decoupled frontend, etc) to empower the audience to create amazing digital experiences.

This year, the Drupal Europe program is designed around the idea of industry verticals with sessions and workshops based on specific industries. We expect a huge amount of session submissions in the Drupal + Technology track and would kindly advise you to look if an industry track could be more appropriate for your talk to have a better chance of being accepted.

Be ready to sharpen your skills and connect with other tech-minded folks. Convince your boss to invest in your skills, and get you a regular Drupal Europe ticket before they increase in price on 12th of August.

There will also be plenty of contribution opportunities during the event. All expertises and energy levels are equally invited!

Susanne Coates @flickr

Location & Dates

The deadline for the call for papers is 30th of June. Share your skills and empower other developers at the Drupal + Technology track. Submit your session now!

About Drupal Europe 2018

Drupal Europe will be held in Darmstadtium in Darmstadt, Germany — with a 15 min direct connection to Frankfurt International Airport. Drupal Europe will take place 10–14 September 2018 and will bring over 2,000 creators, innovators, and users of digital technologies from all over Europe and the rest of the world together for three days of intense and inspiring interaction.

Oct 02 2017
Oct 02

Working in the charity sector you learn to be pretty resourceful when you need to be, and that doesn’t stop at blagging free stuff (obviously we never do that ;)).

One of the most significant things we learnt from amalgamating our campaign sites onto a single platform was the efficiency that emerged from reusing code and functionality.

So when our Schools and Youth team approached us with an objective that was new to all of us we did what anyone else would do, look at what we’d done already and could copy!

The objective

Noses! 

Red Noses to be precise. We’ve just launched our first ever ‘Design a Red Nose’ competition for schools where students between 4 and 18 can draw their own Nose design with a chance of getting their masterpiece as one of the final nine Noses made for the next Red Nose Day in 2019. Yes, it’s pretty exciting stuff and we’ve had more than a few disgruntled members of staff annoyed at the fact that they’re no longer schoolchildren.

To build the entry functionality, we needed a simple and efficient solution for teachers and school staff to be able to upload their students’ entries.

I thought about various online forms we’d created in the past and whether we could repurpose those to add an image upload mechanism.

Then my somewhat genius colleague Caroline – whom you might know from blogs such as Optimistic about our future of optimisation and How ‘going live’ became my mental blogger –  completely flipped it on its head and suggested a piece of functionality we’d used for past Sport Relief and Red Nose Day campaigns – our fundraiser gallery. This was used for our fundraisers to upload photos of themselves doing the weird and wonderful things people do for Comic Relief.

It seemed like the perfect solution and – spoiler alert – eventually it was, but obviously there were a few creases to iron out first. I won’t bore you with the details, no one likes ironing, but in short we had to:

  • Add an online form to the current functionality
  • Adapt the existing validations to fit other file sizes and formats like pdf
  • Ensure the designs being uploaded had somewhere to go and that we could get to them!
  • Ensure the data in the online form was sent to a secure and integrated database we could access
  • Integrate a schools address look-up used for schools-related forms

So we managed to get the form up and running (despite a few niggles that came up in QA, a few grumbles that came up with the changing the validations and error messages and a couple of gripes when we tried to link the form to our CRM database) – hurrah!

Lessons learned

There were lots of elements to this upcycling process: numerous parties that needed to be consulted, from data and legal, to tech and design; finding and implementing a solution in six weeks (while working on other products with clashing launch dates) and; testing and ensuring a simple user journey.

So, what nuggets of wisdom can I pass on to anyone else about to attack the same kind of problem?

  1. Communicate! Regular stand-ups made sure all teams were on the same page at all times, and allowed us to work quickly.
  2. Upcycle! Look at what you’ve used before and how you can adapt and iterate to get to your end goal more quickly. Also, think about how you might use it again – we’ve already planned our next iteration!
  3. Trust and collaboration! We reached a solution smoothly and efficiently because our stakeholders came to us with the problem. By being descriptive to our dev team of what was needed rather than prescriptive about what they should build, our team ended up building the best thing!
  4. Focus! It’s easier said than done but where you can get teams to focus on one thing at a time, it’s efficient, productive and keeps people a lot happier!

Share this:

Like this:

Like Loading...
Jan 31 2017
Jan 31

Drupal Global Sprint Weekend, which took place last weekend sees Drupal developers from around the world come together to contribute to the open source content management system’s codebase. On Saturday, in London, we took the opportunity to give back to the Drupal community by hosting a sprint at the Manifesto studio.

Wait, what’s a Drupal sprint?

For those who don’t know what a code sprint is, here’s a good definition taken directly from the Drupal website:

A code sprint is getting developers for a set amount of time
– usually one to two days – and just writing code. That’s it.

You’re not teaching anything. Participants will learn from others as they go,
but the focus is not on instruction. The goal is to create working software.

Essentially we just made some time and space for Drupal developers to work on outstanding issues for Drupal core or its most popular modules. But there was also room for Drupal newcomers to get to grips with the CMS and work towards becoming core contributors by completing the lessons in the Drupal Ladder.

So, in effect, we were running both an Issue Sprint and a Learn Sprint.

What did we achieve?

We are quite proud to say that our first experience of running a Drupal sprint was an amazing success:

  • There were 10 participants, 6 of whom were first time contributors;
  • We had Drupal Ladder and Sprint areas running simultaneously;
  • We consumed 3 pots of coffee, 15 bags of tea, 5 cans of Coke and 10 pizzas during the day;
  • Our concentration was interrupted just once (apart from the lunch break) by a 15-minute hailstorm;
  • We worked on 17 Issues during the day, 3 of which are RTBC (Reviewed and Tested by the Community) and 1 is Fixed (to be honest it was already fixed, we just flagged it).

lunch at Drupal Global Sprint Weekend, London 2017

All issues are tracked on the Drupal website. If you look for just those with the SprintWeekend2017 tag, you’ll see that out of the 188 issues tackled over the whole weekend, worldwide, we worked on almost 10% of them!

What’s next?

In the Issue Sprint area we tried to focus on experimental modules like Workflow, Content Moderation and Datetime Range as these need to be stable before Drupal 8.4.0-beta1 (in six months), while the guys in the Drupal Ladder room tackled some ‘Novice’ issues.

Each and every attendee left the studio asking when the next Sprint would be – which makes us feel over the moon! Giving back to Drupal is important, easy and fun, so our prompt answer was always ‘Very soon!

Many thanks to everyone who participated and supported. If you’d like to stay informed about future Drupal sprints at Manifesto, please sign up for our newsletter.

Jul 28 2016
Jul 28

This Drupal cache case study began on a pleasant January afternoon in beautiful Goa. The entire company flew in for our annual retreat, enjoying the scenic beauty of the sandy beaches and the cool breeze. Between the fun times, we were ducking into our remote workspace, poring over a cachegrind report sent over by our client.

This report was generated for ajax responses coming from a product page on an e-commerce website. We could clearly see that the page was extremely slow to render and that this was true for all ajax responses.

The Cachegrind report as sent by the client - Drupal Cache: A Case StudyThe Cachegrind report as sent by the client – Drupal Cache: A Case Study

Progressive Doping

Digging deeper to figure out what was causing the performance bottleneck, we use XDebug to generate cachegrind files, which we could then analyze to determine what functions were costing us the most, or where there were functional paths that could be truncated via caching. Performing this process iteratively we came up with a list of major pain areas. This list was very specific to our project.

  1. Function “get nid from product_id” was being frequently called with a resulting resource consuming data query.
  2. Function “hook_commerce_checkout_pane_info_alter” was being executing on each request.
  3. Product filtering for a particular type of user was a resource consuming activity
  4. Function “get product_id matching attributes” was being frequently called, with a resulting resource consuming query.
  5. The theme function “theme_extra_bundles_radio” was processing some resource consuming business logic.
  6. A lot of calls were made to the “entity_load” function.

Drupal Cache

It is a widely accepted fact that as great as the Drupal 7 core can be, it doesn’t scale well for web sites with a lot of content and a lot of users. To extract the best performance under such scenarios, it’s necessary to make use of several strategies, tools, and techniques. Keeping this in mind, we settled down with the following strategies:

  • Basic Drupal caching:

Drupal offers basic performance settings at:

Administration > Configuration > Performance > Development > Performance (admin/config/development/performance)

Here we enabled block and page caching which cached the dynamic complex SQL queries of Drupal for quick retrieval of content. We also enabled the Compress cached pages, Aggregate and compress CSS files and Aggregate JavaScript files which further helped in bandwidth optimization by reducing the number of HTTP calls.

Lineup/Dealership cache - Drupal Cache: A Case StudyLineup/Dealership cache – Drupal Cache: A Case Study

You can also define your panel cache method for your particular use case and cache the panel content.  First, define a ctool plugin like:

<?php // Plugin definition. $plugin = array( 'title' => t("Example cache"),
  'description' => t('Provides a custom option to cache the panel content.'),
  'cache get' => 'my_module_cache_get_cache',
  'cache set' => 'my_module_cache_set_cache',
);

/**
 * Get cached content.
 */
function my_module_cache_get_cache($conf, $display, $args, $contexts, $pane = NULL) {
   $cache = cache_get(‘my_panel_data', 'cache_panels');
  if (!$cache) {
        return FALSE;
  }

  if ((time() - $cache->created) > $conf['lifetime']) {
        return FALSE;
  }

  return $cache->data;
}

/**
 * Set cached content.
 */
function my_module_cache_set_cache($conf, $content, $display, $args, $contexts, $pane = NULL)    {

        cache_set('my_panel_data', $content, 'cache_panels');
}

?>
  • Custom caching:

After looking at few more cachegrind reports, we identified some custom functions that were causing a performance problem and thrashing the database to perform complex queries and expensive calculations every time a user viewed specific pages. This prompted  us to use Drupal’s built-in caching API’s

The rule is never to do something time-consuming twice if we can hold onto the result and reuse them. This can be depicted in a simple example:

<?php function my_module_function() { $data = &drupal_static(__FUNCTION__); if (!isset($data)) { // Here goes the complex and expensive calculations and populate $data // with the output of the calculations. } return $data; } ?>

The drupal_static function provides a temporary storage to functions for data that sticks around even after they are done executing. drupal_static adds the magic to this function. It returns an empty value on the first call and preserves the data on next call in the same request. That means our function now can determine if the variable is already populated or not. If it has been populated, it will return the value and skip the expensive calculations.

The static variable technique stores data for only a single page load. To overcome this situation Drupal cache API persists the cached data in a database. The Following code snippet illustrates the use of Drupal cache API

<!--?php function my_module_function()   {   
$data   =       &drupal_static(__FUNCTION__);           
if (!isset($data)) {
  $cache = cache_get('my_module_data', 'cache_my_module')
  if ($cache && time() < $cache->expire) { 
    $data = $cache--->data;
  }
  else {
    // Here goes the complex and expensive calculations and populate
   // $data with the output of the calculations.
   cache_set('my_module_data', $data, 'cache_my_module', time() + 360);
  }
}
return $data;
}
?>

This version of the function uses database caching. Drupal caching API provides three key functions –  cache_get(), cache_set() and cache_clear_all(). The initial check is made to the static variable, and then this function checks Drupal’s cache for data stored with a particular key. If data is found the $data is set to $cache->data.

If no cached version is found, the function performs the actual work to generate the data and saves it to the static variable at the same time which means that in the next call in the same request, it does not even need cache_get.

Finally, we get a slick little function that saves time whenever it can—first checking for an in-memory copy of the data, then checking the cache, and finally calculating it from scratch.

Conclusion:

After putting all these together, we were able to reduce the total number of functions call to 741 and the execution time reduced to 665ms. Hence we get the 1500% of performance boost.

Cachegrind Report Generated After Implementing Drupal Cache. - Drupal Cache: A Case StudyCachegrind Report Generated After Implementing Drupal Cache. – Drupal Cache: A Case Study Want to learn how to set up RESTful Drupal Caching?

References:

This article was originally published in April 2015.

Jul 21 2016
Jul 21

Using Drupal in higher education has been a popular choice among leading schools. It’s become the preferred website platform for hundreds of institutions of higher learning around the world. Schools like Harvard UniversityStanford Law SchoolDuke UniversityBrown UniversityRutgers UniversityUniversity of OxfordUniversity of Prince Edward IslandKarlstad UniversityZaman UniversityBentley UniversityUncommon SchoolsUniversity of Waterloo, and Yale have chosen Drupal as their preferred content management framework because it best supports current and future needs of students, faculty, alumni, and their communities.

In short, Drupal has proven these top schools that it serves higher education website needs. Here are some specific reasons why it’s best for your school.

The Top 14 Reasons To Use Drupal In Higher Education:

1. Multi-Site Functionality

Most universities and colleges maintain multi-faceted websites, ones that serve a broad range of purposes. By leveraging Drupal’s built-in multi-site functionality, institutions provide their departments with a substantial toolbox and relevant media types for communicating with students, staff, and other users via a single system.

This multi-site capability helps institutions break out independent websites by giving control and ownership to individual departments. This control structure significantly reduces administrative overhead from the IT office. SomeDrupal in higher education distributions like Open Atrium allow you to build intranets for any educational institution.

2. Easy Responsive Design Implementation

According to an eMarketer study, an estimated 90 percent of US college students will own a smartphone by the time they graduate in 2016. Now with Drupal 8, academic centers can easily use Drupal in higher education to stay up-to-date and relevant to users by delivering smoother, responsive website experiences out of the box.

Experiences from each user’s device of choice. Drupal sites adapt to user evolutions, making it optimal for institutions with student demographics. It’ll also be easier for admins to manage content with a dashboard (one that’s responsive and mobile ready out of the box as well).

3. Workflow Modules

Drupal’s Workflow modules and features set allow universities and colleges to control and manage the publication process actually, without limiting its use as a mere content management tool. There’s granular control available for every content operation.

At each step, employees can be notified to complete their tasks (like editing). This control keeps team members from performing tasks out of order and keep projects moving forward.

4. Content & User Access Control

With Content and User Access Control, site administrators can create privileges grouped together by access level, function, and role. These permission sets can be assigned to groups of users rather than manually granting privileges to each and every user. Permission sets help decentralize task responsibilities like creating, editing, and managing content, all without putting extra workload on your IT hub.

These Drupal in higher education access control features are exceptionally handy on university websites where professors, students, alumni, and site visitors require unique user experiences and different access rights. The domain access module enables sharing content across multiple sites quickly, allowing site owners to share configuration settings and users among various college or university portals.

5. Multilingual Awesomeness

With Drupal 8 now available in over 110 languages, you can have your site available in almost any language that your student demographic needs. This feature allows decision makers to take into account: international student associations, global event communications, foci of studies, and more.

6. Efficient Use Of Taxonomy System

Drupal’s taxonomy system is a robust method for classifying website content into groups. Taxonomy systems can be designed and deployed on a per-content basis.

This system ensures extremely efficient content categorization on the site, resulting in ease of access for site visitors or users. Through taxonomy usage, only relevant content is delivered to site visitors; this avoids distractions and simplifies navigation.

View Our Work

7. Collaboration Modules

Apart from forward-facing content—static pages, forums, course schedules, blogs, and articles—Drupal provides powerful collaboration features and document management for back-end users. These systems are not typically part of the public front-end but are critical for faculty and students who require access to manuals, handbooks, procedural guides, and research documents. Because of its tools for collaboration, Drupal is a prime system for supporting internal teams and research for university and college websites.

8. Single Sign-On

Most higher education institutions have existing authentication systems for email or other internal accounts. With Drupal using LDAP and CAS, single sign-on for academic websites are easily doable. These single point access integrations result in a secure environment for users who want multiple resources and services via a single login.

9. Community Support for Drupal in Higher Education

IT movers and doers can connect with Drupal community groups around the world, and can easily search the issue queue for questions and answers related to institutes of higher education. Some community group examples are:

10. Social Media & Email Campaigns

Drupal’s integrated capabilities make engagement easier. From email marketing services like MailChimp, Constant Contact, etc. to higher ed social media campaigns launched via Twitter, Youtube, Pinterest modules, and more.

11. Drupal’s Multisite Approach

Multisite management needs are common for institutions of higher ed. Different departments or student initiatives often require sister domains. Drupal’s flexibility means effective content storage for each website. Sharing different site content can be done with the Domain Access module, allowing configuration, user, and content settings to be managed between or across sites.

12. Quick Edits

Drupal sites for institutions of higher education provide an editing fast track. School event location changes, cancelations, and more can be managed quickly by a novice. With CKEditor, creating media rich content is simple and time saving. Media management is simplified by the Media Module in Drupal, it helps embed files in your post, makes files fieldable, enabling the use of text fields to store captions on images, taxonomy fields for audio file genres, etc.

13. Security Reasons

College sites are often targeted, which drives higher ed decision makers to choose their digital platform wisely. Open Source Software (OSS) is generally more secure than proprietary software, and Drupal is no exception. Drupal’s security team is highly responsive and sends frequent security fixes for all actively maintained versions—all security fixes are logged.

14. 400+ Experienced Vendors With Drupal In Higher Education

Colleges and universities have many vendors to choose from. And we’re in the top 10.

Download Drupal Staff Augmentation Case Study

Article originally published on December 3, 2015 and has been updated.

Parth Gohil

Parth Gohil

Parth is Axelerant's Community Manager hailing from Surat. He loves supporting open source communities, piloting single-engine aircraft, and being a Cha-Cha Productions actor.

Jul 06 2016
Jul 06

Development started on Drupal 8 features back in March of 2011. Since then, the developer and application framework world has looked forward to the outcomes of every development, feature completion, clean-up, API completion, beta, and release candidate (RC) phase with baited breath. In November of 2015, Drupal 8.0.0 was released. Sighs of relief turned to curious murmers—what’s this all about?

Drupal 8 takes an already terrific content management framework to ever greater heights for users, administrators, and developers. There’s a seriously sharp focus on user-friendliness, but content presentation, new ways to create data structures, build APIs, multilingual capabilities, and the delivery of mobile accessibility out of the box? Drupal 8 brings those to the table too.

Looking for help with Drupal 8?

There are 16 Drupal 8 features worth knowing.

While Symfony 2 powers the Drupal 8 backend, a lighter and faster core offers tons more capabilities for modules and themes. Plus, the Drupal 8 migration and the onward curve is significantly reduced. These changes and more are key reasons to consider that switch to Drupal 8. But I’m getting ahead of myself, here are the 16 top Drupal 8 features:

1. New Theme Engine

Drupal 8 includes a brand new theming engine called Twig, which is PHP-based, flexible, fast, and secure. It’s much easier to create beautiful and more functional Drupal websites using Twig, as its templates are written in a syntax that’s less complex than a PHP template or others while being more secure.

2. Mobile First From The Get-Go

Drupal 8 is mobile first in its approach. All the built-in themes that come with Drupal 8 are responsive, along with an admin theme that adapts to different screen sizes, and a ‘Back To Site’ button to go back to the front page. Tables fit into any screen size without a hitch, and the new admin toolbar works well on mobile devices.

3. More HTML5 Power to You

HTML5 is now more or less the de facto standard when it comes to writing web markup. The same is now available natively in Drupal 8, giving you access to input fields like date, e-mail, phone, etc., and even more functionality and compatibility with mobile and handheld devices.

4. Multilingual Ready

Drupal 8 boasts extensive multilingual features right out of the box. The admin interface has built-in translations. You can also create pages with language-based Views filtering and block visibility. Translation updates from the community are automatically facilitated.

5. Manage Your Configuration

Drupal 8 has configuration management built into it at the file-system level so that carrying over configuration elements (like content type, views, or fields, etc.) from local development to the server is a breeze. You can use a version-control system to keep track of configuration changes. Configuration data is stored in files, separate from the site database(s).

6. Easy Authoring

New Drupal 8 features bring unprecedented power into the hands of the Content Editor, with WYSIWYG editor CKEditor now bundled with the core. However, the most touted improvement remains the in-place editing capability that Drupal 8 will afford users, a result of the Spark Initiative.

Site and content creators or editors can edit text on any page without having to switch to the full edit form. Drafts are now much easier to create, and web security is now better implemented as a result.

7. Quick Edits

There’s something great about seeing something that needs changing and having the ease of access to change it—directly and quickly. Now Quick Edit is a backport of the Drupal 8 in-place editing for Fields. So if you’re logged into Drupal content is in front of you, edit the text directly for quick fixes and additions from the front-end.

8. Views Now Part of Core

Views sit high up in the Drupal module hierarchy, as it is an integral part of most website projects, and a lot is pretty much impossible without it. Site designers have used use this hitherto-contributed module to output galleries, maps, graphs, lists, posts, tables, menus, blocks, reports, and what-have-you.

With this Drupal 8 feature, Views is part of and firmly integrated with the core. The front page and several administration pages are now Views, and users will now be able to quickly create pages, blocks, admin sections, etc., and modify existing ones just as effortlessly.

9. Better Support for Accessibility

Drupal 8 has excellent support for industry standard accessibility technologies, like WAI-ARIA. ARIA Live Announcements API and TabManager are significant improvements in Drupal 8, which provide control for rich Internet applications. Bells and whistles like better font sizes, tweaked color contrasts, jQuery UI’s autocomplete, and modal dialogs go a long way towards making Drupal 8 a breeze to use.

Download our Ebook: Learn to select your best Drupal Partner

10. Web Services Built-in

Drupal 8 now makes it possible to use itself as a data source, and output content as JSON or XML. You can even post data back to Drupal 8 from the front end. Hypertext Application Language (HAL) is implemented in Drupal 8 and makes exploitation of web service capabilities less painful.

11. Fields Galore

Drupal 8 ships with bucket-loads of field types in the core, thus taking its content structure capabilities up a notch. New field types like entity reference, link, date, e-mail, telephone, etc., aid content creation, and now you can attach fields to more content types, as well as create custom contact forms by attaching fields to them.

12. Guided Tour

Now the descriptive text is right under the help link. Users can click and then take the tour; pop-ups appear, explaining how this all works, one of the most helpful Drupal 8 features to newcomers. This user-friendly boost is well-received as it’s making the CMS easier for everyone to understand.

13. Loading Speed

Drupal 8 caches all entities and only loads JavaScript when necessary. When a page is viewed, its content doesn’t need to be reloaded again. Previously viewed content is quickly loaded from the cache. Once configured and enabled, caching is completely automatic.

14. Industry Standards

Drupal 8 aligns with the latest PHP 7 standards like PSR-4, namespaces, and traits, and uses top notch, outstanding external libraries like Composer, PHPUnit, Guzzle, Zend Feed Component, Assetic to name a few. Meanwhile, underlying Drupal 8 features modern, object-oriented code that’s the order of the day, by Symfony 2.

15. JavaScript Automated Testing

Automated testing is not possible for front-end, so JaveScript (JS) automated testing is now possible with Drupal 8.1. Now QA’ers can test the JavaScript front-end automatically, saving time and making continuous integration that much easier.

16. Big Pipe in Core

With Big Pipe part of Drupal core, developers can optimize the site load performance for the end-user significantly. While this feature has nothing to with actual performance and is only perceived, it’s a great feature to have since the end user is able to see a difference in site load times.

Enough Drupal 8 features to think about?

These 16 Drupal 8 features are some of the most important reasons that this upgrade is so worth celebrating; it’s the collective work of over 3,000 contributors. But more importantly to you, this might be that big, bright answer you’ve been searching for.

Got Drupal 8 your mind?

More Drupal 8 resources:

This article was originally published in July, 2014. It has since been updated.

Jun 08 2016
Jun 08

If you or your competitor is moving to migrate to Drupal 8, that’s good for one of you… and potentially really bad for the other.

Somebody is picking up on something big, because Drupal 8 migration is a mark of enterprise-level thought or a sign of aspiring enterprise-level vision. If you or your associates aren’t sold yet, the proof is in D8’s mobile, global features.

You could say accurately that modern Drupal is a preemptive, forward step, a step away from the dangers of a Closed Source, “one size fits all” mentality. See headless Drupal migration stories for even more proof.

Big question: why migrate to Drupal 8?

Well, the sense that mobile incompetence and unchecked global competition are deal breakers? That’s more than a feeling. That’s a fact. Today if your website isn’t responsive and built for growth with features like those of Drupal 8, you’re declining. Let’s get why:

  1. Face it, we need a different kind of responsive.

  2. What makes Drupal 8 mobile first.

  3. You migrate to Drupal 8 for all users.

  4. Migrate to Drupal 8 for your customers.

  5. And migrate for international teams.

Decision makers like you, with a keen sense for growth, will see. Within these features are the traits of an evolving Open Source software for 2016 onward. 

1. Face it, we need a different kind of responsive.

Having a responsive design means having a website that automatically looks good no matter your user device’s viewport size. The way we search the internet has changed. Search technologies and site owners must account for it.

Just last year, Google rolled out a mobile friendly algorithm that led to mobilegeddon. It was labeled a doomsday because of the tremendous boost in search engine results given to responsive websites versus the whack it gave desktop-only sites.

How far does mobile reach?

In the US, one out of every three people owns a smartphone. Worldwide, it’s one out of every five. The number of users browsing on tablets, phablets, and phones will continue to rise—website responsiveness becomes more critical every day.

View Our Work

Responsive websites are made possible with things like CSS media queries. These queries define how page elements should be displayed to users. Its effectiveness can be checked with responsive plugins and extensions from Chrome and Safari. At Axelerant, we created a simple URL mobile friendly website tester that can check your site.

But shouldn’t “desktop” versions come first?

Not anymore. Productive websites from now on should be treating the desktop as secondary. The demand for mobile, responsive themes has never been higher and it continues to rise. The number of users accessing sites from mobile devices only is steadily growing.

Users in the US alone are accessing mobile online media 51% of the time, compared to the 41% using a desktop. These accesses drives the Drupal community to focus on mobile first because we’re passed the 50-50 mark. Having a clear focus on mobile first designs can also improve the efficiency of your desktop website. Your website’s responsiveness has to be taken into account if it’s going to be productive to you and your end users—to inform, deliver services, generate leads, and more.

2. What makes Drupal 8 mobile first.

Drupal 8’s very essence is accessibility because it was made with a mobile first mentality—for users and end-users. When site owners migrate to Drupal 8, they solve the need for an extremely responsive website. It’s an upgrade that isn’t an option anymore.

For Drupalers like us, a Drupal 8 upgrade provides fresh mobile-friendly development for the content management system (CMS) and Open Source software (OSS) industries. In fact, Drupal’s original creator and product lead Dries Buytaert said way back in 2011:

If I were to start Drupal from scratch today, I’d build it for mobile experiences first, and desktop experience second.

Considering all of its modern features, Drupal 8 has been well worth waiting for. Contributors charged forward with a transforming Mobile Initiative to create a first-class mobile platform, spearheaded by the initiative’s lead John Albin Wilkins. The admin interface, themes, tables, and pictures were focused on and today these are incredibly useful:

Drupal’s Admin

As a mobile friendly CMS, Drupal enables on the go administration. Managing content on a mobile device has become painless. The admin layer has been revamped to be simple, straight-forward, and light. Toolbars work horizontal or vertical as needed.

Great Responsive Themes

All built-in themes are responsive. These give you the power to change the way your site looks and feels. Drupal 8’s new theming engine Twig is PHP-based, secure by default, easier to read, and front-end developer friendly.

This new theme flexibility enables the creation of highly attractive, highly functional sites that look great on mobile. The right theme will help power your organization’s branding while providing positive user experiences.

The goal was to transition all existing Drupal 8 themes from “desktop only” to mobile first, and for all to include a useful backend platform. This ties into the push to make Drupal the leading mobile CMS platform.

Flexible Tables

When a user views the page from a narrow device viewport, such as page’s horizontal elements will automatically become vertical, with lesser important columns being removed.

Breakpoints are built into Drupal 8, which keep track of height, width, and resolution. These breakpoints enable a site to respond appropriately to different devices: tables and the likes shrink readily to preserve mobile integrity. So when transitioning from a desktop screen to a mobile one, you’ll see tables adapt seamlessly.

Picture Perfection

With such an emphasis being placed on ease of use for end users and administrators, with a migrate to Drupal 8 images become responsive. Administrators can add large photos to their pages that automatically size themselves appropriately based on the viewer’s device.

The Drupal 8 responsive module that contains breakpoint mapping and an image formatter that efficiently reduces file weight by resizing the image. These features can be used to output responsive images using the HTML5 picture tag.

Responsive image support isn’t just visually convenient, it helps pages with large images load faster. Meaning that pictures worth 1,000 pixels don’t have to make your mobile site slow or awkward.

3. You migrate to Drupal 8 for all users.

You already know that the standards of your website should be up to par with the growing number of relevant on-the-go, global web users. A huge, growing number that has a direct effect on your organization or will soon. Accessible websites existing within the digital space will either experience the positive or negative side of the expanse: one billion users in 2005, two billion in 2010, three billion in 2014, almost three and a half billion in 2015, and counting.

Now if you keep these numbers in mind, consider that the number of smartphone users in the world is expected to be a massive 6.1 billion by 2020. This growth means that in less than five years, 90% of the world will be online and at that point, 70% will be mobile.

You might be tempted to think: “these numbers don’t apply to my organization. Relevant visits to my site aren’t going to increase as these figures grow.” That’s only correct if your website isn’t mobile first and global ready. In fact, if your site isn’t more accessible now than before, you can expect the number of new, relevant visitors (potential customers searching for your services) to drop.

4. Migrate to Drupal 8 for global customers.

Drupal 8 mobile-based global websites are designed to be accessible for international users from other countries and different cultures. With a migrate to Drupal 8, modern organizations looking to target specific even global reaching demographics can succeed.

However, due to rising internationalization and increasing globalization, all forward thinking businesses will eventually need to take up these searchable, accessible, localized websites. Localization is especially true for e-commerce sites, which must be prepared to cater to ever-changing global e-commerce data. If you’re selling a product or a service online, chances are you’ve been made aware of increasing numbers of international visitors. If your organization has the structural capabilities to sell to these demographics, it should.

What’s this about website localization?

This isn’t the opposite of what’s called website internationalization or globalization. Website localization refers to “local” site adaptations, which facilitate particular communicative, cultural, or other demographical requirements that cater to a particular target market. Globalized or internationalized sites enable localization.

Ongoing Drupal 8 initiatives are aimed at improving its localizing interface to suit international users. Likewise, these users can create localized Drupal sites for their audience. What helps make this possible is a sophisticated translation manager in the Drupal core. This system empowers users to utilize the right translations, for example, for each targeted demographic that need to be reached.

5. And migrate to Drupal for international teams.

To be global ready is to be user-friendly on an international scale, and Drupal internationalization accomplishes this. In the late 90’s, over 80% of internet users were native English speakers, by 2010, this dropped to less than 30%.

With Drupal 8’s multilingual capabilities, international site visitors and Drupal 8 site builders alike aren’t met at a half-way mark, but where they’re most comfortable: in their language. Drupal 8’s Configuration Translation enables the translation of essential elements—blocks, toolbars, menus, etc.

With these essential features, Drupal 8 positions itself as the global ready website option. Multilingual feats like translation and transliteration are two pillars of this positioning.

Drupal 8 Translations

Advanced multilingual capabilities of Drupal 8 are hallmarks of this release. Whereas Drupal 7 has regional settings, language support, and usability attention given to interface translation, Drupal 8 brings this into the core. It comes with highly improved language detection abilities that are browser based, meaning it functions to identify preferred languages and present them to users automatically.

There’s 94 languages and counting, one of which that you can assign as a website default for content and configurations. Blocks can also be language dependent. Further, more page elements than ever are now “blocks” in Drupal 8, granting greater translation accessibility.

Even “Transliterations”

There are times when characters need to be romanized for various purposes. Drupal core has addressed this. Now, built-in user interfaces transliterate key language assignments. This transliteration is an advancement from other CMS solutions, enabling efficient romanization of several challenging scripts and types (e.g. Hungarian, Czech, Marathi).

There is a variety of multilingual Drupal 8 sites in production settings of multiple industries that demonstrate Drupal 8 easily makes possible.

Download Drupal Staff Augmentation Case Study

Migrate to Drupal 8 for results.

If you migrate to Drupal 8, you’re setting your organization up for the future. The importance of a mobile-friendly and global ready website cannot be overstated. You’ve heard it more than 1,000 times that “content is king.” It’s true, but it has to be accessible first so your targeted content reigns supreme. Your content after a migration to Drupal 8 can become even more SEO friendly, fast, mobile, and manageable.

Great content doesn’t just happen. Content creators and copywriters need to apply their trade strategically more than ever before. And while it’s principally a supportive means for content creation, Drupal 8 will certainly help. In so many ways, Drupal 8 and content marketers were meant for one another.

SEO capabilities: Users have tons of available modules that monitor SEO activity and track analytics. It’s also able to produce automatically customizable meta tags or create title based URL nodes for a website. Awesome tools like Yoast and Goalgorilla can now be incorporated to develop a site’s SEO in all aspects. Drupal 8 also supports RDF and integrates very easily with Google Analytics.

Content Loading: Another way that Drupal 8 supports content has to do with how quickly and readily it loads. Loading speed is a huge factor that will directly affect both the site’s global rank and local rank. Now Google provides insights on a page’s loading speed to help isolate costly hold ups. Drupal 8 has features that help users address page load issues. As an example, Drupal 8 caches all entities and only loads JavaScript when necessary. What this means for a page is that viewed content doesn’t need to be reloaded again, rather it’s quickly loaded from the cache.

Maximizing Value Via Continuous Discovery (PDF)

When visitors return to a Drupal 8 website, they won’t have to wait for previously viewed content to load up. Updated or new content is presented to visitors while the cache of older unchanged content remains preserved and shown immediately.

Content Visualization For Multiple Devices: See content when editing, as it’ll look when published with a real-time what you see is what you get (WYSIWYG) editor for desktop and mobile devices. Via the WYSIWYG editor, users have the option to choose images and revise content for desktop or mobile versions as needed. By seeing what end users experience—in real time—is a valuable feature for saving time and foreknowing the outcome before publishing.

General Content Management: Drupal 8 offers a simple and flexible CMS. With previous Drupal versions have been seen as too challenging for new users. Drupal 8 changed all that. Now content authoring is easy and reliable performance is guaranteed. Content managers can navigate their site smoothly and use the new on-page editor quickly and with ease.

With mobile, global content taking the center stage on every stage, if you migrate to Drupal 8 your organization can get it right. It’s time to leave the disappointing and the outdated behind so your organization can pursue something greater.

Want to migrate to Drupal 8?

This article was originally published in October, 2015. It has since been updated.

Jun 02 2015
Jun 02

In April 2015, NASA unveiled a brand new look and user experience for NASA.gov. This release revealed a site modernized to 1) work across all devices and screen sizes (responsive web design), 2) eliminate visual clutter, and 3) highlight the continuous flow of news updates, images, and videos.

With its latest site version, NASA—already an established leader in the digital space—has reached even higher heights by being one of the first federal sites to use a “headless” Drupal approach. Though this model was used when the site was initially migrated to Drupal in 2013, this most recent deployment rounded out the endeavor by using the Services module to provide a REST interface, and ember.js for the client-side, front-end framework.

Implementing a “headless” Drupal approach prepares NASA for the future of content management systems (CMS) by:

  1. Leveraging the strength and flexibility of Drupal’s back-end to easily architect content models and ingest content from other sources. As examples:

  • Our team created the concept of an “ubernode”, a content type which homogenizes fields across historically varied content types (e.g., features, images, press releases, etc.). Implementing an “ubernode” enables easy integration of content in web services feeds, allowing developers to seamlessly pull multiple content types into a single, “latest news” feed. This approach also provides a foundation for the agency to truly embrace the “Create Once, Publish Everywhere” philosophy of content development and syndication to multiple channels, including mobile applications, GovDelivery, iTunes, and other third party applications.

  • Additionally, the team harnessed Drupal’s power to integrate with other content stores and applications, 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.

  1. Optimizing the front-end by building with a client-side, front-end framework, as opposed to a theme. For this task, our team chose ember.js, distinguished by both its maturity as a framework and its emphasis of convention over configuration. Ember embraces model-view-controller (MVC), and also excels at performance by batching updates to the document object model (DOM) and bindings.

In another stride toward maximizing “Headless” Drupal’s massive potential, we configured the site so that JSON feed records are published to an Amazon S3 bucket as an origin for a content delivery network (CDN), ultimately allowing for a high-security, high-performance, and highly available site.

Below is an example of how the technology stack which we implemented works:

Using ember.js, the NASA.gov home page requests a list of nodes of the latest content to display. Drupal provides this list as a JSON feed of nodes:

Ember then retrieves specific content for each node. Again, Drupal provides this content as a JSON response stored on Amazon S3:

Finally, Ember distributes these results into the individual items for the home page:

The result? A NASA.gov architected for the future. It is worth noting that upgrading to Drupal 8 can be done without reconfiguring the ember front-end. Further, migrating to another front-end framework (such as Angular or Backbone) does not require modification of the Drupal CMS.

Jan 31 2014
Jan 31

There are a couple of scenarios we see on pretty much any Drupal-powered website we work on. The first and foremost among those is often that our client wants to, you know, actually be able to easily manage their content. At the same time we need to be able to fit their content into the information architecture and design of the site. When we're talking about entities, nodes, and taxonomy terms it is pretty easy for content managers to go in and edit content. But what about little blocks of text on the home page, in the footer – or featured call-outs on various pages? These kinds of features have been a constant struggle to ensure that they exist through the process, but allow the content itself to change as needed.

Front-end example of the Pane Module at work.

Over the years we've tried many different Drupal modules and solutions including, Core blocks, Boxes, Beans, and Fieldable Panels Panes, but none of them quite worked right for both us and our clients. So we wrote our own module called Pane. The key features that we needed from our new module were:

  • Exportability – allow it to be exported through CTools and Features; neither Core blocks, Beans or Fieldable Panels Panes are easily exported
  • Separation of configuration from content – allow the guarantee of existence and format but allow the content to vary; when Boxes are exported they export the content along with configuration
  • Integration with CTools/Panels – we're heavily invested into the CTools universe and needed our tool to work nicely with those; most of the modules above stem from the block system and don't play nicely with CTools
  • Internationalization – allow the content to vary based on the current language; Beans and Fieldable Panels Panes are entities and could presumably be translated, but there's a layer of complexity involved in that which makes it more challenging

What the Pane module allows a developer to do is create a Pane and embed it on either a CTools Page Manager page as a CTools Content Type or through the normal Block interface. From there the Pane can be edited through the normal Panels or Block interface to edit HTML through a WYSIWYG or if using the Pane Entity Reference plugin to add and order references to various entity types much like the Entity Reference module. Those referenced entities can be output using either a display mode or a View. 

Once the module is installed and the permissions configured, an admin can go to Administer -> Structure -> Panes and see a list of current Panes and add new ones.

They can also edit Panes through the normal Panels interface or through the In Place Editor.

And then exporting can be done through the normal Features interface. The configuration and the data can be exported separately and generally only the container is exported. But if you know that the content isn't going to change and needs to be locked down in Features it can be there as well.

This module makes a lot of sense both for developers and content administrators. Let us know what you think in the comments.

Jan 17 2014
Jan 17

Migrating comments from Drupal to DisqusEven if you've never heard of Disqus before, you've almost certainly seen it. With slick social integration, support for a variety of platforms (including WordPress, Blogger, Tumblr, and Drupal) and a rapidly expanding user base, Disqus has become one of the most popular hosting services for website comments. If you've had misgivings about the commenting system you're using – or just envied the functionality and polish of other systems – you may get to a point where you decide (as we did for our Forum One blogs) to make the switch to Disqus.

Making this switch is fairly straightforward – but what about all those wonderful comments that your blogs have earned over the years? You don't want to lose all the valuable discussion, tips and virtual high fives from your online fans, do you? Probably not. So if you're using Drupal and looking to upgrade to Disqus from a system like Mollom, there are various resources that already exist for manually migrating those comments, but nothing explains the process from A-Z, so I've compiled this step-by-step guide to show you how to manually do the job.

There are two primary ways to migrate comments: (1) Using the API to automate the whole process by directly connecting to Disqus from Drupal and move the comments for you (which isn't working at the moment); or (2) Using the Disqus XML export tool to migrate comments from Drupal in XML format which you can then import manually into Disqus.

Versions

  • Disqus module (Do NOT use 6.x-1.9 which was the stable version at the time of writing this. In normal Drupal fashion the Dev version is the one to use which is 6.x-1.x-dev released Nov 22, 2013 which contains the extra features needed to do this.)
  • This was done in Drupal 6 though D7 is very similar

Step 1 - Module Enabled

Enable both Disqus and Disqus Migrate modules (Disqus Migrate provides migration tools for moving comments between Disqus and the Drupal comment system). Disqus has a great reference for this.

Note: There are additional steps to enable Disqus (ie. downloading and installing the API library, adding your Disqus keys and verifying connection with Disqus, as well as actual Drupal access permissions) which are well documented in the list of references I've provided at the foot of this article. Since those steps are primarily used for setting up the module rather than carrying out the actual migration, I will not review those steps here.

Step 2 - Export Drupal Comments

  • Navigate to the Disqus export page /admin/content/comment/disqus_export which contains two buttons, Export Awaiting Comments Using API (which doesn't work as of writing this) and Export All Comments to XML File which is the one you should click.
  • Select Export All Comments to XML File (This option is explained as Exporting via XML will just gather all of your websites comments and format them for importing manually into Disqus)
  • Save the file to your local file system.

At this point you will have all the comments from your site in XML format which we will not import into Disqus.

Step 3 - Import Drupal Comments Into Disqus

  • Log into Disqus and navigate to Admin -> Discussions (Tab) -> Import (Tab)
  • Select the Generic WXR sub-tab option.
  • Select the Upload WXR file browser button and select your XML file you saved locally.
  • Select Upload and Import button.

Upon completing this, the comments will be imported to Disqus and you might want to do some house cleaning of those comments using the Disqus Admin interface tools.

Step 4 - Optional, but pretty much needed

After the comments are imported you may notice that some comments that exist on your Drupal nodes are not being displayed in Disqus. This is most likely caused by URL aliases. Since Disqus maps comments to nodes by path, this means that example.com/node/32 and example.com/how-to-play-ball may be the same node, but Disqus doesn't know that – so the result is that those comments will only show for the URL that was in the export XML file. What we need to do now is provide Disqus URL mapping.

  • In Disqus navigate to Admin -> Discussions (Tab) -> Tools (Tab)
  • Select Start URL Mapper. This takes you to a page that will give you a list of comment paths Disqus knows so you can provide manual path mapping information OR you can have Drupal create a mapping file for you. I chose to do this using a custom script.This page shows you the format it expects the CSV format (comma separated value) file to be in:
  • Follow the link to download the CSV file from Disqus to your local file system and name it disqus-urls.csv.
  • Copy this CSV file to your Drupal root directory.
  • Create a file with the following PHP code in that same Drupal directory called disqus-custom-script.php

<?php

$base = 'http://forumone.com/';

$n = strlen($base);

foreach (file('disqus-urls.csv') as $url) {

  $path = substr(trim($url), $n);

  $source = drupal_get_normal_path($path);

  if ($source != $path) {

    echo "$base$path, $base$source\n";

  }

  else {

  $source = drupal_get_path_alias($path);

  echo "$base$path, $base$source\n";

  }

}

  • Browse to the PHP file (or execute your preferred way so you can see echo output). Browsing to it with yoursite.com/disqus-custom-script.php assuming you named your PHP file that and saved it in the root directory as asked.This will give you output that can be saved into a CSV file and will be in the exact format that Disqus expects.
     
  • In Disqus navigate back to Admin -> Discussions (Tab) -> Tools (Tab) -> Start URL Mapper (Button) and upload the text file containing the output from our PHP script.

Make sure you give it a few minutes to complete, as the mapping in Disqus isn't instantaneous, but you should start seeing your comments appear where they should for the URLs that were in the mapping CSV file.

That's it! Below I've provided a list of references that you can use when following these steps. If this guide is helpful for you, or if you discover a different solution, please leave us a comment ;)

References

Nov 05 2013
Nov 05

Felt Android MascotI’ve recently given in to temptation and bought myself a Google Nexus 7. Having come from a predominantly Apple/IOS background, I was bursting to try out an alternative mobile operating system. Especially one which seems to actively outperforming Apple’s product.

I won’t go into a feature for feature comparison right here. Suffice to say, when I wrote my guide to setting up an alarm clock on the Nexus, I suddenly realised I had no idea how to take a screenshot on the device!

Luckily, taking a screenshot on a Nexus (as with the iPhone/iPad) is a built-in function. However, it’s a little tricky to carry out. Here’s how to do it:

Press and hold the power and volume down buttons simultaneously. That’s it. Seriously.

It might take a second, but you’ll hear the sound of a camera shutter and a still image of your screen will shrink and disappear. The status bar at the top of your screen will say that your screenshot is currently being saved.

To retrieve your screenshot files, simply fire up the Gallery app on your Nexus and you should see a subfolder called Screenshot. There are plenty of sharing options for getting your pictures online, and I could have attempted to upload them directly to WordPress via Chrome. However, I opted to email them to myself via Gmail and then resize the images on a laptop instead.

Nov 03 2013
Nov 03

Google Nexus LogoIf, like me, you’re just starting to get into Android through Google’s fantastic Nexus products, you’ll probably have spent some time looking for the alarm clock functionality. Trust me, it’s well hidden! I initially went looking through the Nexus settings, but had no luck. Guess what? Once you discover where to look, setting up multiple alarms on the Nexus is actually a doddle. Let me talk you through it! These instructions should hold steady on any Nexus device, though I’m using a Nexus 7 with Android 4.3.

Set up your first alarm

The Nexus Clock App

Click on the clock at the top of your home screen. This should take you into the clock config screen. (Alternatively, click the “All Apps” button – the circle on the bottom of your home screen – and then open the Clock app from there.) Next, click on the alarm clock icon in the lower left corner.

This should bring up the following screen. It may contain a preconfigured alarm, or it may be empty.

Nexus: Empty Alarm Screen

Click on the + button in the top right corner to add a new alarm. You should then see the following screen:

Alarm app - setting the time

Simply use the numberpad to type in the exact time you want to be woken up at. There are a couple of shortcuts for :00 and :30 which might come in handy. Click OK when you’re done.

That completes the basic alarm setup, but you can choose the ringtone and the repeat settings for the alarm in the following screen:

Alarm repeat settings on Nexus

You may also set a label for the alarm, however unlike the IOS alarm app, this isn’t displayed prominently, so it may not be of much help to you. If you want to add a label anyway, click into that field and type a name for the alarm.

That’s it, you’re done!

Disabling an alarm

If you want to temporarily disable an alarm (say you’re on holiday for a week and you want to lie in), you can simply toggle the on-off switch at the right hand side of the alarm. See the photo below:

Alarm configuration screen on Android 4.3

Deleting an alarm

Deleting an alarm on the Nexus is easy – you simply hold your finger on the alarm you want to delete. This should highlight the entry in blue, then the top toolbar will display a trash can icon. Click the trash can and your alarm will be deleted.

How to select an alarm and delete it on Android

That’s it for my Nexus/Android alarm configuration guide. If you’re an IOS user, here’s a photo guide showing you how to set up your IPhone alarm clock.

Oct 03 2013
Oct 03

The Node Access system in Drupal provides a powerful way to provide granular access to individual nodes, but it can occasionally cause unexpected problems.

Consider a case I ran into the other day: I had a View that was supposed to show all files managed by Drupal, however some users could only see a subset of the files. My initial detective work took me the wrong direction (I was using the File Entity module and spent a little time investigating its file access system) but eventually I realized that:

  • Only users with the “Bypass content access control” permission could see all the files.
  • The “missing” files were ones that were not used in any node.
  • The first step of debugging any problem like this should always be to take a look at the actual query being run by Views.

Once I took a look at the query being generated by Views I realized my problem stemmed from the fact that my View contained an optional relationship to the node table via the file_usage table. This wouldn’t normally be a problem, but the node access system was adding node access criteria to the query in such a way that this optional relationship was effectively being made “required.” The net result for this View was that users without “Bypass content access control” (which prevents node access criteria from being added to a query) were unable to see files that were either never used on a node, or were used only on nodes which the current user was not permitted to view.

So yes, there is a bug

There’s a bug in Drupal core that causes this problem: https://drupal.org/node/1349080. There are a lot of comments on that issue, but I’ll try to offer a summary by way of an additional example. Consider a content type “album” that contains an entityreference to nodes of content type “artist.” If you have a View listing albums and add a relationship to the node table to get data about the related artist then the node access system will prevent some of your albums from being listed, even if you have permission to view all albums, and if either of the following is true:

  • No artist value has been entered for the album.
  • The current user is not allowed to view the artist node which the album references.

How to fix it?

You have a few options:

Patch core

At this point there’s only a patch available for Drupal 8. It hasn’t been backported to Drupal 7. There is a quasi-fix for Drupal 7 in comment #89 on that issue but it’s not totally correct and needs to be updated to use placeholders properly.

Disable SQL rewriting for your View

This was the approach I took to solve the problem I was having with my View of files. Perhaps you know you’re not displaying any sensitive data in this View are only using the joined-to table for filter criteria or something similar. In that case you can just disable SQL rewriting which will prevent the node access criteria from being added to your View. You can do this in the configuration for your View under Other → Query Settings. Be mindful when you do this because you may allow users to see data they shouldn’t be allowed to see.

Try to reconfigure your View to remove the relationship

Does the relationship to the node table exist to allow you to grab data that you’re rendering in fields in the view? You may be able to instead configure your View to output the view results via rendered entities and remove the need for the troublesome relationship entirely. Or is the relationship there to enable certain sort criteria? Consider changing the sort criteria. This won’t work for all situations (and won’t work when the relationship exists for purposes of filtering as in my case), but will be a useful approach for some.

In Conclusion

Keep a close eye out for this tricky bug. Your users might be getting blocked from seeing content (even non-node content) that they should be allowed to see!

Sep 18 2013
Sep 18

It's the minor things that get you into trouble sometimes. For instance, when I used drupal_http_request to do some proxying of content I ran into a little quirk of Drupal. If you get cookie headers back Drupal will go ahead and combine them all into a comma-separated list. If you look at the code you can plainly see where it does this and the rationale in the Request For Comments (RFC) 2109. The unfortunate part is that RFC 2109 has been made obsolete by RFC 6265 which was published in April 2011. If you blindly take this cookie header and pass it back to the client only the first cookie is actually captured. Whoops. 

Normally I'd just explode it and call it a day. Unfortunately the format for the cookie expiration is "Wdy, DD-Mon-YY HH:MM:SS GMT" (as per section 10.1.2). With just a little regex your problem is solved. It means having to do some annoying workarounds, but here is a solution:

function my_module_proxy_url($url) {
  $result = drupal_http_request($url);  if (200 == $result->code) {
    foreach ($result->headers as $key => $value) {
      if (strcasecmp($key, 'set-cookie')) {
        $cookies = preg_split('/(?<=\S),(?:\S)/', $value);
        foreach ($cookies as $cookie) {
          // Send separately since drupal_add_http_header concatenates with commas
          header($key . ': ' . $cookie, FALSE);
        }
      }
      else {
        drupal_add_http_header($key, $value);
      }
    }
  }
}

Aug 02 2013
Aug 02

After you've been working with Drupal profiles for a while, the line between what functionality is a part of core Drupal and what comes from contributed modules tends to blur, but it is important to step back every once in a while and examine these distinctions. I recently had a wheel-spinning moment over the difference between two formatters for file fields: Generic files and Rendered files. Specifically trying to answer the question: Why don't custom Display Suite fields to show up, or why can't I select Display modes (e.g. Default, Teaser, Full content), when a file is formatted with the Generic file formatter? The short answer is because the Generic file formatter does not render a file as an entity. And here is why…

I wanted to use the Display Suite module to show an extra field that I had attached to a file entity (In this case, it was a custom display suite code field to show the file size). Here you see where I am already relying on contributed functionality in Drupal. In out-of-the-box Drupal, files are not entities. You must to use the File Entity module to allow files to become entities and gain the benefits of an entity, like being field-able or using display modes. Once the file entity module is installed, you now have access to the Rendered file formatter for file fields, which can then display the fields attached to a file entity because the formatter's view function constructs a renderable array that is passed to drupal_render(), a very dynamic method for generating markup compared to a very set theme. Otherwise, when you use the Generic file formatter, you are dedicated to using the theme file_link provided by core's File module. This theme formats fields in a very basic manner; as a link and an icon. Here is what the theme's function returns:

return '' . $icon . ' ' . l($link_text, $url, $options) . '';

Which definitely is not as dynamic as how a rendered entity might be output. No fields, no display modes, just the file's basic information as a link (You could give it access to display modes though by making those available in the formatter settings hook, Then you would be responsible for handling those settings in whatever theme you use to render the field).

In the end, I did not use the Display suite code field at all. It relies on PHP code in the database, which presents issues around security, and also, as a colleague of mine pointed out, PHP code from the database is not cached, so there is a performance hit as well. Instead, I implemented my own Display suite formatter (Which is really just allows DS to use any standard Drupal field formatters) with a theme that re-implements file_field, adding the file size as a part of the display.

So in short: Generic files and Renderend files share the fact that they are both field formatters, but Rendered file > Renderable array > Rendered entity, while Generic file > file_like theme. It all makes perfect sense now.

Jul 31 2013
Jul 31

I gave this session at CapitalCampDC, to shed some light on to these aspects of Drupal. Panels, Panelizer and Panopoly can seem a bit overwhelming but this session will go over the best features of each one and how they can be invaluable tools. The Panels module alone offers so much out the box and Panelizer and the Panopoly distribution shows just how much this tool can preform. They are long tested tools that have so much built into them in their evolution in Drupal 7. This session will cover:

  • Panels and an understanding about the functionality it provides.
  • Panelizer and how it enhances Panels to do even more.
  • Panopoly and it's attempt to simplify the possibilities of Panels and Panelizer.
  • What are they good for.
  • What isn't the best use for them.
  • Quick tips that may save you a lot of time.

Check out the slides: 

Jul 01 2013
Jul 01

Although the Drupal Kaltura module (6.x-2.0-beta2) is great for most video play, it doesn’t always play nice with Organic Groups. Recently I was tasked with using the module on an existing Drupal 6 Commons site. The problem was that Kaltura media nodes do not automatically inherit the group association, when created in a group context. In other words; when there is a GET parameter for a group id (gid) present in the node add page for kaltura_entry content types, Kaltura content would not be associated with the group like other group post content types. This is because the module relies on notifications from the Kaltura service before a node is actually created, at which point, the parameter has no relevance. So all we needed to do was pass some data to Kaltura and have Kaltura pass it right back to us.

After some extensive research, I finally came across this documentation page. The section "Passing Partner Data to the KCW Widget" (KCW = Kaltura Contribution Wizard) explains that we do have a partnerData key in the variables passed to the Contribution Wizard widget and then on to Kaltura. In fact, the module already does something similar to pass the user ID. All we had to do was plug the gid in there then handle the returned data. This does require a bit of patching to the contributed module.

First, plugging in our group id. This required adding the following to line 47 of kaltura/kaltura_client/kaltura_helpers.php

if(array_key_exists('gids', $_GET)){

$flashVars["partnerData"] .='|[email protected]'. filter_var($_GET['gids'][0], FILTER_SANITIZE_NUMBER_INT);  

  }

Note that the values are delimited by pipes, and paired with an @. Next, we had to figure out how to handle the returned data. This required modifying the kaltura_notify_node_entry_add() function in kaltura/includes/kaltura.notification.inc to assign the node to a group during node construction. I was not entirely sure how to do this off the top of my head, so I relied on the suggestions in this Drupal stack exchange post and dropped the following code in around line 206 right before node_save($node).

if(array_key_exists('gid', $partner_data)){

$node->og_initial_groups[0][$partner_data['gid']] = $partner_data['gid'];

$node->og_groups[0] = $partner_data['gid'];

$node->og_public = 0;

$gnode = node_load($partner_data['gid']);

$node->og_groups_names[0] = $gnode->title;

}

As always, when modifying a contributed module, I saved these changes in a patch file in the repository so they can be tracked and re-applied in the event that we upgrade the module later (if the patch is not already applied by then).

Jun 03 2013
Jun 03

Last week, 17 Forum One developers and strategists joined 3,300 other Drupalers in Portland, Oregon, for the biggest DrupalCon conference ever. We had a “Nodetorious-ly” good time, convening with the Drupal community, learning about the future of Drupal, and exploring Portland.

Forum One DrupalCon Booth

Many of the session videos are available online. But to save you time, we’ve compiled our top 10 key takeaways from the DrupalCon 2013 conference:

1. Drupal 8! Drupal 8! Drupal 8! 

It was amazing to see the progress that has been made on Drupal 8 and the direction it is going. Infused in every session, from Dries Buytaert’s opening keynote, to the breakouts, to the Birds of a Feather discussions, to the happy hours, was excitement and anticipation for the next major release. While much of the front-end appears the same, nearly everything in the back-end has changed (for the better, in our opinion). Using the new APIs and object-oriented code, we’ll be able to accomplish previously difficult changes much more quickly and cleanly. On the administration side, Drupal 8 is making progress as a content distribution tool with digital output services built in. Because Drupal 8 is a far more advanced publishing tool, marketers and web managers will have access to component levels, layouts, and more with Drupal 8.

2. Know Your Content & Context

The future will be filled with more devices in different contexts, outside, inside, on-the-go. As Karen McGrane talked about in her keynote, it’s all about how the content is “chunked” in ways that we can push it to our multitude of devices in optimized formats and contexts that are relevant to the users. As much as there is talk about mobile, mobile is just one use case, albeit the predominant one now. Who knows what will happen in the next few years? Voice-activated interfaces will get really good? Smart watches? Drupal 8+ is well positioned to take advantage of this future through its flexibility.

3. Explore Fast, Light Prototyping

Through the user experience tracks, we saw that web teams are shifting away from pixel-perfect, static, “heavy” deliverables to lightweight, easily modifiable deliverables. We’ll see more tools for HTML-based, clickable, and interactive experiences over Omnigraffle or Visio wireframes. Speaking of which, Forum One has built a popular interactive prototyping tool for this purpose. Check out Proty.

4. Drupal Isn’t for Everything

Obvious? Yes. But we gained a deeper understanding of that statement during the event. It is easy to think of yourself as a “Drupal shop” and forget that other tools may do things easier and faster. Many of the sessions focused on whether or not Drupal is a CMS or a content publishing tool. Informal break-out conversations and other side conversations focused on NodeJS, REST, WordPress, and other lightweight options that only provide content management and user management frameworks. These were great reminders that Drupal isn't for everything.

5. More Tools for Multilingual Translations

Because many of our clients have an international focus, we learned about the many new tools and modules that aid in building multilingual sites. We’ve built many multilingual sites, and shed some blood and tears in the process. Thankfully, many more tools are emerging to make the job easier. A great session on multilingual in Drupal 7 pointed me to a bevy of Drupal modules that make the process a lot easier and more user-friendly.

6. Know Your Content Strategy

Several sessions mentioned NPR’s COPE (Create Once Publish Everywhere) strategy. It’s again about making content publishing future-proof and device-accessible. Drupal’s future will look like a system that allows site-builders to model all different types of content, users, and context. Representing these three things accurately will allow organizations to serve their content to the right people, in the right way, at the right time. Creating websites/pages will always be a core “feature” of Drupal, and most people will probably just use it to do that, but those who understand content strategy will really be able to harness Drupal’s abilities in a powerful way.

7. Drupal 8 Will Be Object-Oriented

Drupal 8 represents the single largest change to the code-base ever, restructuring Drupal to use object-oriented practices. This will change the project entirely moving forward. Although this is a programming change, the outcome will be sites that perform better and have shorter development cycles. Using more sophisticated design patterns, developers can more cleanly extend almost any part of the system without having to duplicate functionality. As we continue down this path, we foresee Drupal becoming more modular to allow the system to function more efficiently based on the types of requests being made, rather than loading the entire code-base into memory for even basic JSON requests. 

8. Drupal 8 Will Be More Accessible 

Major improvements are coming in Drupal 8 for accessibility. In a perfect world, websites would be just as accessible by sound as they are by sight. Drupal takes us part of the way there with some new amazing tools. The foundational HTML markup is being expanded into APIs that make it easy to express the state of page components, not just their properties. They will be available in contrib and some in core as well.

9. Drush 6 Will Be (Even) Easier for Standard Tasks

Drush 6, a command line shell and scripting interface for Drupal 8, is going to really help developers execute complex or repetitive tasks. New features in Drush will allow developers to edit views and other configuration directly through Drush. In addition, many standard tasks, such as setting up test environments, will be quicker and less costly. These updates will make developers happier and reduce the time (and costs) for many activities.

10. A More REST-ful Drupal Will Lead to More Data Sharing
Drupal 8 will ship with a powerful REST-ful interface. REST, which stands for representational state transfer, is a predominant method for enabling programmers to move content between sites and services. Making Drupal more “REST-ful” is huge, as it will allow sitebuilders to expose any Drupal data they’d like onto web apps, mobile apps, and any other device that can consume RESTful data over the internet. Drupal 8 will help push Drupal from being just a simple CMS that pushes HTML to a browser to a powerful platform that can push data to interactive web apps and mobile apps. Organizations with interesting data stored and managed in Drupal can more easily share that data to today’s devices and applications, as well as to those that haven’t been invented yet!


What is your favorite DrupalCon take-away? Share it in the comments. Interested in working with Drupal for organizations doing good work in the world? Join our team

Apr 24 2013
Apr 24

Black Duck Software recently released the results of its 7th annual “Future of Open Source” survey, and one data point in particular caught my eye.

When you think of the world’s largest and most recognized open source communities, they tend to focus on projects that are either lower on the computing stack and organized to address infrastructure needs (think Apache’s & Redhat’s projects), or consumer-focused (like Mozilla’s projects), or issue-focused (think open medical records standards and systems). But with 613 active distributions from more than 25,000 contributors, the Drupal Community is, in sheer numbers, larger than the world’s most recognized.

Apr 15 2013
Apr 15

Sites using shared databases for tables like shared users are great for sharing users between sites. It works for many other entities as well. The tricky part is using Solr indexing on this content.

The way Solr indexes things is when a new entity that should be indexed is added it is marked for Solr indexing as well. This works great but it's limitation is that the Solr index itself is stored in the current site's database. This means that if you have Site A and Site B and Site A adds a user (to the shared user table that Site B also uses), site A will mark it to be indexed by Solr. In turn Solr will add it to Site A's Solr index, but Site B still misses the Solr index marking (since as far as site B is concerned it now always existed.) To solve this problem I created a Cron job hook in a module that is used on both sites that scans the Solr index for items of a desired type and then compares them to the actual shared table to see if any are missing in the Solr index. If items are found that are not in the Solr index, they are added.

This is beneficial for many reasons. For example if you have views that use a Solr index for content you want to make sure everything in your shared table is in this index. In my case user searches in site A were missing users that were created on on Site B.

Why do a Cron hook (instead of hook_node_insert)? You need to make sure the other site is able to find the entities that it didn't create. Cron is great since it runs on both sites no matter what and checks. Insert response hooks will only work on the current site being used to add the user, but the other site is unaware even if they both share that same module. Site B will not respond to a node insert done on Site A with an insert hook.

The most important part of this is search_api_entity_insert which actually marks an item as to-index.

// Ensure that users are indexed correctly, regardless of which site they were created on.
// Since users can be created on two sites, search_api_entity_insert($entity, $type) might
// not be called, which results in an incomplete user index.
function MYMODULE_cron() {
  // Make sure search_api module exists
  if (module_exists('search_api')) {
    // I am searching for users so this is my type. This could be a different type if 
    // not being used for users
    $user_type = 'user';
    $conditions = array(
      'enabled' => 1,
      'item_type' => $user_type,
      'read_only' => 0,
    );

    // Each type in the search_api index has a different ID. That ID can be different 
    // even between sites that share the same item type so it is important to do this 
    // to get the Solr ID of the type of entity you are loading for use in the following 
    // steps. We of course will only get one index back.
    $indexes = search_api_index_load_multiple(FALSE, $conditions);
    if (!$indexes) {
      return;
    }
    
    // For the one Solr ID index found
    foreach ($indexes as $index) {
      // User type exists
      // Select all users from the shared users table that are not present in the search 
      // index on this local site.
      // Note that the users table is set to use the shared database:table in 
      // settings.php of both sites.
      // The following drupal query essentially does this sql query:
      //    select u.uid from SHARE_db.users as u 
      //      where uid not in 
      //      (select item_id from THISSITE_db.search_api_item
      //       where index_id = ThisSolrUserTypeID);

      $query = db_select('users', 'shared_u');
      $query->addField('shared_u', 'uid');
      
      $query_exists = db_select('search_api_item', 'indexed_users');
      $query_exists->condition('indexed_users.index_id', $index->id, '=');
      $query_exists->addExpression('NULL');
      $query_exists->where("indexed_users.item_id=shared_u.uid");

      $query->notExists($query_exists);
      $results = $query->execute();

      // Great idea to add a log that users are found that are about to be indexed since 
      // this is running in cron. That way if something goes wrong we can at least see 
      // that this started.
      if ($results) {
        watchdog('MYMODULE', 'Adding shared users to search index');
      }

      // $results now holds all the users that need to be indexed because they were not 
      // found in the current site's Solr index.
      foreach ($results as $result) {
        // The user record doesn't appear to have been indexed, so call
        // search api's search_api_entity_insert directly and make it so.
        search_api_entity_insert(user_load($result->uid), $user_type);
        // You can un-comment the following line if you want to see each entity you are 
        // adding to be indexed by Solr.
        //watchdog('MYMODULE', 'Adding user ' . $result->uid);
      }
    }
  }
}

As a follow up note this only handles entity adds. If an entity is removed a similar function needs to be created to un-index the entity as well. You can use search_api_entity_delete.

If there is interest or if it would be helpful we could put together a Birds of a Feather at Drupalcon Portland (2013) for this. Let us know! 

Mar 05 2013
Mar 05

On Friday, we posted the Community Plugin Toolkit to the community.openatrium.com site. This “toolkit” is a set of documentation (with code examples to follow) describing how to build Plugins for Open Atrium 2.0 in Drupal 7.

For the past several months, Phase2, with help from some wonderful sponsors, have worked to build a solid architecture and framework for Atrium 2.0. To make community contribution as productive, valuable, and easy as possible, we focused on the API and framework first. Now that we have a stable core and solid architecture, we are excited for the community to start working on Plugins that will provide much of the end-user functionality of Open Atrium.

openatrium_logo copy

Getting Started with Open Atrium 2 Development

Open Atrium 2 (OA2) was architected to make it very easy to develop your own Plugins. An OA2 Plugin is just a Drupal module, whether it comes from Apps, Features, or is just a regular module. The Community Plugin Toolkit (CPT) describes how you hook your module into the Groups and Sections that provide the structure and access control for OA2. Your Plugin can define new Content Types, Views, Panes, Blocks, Boxes, Menus, or most any other normal piece of Drupal content.

For example, let’s say you want to add an Event Calendar plugin to Open Atrium 2. You simply create an Event content type, then add some Date fields for the Start/End of the event. Then add a Google Map Address field for the Event Location. Then you add the Calendar module and create a View of your event calendar. Using the Features module, you export all of this into your own “Event Module”. Once your module is enabled in Open Atrium, you add the Group and Section fields to your Event content type as described in the Community Plugin Toolkit. Then you create a new Panelizer layout for a Section Page called Events. On this page layout you add the Calendar view to the main content region, then add an Upcoming Events view to the right sidebar.

Voila! You now have a rudimentary Event calendar landing page (Section) for a Group. The Group Admin can create a new Section using your Event layout. Members of the Group can create Event content that is assigned to their group. You can even create multiple calendars with different levels of access control, such as a private calendar within a private Section of your Group.

The built-in message and notification system in Open Atrium 2 will automatically generate messages when Events are created, updated, or deleted. You can add your own custom hooks to create a new type of message to remind members when an event is about to begin using custom email templates. You can also create templates to control how your custom event message is displayed in the OA2 Recent Activity “river”.

Creating Plugin functionality for Open Atrium isn’t much different from creating normal Drupal functionality. The steps to integrate your content types into OA2 Groups and Sections are easy to follow. You still have all of the power of Drupal, along with the enhanced content organization and access control of OA2. This architecture allows you to easily re-use your existing Drupal modules within Open Atrium.

Contributing to the Community

While Phase2 Technology continues to maintain the core components of Open Atrium 2, this distribution is open source and community-driven; so most of the functionality will come via community plugins. For example, Open Atrium 2 doesn’t have any “CaseTracker” functionality as part of the core. There are a variety of Project Management tools that different people might need, from simple “To-do” list, to Issue Tracking, to integration with 3rd party ticketing systems such as JIRA. Open Atrium does not want to dictate a specific solution hard-coded into the core project, but wants to allow different Plugin solutions to better meet customer needs.

The new architecture should make it relatively straightforward to integrate your existing modules and functionality into Open Atrium 2. By sharing your Plugins with the community you will be helping to build a world-class Open Source solution for Collaboration, Project Management, and Communications. Eventually, we will have an “App” model that can be used to easily share your Plugins throughout the Open Atrium community. We will have a Plugin browser area on the Open Atrium community site to provide a way to share information about your plugins. For now, just use Drupal.org and submit your modules as normal Drupal Projects. With the Drupal.org Sandbox functionality, any developer can get started and post their own OA2 Plugins.

Where is the code?!

We know it is difficult to start Plugin development without the actual Open Atrium 2 code base to play with. We hope to have the OA2 code put into the Drupal.org Open Atrium Project space within the next week or so. This will be very early Alpha code, but will at least give the community something to start with. Once this code is posted keep in mind that it will be missing functionality and have plenty of bugs. We will eventually enable the Issue Tracker on Drupal.org to handle patches and issues.

In the meantime, feel free to post questions or plugin announcements to the Development group on the community.openatrium.com site or contact us directly at [email protected].

Feb 27 2013
Feb 27

Posted Feb 27, 2013 // 0 comments

Are you ready to DrupalCon Portland style? Here at Phase2 we are anxiously waiting to hear which sessions get accepted, while we dust off all of our organic cotton shirts with birds on them and study up on local Portland micro-brews.

With about 600 sessions submitted to DrupalCon Portland, deciding which sessions to comment on is no easy task. After polling Phase2’s DrupalCon enthusiasts, I have created a list of the Phase2 top 10 session picks of 2013. This list is a mix of Phase2 sessions and also sessions from the Drupal Communtiy that we are really stoked about.

Check out these awesome sessions, and be sure to add a comment if you would like to see them too!

Speakers: Molly Byrnes, Steven Merrill, Brian McMurray, John Robert Wilson, and Heather Johnson

When Lady Gaga and the Black Eyed Peas are helping you promote your Sandy Hurricane Relief Campaign, you can’t get bogged down with website troubles.  See how Phase2 and Robin Hood Foundation created elegant and effective Drupal web solutions.

Add a

Speakers: Kris Vanderwater, Kristof De Jaeger, Chris Johnson, Matt Cheney, and Neil Hastings

When Drupal rock stars come together, great things happen.  You won’t want to miss these leading Drupal layout experts discussing the different ways to layout your site, and the benefits of each solution.


Add a !

Speaker: Josh Miller

We are as excited for Josh’s ecommerce presentation as his Q&A discussion at the end.  Josh has a wealth of knowledge about ecommerce in Drupal and we can’t wait to pick his mind!

Add a !

Speaker: Mike Potter

Learn what’s new with Open Atrium and how you can use the new and improved Open Atrium to easily add new functionality and integrate with other systems.  

Add a

Speaker: Michael Meyers

It is more important than ever to learn about the needs of the biggest companies using Drupal.  Learn from Michael Myers how we can move forward with Drupal enterprise development.

Add a

 

Speaker: Tobby Hagler

Tobby Hagler makes structured data and content strategy fun and approachable with his example of Dungeons and Dragons.  Tobby Hagler is a DrupalCon vetran, you won’t want to miss this!

Add a

 

Speaker: Dan Mouyard

This should be a great session for all the advanced Drupalers.  Let’s talk markup in Drupal 7!

Speakers: Brandon Morrison, Patrick Hayes, Josef Dabernig, Pol Dell'Aiera, Tom Nightingale, and Nate Parsons

 You really can’t miss the opportunity to learn about mapping in Drupal from some of the lead Drupal mapping experts around. Learn about mapping efforts to date and what’s on the horizon for Drupal 8.

Add a

 

Speakers: Kellye Rogers, Josh Turton and Rob Roberts.

Learn how Energy.gov created an innovative responsive solution and avoided having to wait for a complete redesign.  

 

Speakers: Vesa Palmul, Jeff Walpole, Fred Plais, and Michael Caccavano

The leaders from some of Drupal’s most talked about mergers, reveal how they have successfully navigated their company’s merge and the unique challenges with M&A in the services industry.

Add a

As marketing coordinator at Phase2, Annie is involved in the open source events in the New York metro area. She really enjoys engaging the lovely Drupal Community and promoting Phase2 to prospects, clients, staff members, and the greater ...

Feb 25 2013
Feb 25

I am very excited to participate in the an OpenPublic webinar hosted by Acquia this Wednesday, with my Phase2 public sector parters in crime, Greg Wilson, and Karen Borchert. Our goal for OpenPublic this year is to celebrate and highlight what can be built with OpenPublic and Drupal and how we can nurture this growing community of users.

We will start by introducing how OpenPublic works and its capabilities out-of-the-box. Then you will get to hear about the awesome new features being developed from some major government projects that use OpenPublic. We will also demo some often requested features that can be built or added into OpenPublic:

  • A new Security Application for managing user policies and authentication controls
  • A great approach on multi-lingual content built on the best core and contrib Drupal modules
  • An example of a simple API for feeding critical information to other Drupal and non-Drupal Sites

We’ll finish up with some additional examples of some of the exciting OpenPublic based projects from 2012 and what’s to come in 2013, including some community events that Phase2 is sponsoring.

As Drupal and OpenPublic mature, we want to make sure that we encourage organizations to use OpenPublic to take care of the basics, and continue to dedicate resources to contribute additional site specific development like data API’s for the community at large. We hope that the webinar will get folks excited about the great sites that can be built with OpenPublic; It’s what the distribution exists for: to provide a great out-of-box experience that can (still) be used to build custom sites.

Watch the webinar here:

Feb 22 2013
Feb 22

Simplifying Wordpress and Drupal configurationAt last year's Drupalcon in Denver there was an excellent session called Delivering Drupal.  It had to do with the oftentimes painful process of deploying a website to web servers.  This was a huge deep dive session that went into the vast underbelly of devops and production server deployment.  There were a ton of great nuggets and I recommend watching the session recording for serious web developers.

The most effective takeway for me was the manipulation of the settings files for your Drupal site, which was only briefly covered but not demonstrated.  The seed of this idea that Sam Boyer presented got me wondering about how to streamline my site deployment with Git.  I was using Git for my Drupal sites, but not effectively for easy site deployment.  Here are the details of what I changed with new sites that I build.  This can be applied to Wordpress as well, which I'll demonstrate after Drupal.

Why would I want to do this?

When you push your site to production you won't have to update a database connection string after the first time.  When you develop locally you won't have to update database connections, either.

Streamlining settings files in Drupal

Drupal has the following settings file for your site:

sites/yourdomain.com/settings.php

This becomes a read only file when your site is set up and is difficult to edit.  It's a pain editing it to run a local site for development.  Not to mention if you include it in your git repository, it's flagged as modified when you change it locally.

Instead, let's go ahead and create two new files:

sites/yourdomain.com/settings.local.php
sites/yourdomain.com/settings.production.php

Add the following to your .gitignore file in the site root:

sites/yourdomain.com/settings.local.php

This will put settings.php and settings.production.php under version control, while your local settings.local.php file is not.  With this in place, remove the $databases array from settings.php.  At the bottom of settings.php, insert the following:

$settingsDirectory = dirname(__FILE__) . '/';
if(file_exists($settingsDirectory . 'settings.local.php')){
    require_once($settingsDirectory . 'settings.local.php');
}else{
    require_once($settingsDirectory . 'settings.production.php');
}

This code tells Drupal to include the local settings file if it exists, and if it doesn't it will include the production settings file.  Since settings.local.php is not in Git, when you push your code to production you won't have to mess with the settings file at all.  Your next step is to populate the settings.local.php and settings.production.php files with your database configuration.  Here's my settings.local.php with database credentials obscured.  The production file looks identical but with the production database server defined:

<?php
    $databases['default']['default'] = array(
      'driver' => 'mysql',
      'database' => 'drupal_site_db',
      'username' => 'db_user',
      'password' => 'db_user_password',
      'host' => 'localhost',
      'prefix' => '',
    );

Streamlining settings files in Wordpress

Wordpress has a similar process to Drupal, but the settings files are a bit different.  The config file for Wordpress is the following in site root:

wp-config.php

Go ahead and create two new files:

wp-config.local.php
?wp-config.production.php

Add the following to your .gitinore file in the site root:

wp-config.local.php

This will make it so wp-config.php and wp-config.production.php are under version control when you create your Git repository, but wp-config.local.php is not.  The local config will not be present when you push your site to production.  Next, open the Wordpress wp-config.php and remove the defined DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, DB_CHARSET, and DB_COLLATE variables.  Insert the following in their place:

/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') ) {
    define('ABSPATH', dirname(__FILE__) . '/');
}
if(file_exists(ABSPATH  . 'wp-config.local.php')){
    require_once(ABSPATH  . 'wp-config.local.php');
}else{
    require_once(ABSPATH . 'wp-config.production.php');
}

This code tells Wordpress to include the local settings file if it exists, and if it doesn't it will include the production settings file. Your next step is to populate the wp-config.local.php and wp-config.production.php files with your database configuration.  Here's my wp-config.local.php with database credentials obscured.  The production file looks identical but with the production database server defined:

<?php
// ** MySQL settings - You can get this info from your web host ** //
 
/** The name of the database for WordPress */
define('DB_NAME', 'db_name');
 
/** MySQL database username */
define('DB_USER', 'db_user');
 
/** MySQL database password */
define('DB_PASSWORD', 'db_user_password');
 
/** MySQL hostname */
define('DB_HOST', 'localhost');
 
/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8');
 
/** The Database Collate type. Don't change this if in doubt. */
define('DB_COLLATE', '');

What's next?

Now that you're all set up to deploy easily to production with Git and Wordpress or Drupal, the next step is to actually get your database updated from local to production.  This is a topic for another post, but I've created my own set of Unix shell scripts to simplify this task greatly.  If you're ambitious, go grab my MySQL Loaders scripts that I've put on Github.

Jan 28 2013
Jan 28

Node Access: Who wins?

While Drupal has always had a pretty robust access control mechanism, it was difficult in the past to handle multiple contributed modules who wanted to impose different types of access control. Who wins? If a node is within a private Organic Group, but is also in a public Forum, is the node private or public? In Drupal 6, multiple access control modules could conflict and had to take special care to co-exist. It was messy.

In Drupal 7 the access control API was cleaned up and now it is relatively easy to handle multiple access control systems. Let’s learn the best way to implement your own access control system in Drupal 7.

The Perils of hook_node_access

Drupal 7 added a cool new hook for developers: hook_node_access($node, $op, $account). On the surface, this seems like the ultimate hook to control access. You simply return NODE_ACCESS_ALLOW, NODE_ACCESS_DENY, or NODE_ACCESS_IGNORE. In reality, this hook can be very dangerous! It allows you to override the access control of any other modules on your site. For example:

1
2
3
function mymodule_node_access($node, $op, $account) {
   return NODE_ACCESS_DENY;
}

This would deny access to all of your content regardless of any other access control. If it returned NODE_ACCESS_ALLOW it would *allow* access to all of your content! Unless some other module returns NODE_ACCESS_DENY, in which case access would still be denied.

Even worse, your custom hook_node_access function is ignored by Views, Menus, and other content queries on the site. Even though you have denied access to all content, you’ll still see all of your normal menu links, and will see your nodes listed in Views. Only when you click on a node to view it’s full detail page will you then be denied. You might be violating content privacy just by showing that certain content exists!

A “Deny” based approach

Drupal is a “deny-based” access control system. In other words, if anybody denies access to a node, then the node is blocked. This is similar to having multiple locks on your door: you need to open ALL the locks to enter your door. Using hook_node_access to return NODE_ACCESS_ALLOW access violates this convention and is generally a bad idea. Instead you should design your modules to DENY access when needed, and otherwise return NODE_ACCESS_IGNORE to allow other modules to decide if access should be granted. The hook_node_access results are the “last line of defense” for denying access and don’t stop Views or Menus from showing parts of the content anyway.

The correct approach is to use the Drupal “Grant” system. This API existed in previous versions, but in Drupal 7 it was cleaned up and works much better. The key hooks are hook_node_grants($account, $op) and .hook_node_access_records($node). The documentation can be hard to follow and talks about “realms” and “grant ids”. Instead, let me explain this API using the concepts of Locks and Keys.

hook_node_access_records are Locks

LocksThe hook_node_access_records is called to determine if a specific node should be locked. Your module has the opportunity to create a Lock with a specific “realm” and “id”. The “realm” is like the color of your lock and is typically the name of your module. This allows a single node to have multiple locks with different colors (multiple modules). To open the door, you would need keys that match each color of locks on the door.

Within a realm, you can have multiple locks with different “ids”. This is like giving the colored lock a specific serial number corresponding to a key with the same color and serial number. If you have a key with the correct color and serial number, than all of the locks of that color are opened. To summarize:

  • Each lock Realm (color) must be opened to access the node
  • Only one ID (serial number) within the Realm needs to be unlocked to open that entire Realm.

These node Locks are stored in the node_access database table, which means they are cached. This table is only rebuilt when you run the Rebuild Permissions in the Status Report area of your Drupal admin. When you save a node, hook_node_access_records is called only for the node being saved to allow it’s locks to be updated. If changing a node can affect the locks on other nodes, then you’ll want to call node_access_acquire_grants($node) to update the locks on the related nodes.

hook_node_grants are Keys

KeysThe hook_node_grants is called to create a “key-ring” for a particular user account. This is called dynamically at each page load to determine what keys the current user has. As mentioned above, a particular node can be accessed only if the user has the appropriate keys for each Realm (color) of locks on the node. Because this key-ring is not stored or cached, it is important to make your hook_node_grants function very fast and efficient.

When implementing hook_node_grants, you are typically only concerned about the Realm implemented by your module (remember that Realm is usually your module name). You probably don’t want to be messing with keys for other modules. Your hook just needs to decide if the user has any of *your* keys. Specifically, your hook needs to return a list of key IDs (lock serial numbers) within your Realm for the specified user account.

REAL Node Access!

The beauty of using the two Grant API hooks described above is that they are respected by Menus, Views, and optionally other queries within the database API. If the user does not have the proper keys to open the locks on a node, then the node will never display in any Menu or View. Unlike hook_node_access(), this properly protects the privacy of your content.

With Views, you can turn off the node access filtering in the Query Options of the Advanced section of the View. Turn on the “Disable SQL rewriting” option and now Views will return all results regardless of the keys and locks.

If you create your own database queries using the Drupal database API, you can also easily filter results based upon node access. Simply add a “tag” to the query called “node_access”. For example:

1
2
3
4
$query = db_select('node', 'n');
  ->fields('n', array('nid', 'title'))
  ->addTag('node_access');
$result = $query->execute();

The above example would only return the nid and title of nodes the current user can access.

UPDATED: It is important to include this addTag(‘node_access’) for ANY query that you perform that returns node results to a user. Otherwise you’ll be introducing a security hole into your module. You can also use EntityFieldQuery which automatically filters results based upon node access.

An Example from Open Atrium 2

In Open Atrium 2, we implement a flexible node access system. All content is assigned to a specific “Section” within a normal Organic Group. Each Section can be locked based upon Organizations, Teams, and Users. For example, if Mike and Karen are assigned to the “Developer” Team, and the “Developer” Team is assigned to a specific Section, then only Mike or Karen can see the existence of that Section and the content within it. To accomplish this, we implement hook_node_access_records to assign locks, and hook_node_grants to assign keys.

First, let’s assign the locks for content within a Section:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
 * Implements hook_node_access_records().
 */
function oa_node_access_records($node) {
  $sids = array();
  // handle the Section node itself
  if ($node->type == OA_SECTION_TYPE) {
    if (!oa_section_is_public($node)) {
      $sids[] = $node->nid;
    }
  }
  // Now handle pages within the Section
  else if (!empty($node->{OA_SECTION_FIELD})) {
    foreach ($node->{OA_SECTION_FIELD}[LANGUAGE_NONE] as $entity_ref) {
      $section = node_load($entity_ref['target_id']);
      if (!oa_section_is_public($section)) {
        $sids[] = $entity_ref['target_id'];
      }
    }
  }
  if (empty($sids)) {
    return array();
  }
  foreach ($sids as $sid) {
    $grants[] = array (
      'realm' => OA_ACCESS_REALM,
      'gid' => $sid,
      'grant_view' => 1,
      'grant_update' => 0,
      'grant_delete' => 0,
      'priority' => 0,
    );
  }
  return !empty($grants) ? $grants : array();
}

For a Section node, we just grab the node ID. For pages within a section we grab the referenced section IDs. Once we have a list of section IDs, we loop through them and create a $grants Lock record giving our module name OA_ACCESS_REALM as the Realm (color), and the Section ID as the ID (serial number). This adds our colored Lock to the nodes that are protected within Sections, using the specific Section ID as the lock serial number.

Next, let’s build the key-ring for the user account (*Note, this is a non-optimized version of code for instructional purposes):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
 * Implements hook_node_grants().
 */
function oa_node_grants($account, $op) {
  $sections = oa_get_sections();
  // returns a list of all section IDs
  foreach ($sections as $sid) {
    // determine if the user is a member of this section
    if (user_in_organization($sid, $account) ||
      user_in_team($sid, $account) ||
      user_in_users($sid, $account)) {
        $grants[OA_ACCESS_REALM][] = $sid;
    }
  }
  return = !empty($grants) ? $grants : array(); }

For each Section that the user is a member of, we return the Section ID for that Realm in the $grants array. If a particular node has Section locks, only users with a key to that Section will be granted access. For example, if a node has locks for $sid 1, 2, and 3, but the user only has a key for $sid 4, then access is denied. But if the user has a key for $sid 1, 2, or 3, then access is granted. You only need a single matching key within the Realm to grant access.

Conclusion

If you think about the Drupal node access system as a system of Locks and Keys, then it’s pretty easy to understand. It’s a very powerful system and one of the key strengths of Drupal. Try using this Grant API and only use the new hook_node_access as a last resort, especially when building other contributed modules where your hook_node_access might conflict with other modules.

Jan 03 2013
Jan 03

When it comes to creating layout and design, empowering content editors is key to a successful project. We learned just how important content flexibility can be while working with Robin Hood, New York’s largest poverty- fighting organization. When Hurricane Sandy hit, Robin Hood was able to use the flexible content environment that we developed for them to quickly and efficiently launch new pages detailing the mobilization of their large-scale relief effort to aid victims in the tri-state area.

Robin Hood needed a flexible content solution for their website which emphasized their vibrant design, and which could be updated quickly as their relief efforts expanded. They wanted control when it came to content layout and they wanted to be able to reuse content like their rich media, dynamic displays, and large images and videos across their site. Our solution was to develop a flexible content architecture using Template Field and a customized WYSIWYG.

 Hurricane Sandy Relief Campaign homepage, created with Template Field

We organized Robin Hood’s content by a content type called a ‘Pane,’ which has a Template field. A number of custom templates are available that allow the Robin Hood team to pick different combinations of multiple column layouts, as well as some highly interactive templates that create interactive animations, powered by Raphaël, a JavaScript library for vector graphics on the web.

A custom interactive template for Template Field called "City Stats" powered by RaphaëlJS

We developed another content type called ‘Pane Stacks,’ which is a collection of Panes stacked together to create complex and compelling pages. Jimmy Park, of Robin Hood, says, “Pane Stacks are awesome. It allows us to be so flexible and fast. Both the homepage and the [Hurricane] Sandy pages were done with ‘configuration.’ Ridiculous when you think about it.”

In addition to the flexibility provided by Template Field and the content architecture of the Robin Hood site, content editors are further empowered by a robust WYSIWYG editor within the site. Custom WYSIWYG styles help content editors to keep within brand style guidelines but still have room to customize color, font, size and spacing when deviations from the site’s styles are necessary. Additionally, content editors can easily embed blocks and Beans into WYSIWYG content, allowing them to insert video content, social media widgets, and custom interactive call-to-action elements.

 The content flexibility created with Template Field and WYSIWYG customization gives a lot of creative power to content editors, allowing Robin Hood to quickly create Hurricane Sandy Relief campaign pages, getting their message out to donors, media and others efficiently.

 A ‘pane’ with video embeds

How Template Field Works:

Template Field was developed by a group of Drupal community and Phase2 team members led by Roger López, Neil Hastings, Brian McMurray, and John Robert Wilson. From the beginning it was designed to work as a developer tool with a robust API, as well as a content administrator tool with an administrative interface. Template Field is made up of three component modules:

  • Template API – The base API for defining, loading, and working with Templates
  • Template Field – A Field API Implementation that allows users to add templates to their content types
  • Template Mustache – A rendering library for Template API that uses Mustache

The Template Field module suite was an effort to avoid having to create a different content type per layout, and then theming them differently. Instead, Template Field bundles together the HTML, CSS, JS, and specialized inputs necessary for a particular custom layout and to store all of those different layouts uniformly as a Drupal entity field. What this means is that we (or a content administrator using an admin interface in the site) can put together a package of flexible field-like inputs (text fields, file uploads, WYSIWYG text areas, checkboxes, etc), specific HTML for formatting the output (using the Mustache template library, more on that in a second), CSS for styling, and JavaScript to add interactivity. All of these things are bundled together as “templated content.” You can then create a single content type on your site (perhaps you’d call it ‘page’), add a template field, and then when creating page content, you have access to your templates to pick and then fill out with content. You could have a ‘page’ with multiple extra image files uploaded, a ‘page’ with highly interactive JavaScript, or a ‘page’ with its content divided into multiple columns – all using the exact same content type so it only needs to be themed once.

The rendering layer of the Template API is pluggable, which means that a rendering library other than Mustache could be used as well. Currently, Template Mustache is the only rendering library available.

Templates can be created in code directly, with a developer specifying inputs (like fields on a content type), and specific CSS, JS, and HTML files for the template to use; or templates can be created and managed using an administrative interface that can store template information in the database, or be exported to code later using Features. Because Mustache is a really simple template language, and because the Template API keeps input names for templates simple, even people unfamiliar with the intricacies of Drupal theming can put together new custom layouts for their template in minutes, and because a content administrator can add the CSS or JavaScript necessary for the template directly in the administrative interface, you don’t have to perform updates to your site’s theme to roll out new designs.

Template Field has proved itself in creating flexible experiences for admins to respond to crisis and unplanned relief situations. Content staging elements can also be added to Template Field to provide revisioning and permissions to the admins and content editors. We are excited to see how Template Field will be refined and used in more projects moving forward.

Dec 12 2012
Dec 12

Most Popular blocks are a pretty common requirement. One nice solution for Drupal is the Drupal Most Popular module. The Most Popular module provides several sources for your blocks, such as Drupal core Statistics and Comment modules, as well as Google Analytics (see the issue regarding Google Analytics/Reports), Disqus and AddThis, allowing you to create different block types like Most Viewed, Most Commented and Most Shared. The Most Popular module also provides a lot of nice themeing options and allows you to set up tabbed blocks without writing any code. I won’t go into documenting how the module works, as that has already been done. You may decide you just want to use blocks from Views. If you try to create a Most Commented block using the Disqus module, you quickly discover it currently only provides a field for views and not a sort option. Fortunately, this is not difficult to remedy. A simple module can be created to provide this functionality. (To be really creative, going to it: disqus_most_commented.) First, implement hook_schema in the module .install file to add a new table to hold the comment counts.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**  
 * Implements hook_schema().  
 */
function disqus_comment_count_schema() {
  $schema = array();
  $schema['disqus_comment_count'] = array(
    'description' => 'Stores counts from disqus',
    'fields' => array(
      'nid' => array(
        'type' => 'int',
        'not null' => true,
        'description' => 'nid of related node',
      ),
      'count' => array(
        'type' => 'int',
        'not null' => true,
        'description' => 'number of reads',
      ),
    ),
    'indexes' => array(
      'disqus_comment_count_nid' => array('nid'),
      'disqus_comment_count_count' => array('count'),
    ),
    'primary key' => array('nid'),
  );
  return $schema;
}

The meat of the .module file could look something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
function disqus_comment_count_views_api() {
  return array(
    'api' => 3,
  );
}
 
/**  
 * Implements hook_cron().
 */
function disqus_comment_count_cron() {  
  // Assumes the Disqus module is installed   
  // Could be made into module admin settings if it is not   
  $secret_key = check_plain(variable_get('disqus_secretkey', ''));  
  $forum = check_plain(variable_get('disqus_domain', ''));
   
  // According to Disqus api: disqus.com/api/docs/threads/listPopular/   
  // acceptable interval options are: 1h, 6h, 12h, 1d, 3d, 7d, 30d, 90d   
  $interval = '1d'; // hard-coding one day, but could make this an admin setting   
 
  // Using the Disqus php api downloaded to sites/all/libraries from   
  // github.com/disqus/disqus-php   $path = libraries_get_path('disqusapi');    
  require($path . '/disqusapi/disqusapi.php');  
  $disqus = new DisqusAPI($secret_key);  
  $data = array(); //will hold return data    
 
  try {
    $data = $disqus->threads->listPopular(array(      
      'forum' => $forum,        
      'interval' => $interval,    
    ));  
  }  
  catch (Exception $e) {    
    // Log or throw exception   
  }    
 
  if (!empty($data)) {    
    // Clear out the table and insert new rows     
    db_query('delete from {disqus_comment_count}');      
    foreach ($data as $comment_info) {
      $nid = str_replace('node/', '', $comment_info->identifiers[ 0 ]);      
      $record = array('nid' => $nid, 'count' => $comment_info->posts);      
      drupal_write_record('disqus_comment_count', $record);    
    }  
  }
} 

Finally, add a Disqus count sort option for Views in the module’s .views.inc file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 * Implements hook_views_data(). 
 */
function disqus_comment_count_views_data() {
  $data = array();
  $data['disqus_comment_count']['table']['group'] = t('Disqus Comments');  
  $data['disqus_comment_count']['table']['join'] = array(
    'node' => array(      
      'table' => 'disqus_comment_count',
      'left_field' => 'nid',
      'field' => 'nid',
      'type' => 'left outer',    
    )  
  );    
  $data['disqus_comment_count']['count'] = array(    
    'title' => t('Comment Count'),    
    'help' => t('Number of Disqus posts on a node.'),    
    'sort' => array(      
      'handler' => 'views_handler_sort',    
     ),  
  );    
  return $data;
}

The above functions are relatively simple and can certainly be made more robust, but they illustrate a straight-forward means of adding a Disqus comment count sort option for Views.

Dec 04 2012
Dec 04

OpenAtriumLast week we had a great 3-day code sprint for Open Atrium 2 (OA2) and Panopoly here at the Phase2 office in Alexandria. Joining the Phase2 Open Atrium team (Mike Potter mpotter, Peter Cho pcho, Frank Febbraro febbraro) was the Panopoly team of Matt Cheney (populist) and Brad Bowman (beeradb) from Pantheon. The goal of the sprint was to work on various issues in Panopoly/Panels that needed some improvements for Open Atrium 2. We achieved our initial agenda on the second day and spent the remainder of the sprint digging into even more detailed issues. Here are some highlights:

Access Control [#1772844 Allow More Granular Permissions in the IPE]
The goal was to control access to the IPE so OA2 Group Owners could only customize their own group and section pages. Shoutout to merlinofchaos who worked closely with Matt on IRC to get this committed and adding [#1854374 Panels IPE needs additional permission for Page Manager] to Panels itself so Group Owners wouldn’t have access to customize landing pages such as the Home page.

Allowing Multiple templates [#1790434 Panelizer panel select tab (activated with 'allow panel choice') not appearing when adding a node."]
Open Atrium 2 needs the ability to define several default page templates for Section landing pages. A Panelizer option called “allow panel choice” was available, but the list of added templates never showed anywhere. Merlin committed #1790434 to expose the selection and a Panopoly issue [#1854182 Support Allow Panel Choice for Panelizer] was added to finish looking at the access rules when using multiple panel choices.

Context (Module) and Panels [#305289 Integration with Panels module]
Many people have considered Panels and Context (Module) to be two completely different (and opposing) methods to perform site building and layout. But I’ve always thought they could co-exist and found this old #305289 issue talking about integration. Panels and Context both have their own “access rules” or “conditions” that can be used to control whether “panes” or “blocks/boxes” are displayed. And while these two sets of condition rules overlap a great deal, there are still some contrib modules that set a particular Context condition that would be nice to use to control Panels panes. Turned out to be pretty easy to write a new CTools access plugin that fires whenever a specified Context is true. The plugin simply shows a list of all Contexts defined in the Context UI and allows you to select which ones you want to use. If any of the selected Contexts are set, then the CTools access plugin returns True to select the Panels pane using that selection rule. It’s a limited use-case, but now you can use the Context module to control which panes are displayed on your page within Panels.

Media module Accessibility [#1847912 Support Alt and Title for Media Integration]
Panopoly provides excellent integration with the Media module, but there was a specific issue around Accessibility and missing Alt and Title fields. We did some testing to get sylus‘s patch applied to enable Alt and Title fields for embedded media in WYSIWYG.

Inherited Profiles [#1356276 Make install profiles inheritable]
The Open Atrium 2 distribution profile will inherit from the Panopoly distribution. We continued testing work on the core patch needed to support inherited profiles. This patch needs some D8 testing so we can get it back-ported to D7. Frank spun up a D8 environment to test and we still need to track down a warning message before marking this as reviewed.

Apps
Open Atrium 2 will be heavily based on modular “Apps”. We had a discussion about Apps and came to consensus on how we want to handle Apps between Open Atrium 2 and Panopoly to ensure as much compatibility as possible. Will continue to have further discussions with other App providers later this month to get everybody on the same track.

Multilingual
Multilingual support is important to both Open Atrium and Panopoly. We performed some testing with multilingual content and language translations. This looks pretty clean so far with the current versions of the Internationalization (i18n) module suite, so no new issues were added.

Other
We discussed and added several other issues to the Panopoly queue that we will all continue to work on. There was a great commitment from Pantheon to help work on any Panopoly issues needed to make Open Atrium 2 a success!

Beyond the technical coding details, the sprint was a great chance to exchange information about Panopoly and Open Atrium 2 and build an even better partnership for the future. Open Atrium 2 is a true win-win project for both organizations and for the Drupal community at large and it was great to see community members come together to help with these issues. It’s exactly the spirit needed to make Open Atrium 2 a great success. I look forward to having continued involvement from the Panopoly team at Pantheon in the Open Atrium 2 project!

If you are interested in following Pantheon’s lead and sprinting with us on Open Atrium 2, either in here in DC or remotely, please contact us at [email protected].

Nov 26 2012
Nov 26

As designers, we’re pretty spoiled for options to express our visual and interaction designs. That said, one tool I end up using at least a little on every project is the venerable OmniGraffle. Sometimes it’s just to draw a technical diagram or to quickly sketch a lo-fi wireframe, but in any case, I end up using it when I need to capture an idea visually in a way that’s clear and polished.  

That said, any asset you build for a project needs to be weighed against the time it takes to create it. I value good communication very highly, including artifacts, but there isn’t an unlimited amount of time; to turn to Graffle instead of throw-away paper or long-lived prototypes, it needs to be the right tool for the job and I need to be fast with it.  

To speed up working in Graffle, one of my favorite “tricks” isn’t a trick at all, it’s right on the default toolbar (you have already customized your toolbar, right?): the inspector palette. If you’re not familiar with the Graffle’s Inspectors, you may not know that they actually have a host of behaviors that normal palettes in OS X don’t, and they’re all useful:

  • Tabs can be made sticky: when you select another tab, they will remain open
  • Groups of tabs (Style, Properties, Canvas, and Document) can be moved around independently
  • Each group has a keyboard shortcut (normally command-1 through 4) to quickly show and hide

When I’m working I tend to be in a particular mode, and I’m going to go back to the same tabs, group of controls, over and over again. For instance, when I’m quickly building a new diagram I’ll rough it in with lots of boxes, and for each shape I’ll change the color and stroke. In this mode, I want quick access to Fill and Stroke tabs, so I just do the following:

  1. If not open already, open the Inspectors (from the document toolbar, from the Inspectors menubar command, or with the keyboard shortcut cmd-shift-i)
  2. In the Style group, double click the Fill and Stroke tabs (they’ll get a little green lock icon when you double click them)
  3. Grab groups 2-4 and drag them to snap them off  and position as you want (or close them entirely)

OmniGraffle Style Inspector  with Fill and Stroke locked and Shadow Open

The result is that right after I place an element, I can quickly change all it’s settings without having to open or change items (If I need to, I can open other tabs without closing Stroke and Fill). It may sound small, but this actually helps flow a lot: you don’t need to remember where things are or switch tabs constantly. There are also other advantages, for instance, you can drag color swatches between tabs, from fill to stroke or vice-versa. You can also position other palettes exactly in relation to your fixed controls; I like to put my color picker right next to the Style inspector, so it’s a quick trip to get a new color.

When I’m finishing up a diagram, I’ll tend to swap modes, and want to have easy access to the Canvas’s alignment tab and properties. Quickly hitting cmd-1 will close my Styles group (saving what I’ve locked). I can quickly open up my alignment and property controls in the space where my styles just were. 

If you’re not picking your Inspector tabs for the mode you’re in, give it a try. It may take some tweaking, but you’ll probably find one or two arrangements that you grow to love and help you complete tasks quickly.

(Note that most other apps in OS X don’t sport all these behaviors. However, in some apps, such as iWork, you can option click inspector tabs to open up multiple inspector windows.)

Nov 26 2012
Nov 26

"Show More" buttons help content managers display less text when they want to have a more visual layout. Recently I had the task to make a "Show More" button and functionality that is as reusable as possible. Most "Show More" scripts that are out there function on word/character counts. However, this one needed to use a pixel height restriction. In my case, the solution should target a HTML element (by class name) and restrict its height to 300 pixels as well as hide the overflow from that restriction. It should also append a "Show More" button after the shortened targeted element. When the "Show More" link is clicked the shortened region should expand to it's full height and the "Show More" button should disappear.

I chose to do this with JQuery for portability. This was used on a Drupal site so the code was wrapped in a Drupal Behavior. This can of course be taken out the behavior wrapper function and used anywhere JQuery is available.

Besides reading the comments and code below, the main points to keep in mind is the script targets a DIV tag with a class of "show-hide-more." It reduces the hight/cut-off to 300 pixels. These can of course be changed or made into variables to enhance the script. Also this script assumes there will only be one DIV with that class on a given page. The script can be enhanced by expanding it to use the array and array offset on the target variable "hiddenContent."

Drupal.behaviors.globalFunctions = {
    attach: function(context, settings) {
        /* The following adds Show More link and functionality to a Div with a show-hide-more class name */
        // If the following class name is found on a block
        if( $('div.show-hide-more').length > 0) {
            // Cache a reference to the hidden content.
            var hiddenContent = $('div.show-hide-more');

            // Quickly grab the full height before it is reset
            fullHeight = hiddenContent.height();

            // If the full height is greater than 300 pixels
            if(fullHeight > 300) {
                // Set smaller height
                hiddenContent.css({'height': '300px', 'overflow': 'hidden'});

                // Add Show More link that will trigger height expand
                hiddenContent.after('Show More');

                // Bind to the Read More link to toggle the
                $('a.showMore').click(
                    function( event ){
                        // Cancel the default event (this isn't a real link).
                        event.preventDefault();

                        // Show full height and change overflow with slow animation effect
                        hiddenContent.animate({
                            height: fullHeight, overflow: "visible"
                        }, {
                        duration: 400,
                        complete: function() {
                            // Hide Show More button after animation finishes
                            $('a.showMore').css({display: "none"});
                        }
                        });
                    }
                );
            }
        }
    }
};
Nov 19 2012
Nov 19

Posted Nov 19, 2012 // 0 comments

As Drupal is adopted by larger organizations, there are more administrators, editors, and content creators that are working on large-scale Drupal sites. The need for an efficient and intuitive process for creating, editing, and publishing content has become increasingly important.

The Content Staging Initiative is an effort in the Drupal community to explore and build a system for content staging and management of publications on a Drupal site. This work has fueled new modules that enhance site preview capabilities, content “staging” for multiple publishing scenarios, and improved editor’s workflow tools.

To illustrate how these tools can be used for publishing, let’s look at how a prominent news site, covering an international soccer game like the Spain vs. Netherlands match in the 2010 World Cup, might use content staging.

Leading up to the game, content administrators would add news articles, images, and editorials about each team. To prepare for the match’s win, editors and reporters would create full content for two scenarios: one in which Spain wins and one in which Netherlands wins.

Netherlands Win Scenario

Content editors can effectively create two versions of the same home page for either scenario -- with content and layout revisions for each. Each scenario is classified in a “collection”, and each node of content (an article, image, or editorial) would be tagged for the Spain or Netherlands Collection. Editors can then use the site preview system to approve how content and layout looks on the site before it is published in either scenario. The Interactive Information Bar Module is used to alert the editor that he/she is in preview mode.

With the Content Staging Modules installed, the editor can review these articles using the Real-Site Preview Module. This module allows editors to see how the site will look with either “collection” of content in place.

When the game is officially over, editors know that Spain has won, and can act quickly to enable the Spain collection of content. Using the content revisions tab, the editor can quickly filter for all articles, images and layout edited for a Spanish win - including the homepage revised block and revised layout prepared for this scenario.

Then after making final copy edits and last look-over, they use the Node Revision Administration (NRA) Module, to select and publish the Spanish win coverage in bulk. Instantly the news site is completely up-to-date with the latest breaking World Cup coverage. Images and layout related to Spain's victory are perfectly configured since the editorial setup can be planned far in advance. This puts the editor in the driver's seat to execute a perfectly up-to-date site, ahead of the competition.

Content staging will help digital workflow in many important ways. This system allows an organization to look at content at any stage of revision and see what it looks like in the context of the entire site before the content is published live. Content staging can be used for:

  • Performing real site previews of content with certain parameters before the content is published
  • The approval process for a landing page layout before it goes live.
  • Looking at a piece of content at any point in history or in the future, and seeing how it looks with affected changes.
  • Publishing bulk publications with revisions
  • Efficient content staging and workflow is crucial for larger organizations who have several people working on content publication, and who need to curate and publish their content very quickly, according to unfolding news, rapidly updating events, and even sports wins and losses.

    The Content Staging Initiative is an exciting development in Drupal digital workflow. Currently, the CSI team, made up of developers from around the Drupal community, is working on improving workflow and revisions to support non-node entities in collection build operations. Stay up-to-date on the Content Staging Initiative by following the CSI Drupal Group announcements.

Team Architect at Phase2, Neil thrives on working with the development team to come up with creative implementations for complex situations. Neil enjoys pushing Drupal past its boundaries to implement cutting edge concepts, and has a ...

Nov 15 2012
Nov 15

Posted Nov 15, 2012 // 4 comments

Drupal can be a scalable platform that can handle high traffic and serve large volumes of data easily with the proper configuration set up and server layout.  The large number of themes and modules in the community makes site development extremely easy and valuable in a sense that you can develop a large set of features in a short period of time without too many hours burned on coding everything from scratch.

 

Knowing this, it’s tempting to simply install everything within your site.  However, if you are going to maintain a high-traffic website, it might be a good idea to offload some of these features elsewhere.

Plan and determine what features of your site should be maintained within your installation and which features should be hosted from external sources.  I’m not saying you should start copying and pasting embed codes from third party websites or start hosting all subsets of data and media files on separate servers.  More so, I recommend that you should entrust third party services to take care of certain features (especially if they can do it better than what exists in the module space) to minimize risk and increase performance.

There are plenty of modules that can help you with this.  For example, rather than use Drupal’s internal commenting module, you can rely on Facebook or Disqus to handle this for you.  Google Analytics is another way to analyze your site’s traffic externally.  I am also fond of other modules such as Paypal and Intuit Merchant Services, which handle credit card payments elegantly for you without the hassle of worrying about security right off the bat (assuming you configure your SSL certificates correctly).

Sharing (work) is caring!

So if, for example, all the comments on your site take up half the server space, wouldn’t it be nice to have someone take care of that so you don’t have to buy more server space?  You might be better off outsourcing that functionality elsewhere so that you can focus on more obscure features on your site.

I would suggest this approach for many reasons:

  • Reliable support for the application by a team of dedicated maintainers focused on one (or a few) functionalities

  • You can switch these features out with careful modularization

  • Simplifies your site’s architecture…and your job

  • More features outside Drupal’s framework

  • The features are readily available (in most cases)

  • More cost-effective (since the pricing is catered to sharing resources amongst multiple websites)

  • It’s kind of like running your website on several sites at the fraction of the cost (since these external services price their services efficiently to share them across various clients)

But do you trust other people with your information?

 You have to consider the potential repercussions that might occur if you do indeed take this route.  If you do decide to take this route, you should ask the following questions before you make the big move.

  • Is the service reliable?  If the service goes down, will my site go into utter chaos?

  • Is the data exportable?  If I build a new version of the site later on or if I want to use a different solution later, will it be easy to migrate it?

  • Does it have all the features I need and (a lot) more?  Can I trust that I won’t have to move to another solution 6 months from now?

  • Do I really want to own the data?  Will it be difficult to customize it however I want for my own needs?

  • Do I want to be liable for protecting the credit card numbers and other sensitive information in my database?

  • What does the terms of service say?  Do you truly own the data, or can they use it for certain purposes?

  • Do your users trust whoever is handling the data outside the site?  Will it tarnish your site’s reputation if you put it on the site?

You shouldn’t take some of these questions lightly.   Using a credit card processor with a history of data leakage or advertisement software that serves annoying and potentially malicious advertisements can ruin your site’s reputation.  It would be wise to do your research on anything you do externally before you implement it on your site.

Couldn’t I just create these features myself on my own separate servers?

If you have the funding and bandwidth to do it, go for it!   Many opt to use the Apache Solr module to delegate the search functionality away from the main site’s server to achieve this.  This approach is common and not unheard of.

Doing this requires more manpower.  Even if the features are developed externally, you still need to upgrade them internally.  Features maintained externally typically have the advantage of acquiring upgrades without a need to do anything on your end (that’s the beauty of webapps!).  Going this route, you should always subscribe to their blog to make sure you're aware of any changes they make on their end.

Note: At this point, you might think doing all this implies laziness.  Rest assured!  There is nothing wrong with good lazy, however, as long as you achieve the goal at hand.  When the job is done, the amount of work done on your end is trivial as long as you have the research and documentation to handle any future tasks proactively (i.e. be aware of any caveats and risks when using a service, and keep note of any muddy scenarios not covered by their guarantees).

In conclusion…

Remember a decade ago when things rarely ran on APIs, and most site maintainers typically have to copy and paste embeddable codes to achieve the same thing (not to mention the site’s architecture being bloated and messy after a while)?  In some cases, a lot of the code back then didn’t really fit everyone’s needs, so you tend to have a lot of duplicate codebases across sites that tend to go stale months after it gets implemented.

Consider it blessing that we’ve gone all this way to weave various web services into existing sites much easier while tapping into polished features without a sweat on your end!

As a Phase2 developer, Peter Cho strives to create elegant and efficient solutions to provide a positive user experience for clients.

Prior to joining Phase2, Peter worked for the Digital Forensics Center developing marketing and web ...

Nov 13 2012
Nov 13

Posted Nov 13, 2012 // 2 comments

Theming in Drupal has been complicated and difficult, particularly when approaching the problem of websites with multiple layouts.  We've all seen sites with dozens of tpls, with code written into templates, with mile-long preprocess functions covering multiple possibilities… It can be messy!

But it doesn't have to be this way. The addition of just a few modules, and a solid base theme, allow a site's layout to be configured without writing a single line of code. This was the topic of Omega: From Download to Layout in 45 Minutes, my presentation at BADCamp. This post will cover just one part of that, creating a layout for one of the wireframes without writing a single line of code.

Dev Site Setup

We'll make the assumption that you have a dev site set up, with the appropriate content types and some demo content to support this site, along with a few views and utility blocks.  You have also installed the Omega base theme and created a new sub-theme, titled Epsilon.

Wireframes

The site is laid out using 960gs, a popular grid system. For more information on 960gs, visit their site.
Here's a view of the section/content list page wireframe.

Layout

An alternate view of this layout clearly shows the columns widths used for layout on the grid.

The core of layouts in Omega lies in the Zone and region configration tab. Regions should be familiar to us from block admin - that's been around for a couple Drupal versions.  Regions are where you put your content and blocks. But what are Zones and Sections?

Think of them as larger containers into which the zones are placed, in a hierarchy.  Sections are the largest, and can have one or more zones inside them. Zones are next, and can have one or more regions inside them. Finally come regions, this is where the grid is really laid out, as Omega makes them quite easy to size by columns. These serve to wrap and contain your HTML, allowing for common styling and easy layout choices.

In this third view of our wireframe, we clearly see three different sections.

Header Section

Let's start by looking at the header section in detail.  The wireframe really only contains one zone, with two regions: logo and menu. Opening the Header Section configuration menu in Omega, on the Zone and region configuration tab, we see that this section actually has 4 zones, with a total of 6 regions in it – clearly too many for what we need, but a nice example of how versatile Omega is.

Omega allows us to move zones from one section to another, or even to disable them altogether.  We do this by opening each zone's fieldset, then the configuration fieldset within that, and setting Section to – None –.

In this case, we'll start by doing that for User Zone and Header Zone.

Next, we set the width of the Branding Region in the Branding Zone to 4 columns.  This is where we will put our logo, which if you recall was 4 columns wide.

After that, we go to the Menu Region in the Menu Zone, and set the width to 8 columns, as laid out in our wireframes. Weighting in Omega works just like it does anywhere else in Drupal – the higher the weight, the later the item renders in the process, so we set the weight to 5 to push the Menu Region after the Branding Region. And, again, Omega allows us to move a region from one zone to another, so we move the Menu Region to the Branding Zone. This will stack the Branding and Menu regions horizontally without any additional CSS.  Doing this leaves the Menu Zone without any regions, so as a last housekeeping item we set the Section for Menu Zone to – None –.

Content Section

The Content Section comes with three zones by default.  I'm going to leave the Preface and Postscript Zones alone for now, and work in the Content Zone of the Content Section.  Yes, there's a Content Section, and a Content Zone, and guess what?  There's a Content Region, too.  Naming things in Drupal is not an exact science.

We're going to focus our attention for now on the Content Zone.

In the Sidebar First region, I'm going to set the width to 4 columns, and set the weight to 5.  Again, a higher weight will push the item later in the rendering process - in this case, after the Content Region.

I'll set the width of the Content Region to 8 columns, and leave the weight alone.

Finally, I'll set the Zone of the Sidebar Second region to – None –, which will remove it from the Content Zone altogether.

Lastly, in the Footer Zone of the Footer Section, I'm going to set the width of the Footer First region to 8 columns, and the width of the Footer Second region to 4 columns. Since these two regions are already in the same zone, they will line up horizontally automatically, so there's no need to move them around from one region to another.

Save and view the page. Here's what a default Omega sub-theme looks like, out of the box.

And here's what Epsilon looks like now.

All that – and no coding!

Delta and Context

The problem of applying different theme settings – layouts – to different pages remains, of course.  That's where the delta and context modules come in.  For a more thorough explanation of how they work, see the slides from the full presentation at our Slideshare.

Thanks!

Senior Developer Joshua Turton brings a wide variety of skills to his role at Phase2. A programmer comfortable working on both front-end and server-side technologies, he also brings a strong visual sensibility to his work. More than nine years ...

Nov 01 2012
Nov 01

Posted Nov 1, 2012 // 21 comments

A Renewed Focus

Open Atrium has long been the go-to "Intranet in a box" distribution for Drupal 6.  Obviously, Drupal 6 is nearing it's official "end of life" and something needed to be done with Open Atrium.  The question for the past year has been: "What exactly should be done?"  Should we just port the existing modules to D7?  Should we just leap-frog to Drupal 8?  What about new functionality?  What about improving existing functionality?  How do we make Open Atrium more accessible to more types of users?  How do we take advantage of new Drupal 7 components?

We have spent the past year collecting feedback and suggestions from existing and potential Open Atrium clients regarding these questions.  Since DrupalCon Munich we have developed a detailed plan for moving forward with Open Atrium in Drupal 7, have put together a new internal project team, and have finally started development!

I'll be posting more technical details about the new Drupal 7 architecture for Open Atrium 2.0 to the community.openatrium.com site soon and will also be presenting a BoF session at BADcamp 2012 this weekend.  But here are some teasers on what we've been doing and what is coming.

A New Project Team

Like most firms, Phase2 Technology makes its business doing paid client projects.  Performing Drupal module maintenance and building Drupal distributions is something we try to make as much time for as possible to help support the Drupal community.  Fitting this in-between projects works most of the time, but large projects, such as a full Drupal 7 rewrite of Open Atrium, are more difficult and require a greater commitment.  To better achieve this goal, we have put together a full internal project team for Open Atrium 2.0 (OA2) and are treating it the same as a regular client project.  We are actively seeking sponsorship for this work, but also putting a large amount of Phase2 resources into this project.   In fact, Phase2 will be matching dollar-per-dollar any external sponsorship, so please email us if you are interested in funding some of this work.  With this new project team in place, and myself as the new technical lead for the project, you will now see increased momentum behind Open Atrium 2.0.

Open Atrium 2.0 Architecture

When facing a large site migration from Drupal 6 to Drupal 7, it's usually best to use this as an opportunity for improvements to the architecture of a site.  Drupal 7 brings many new core concepts to a project, including Entities, improved node access control, etc.  For Open Atrium, a new architecture was required to take full advantage of these new concepts.

The core concepts of the Open Atrium 2 architecture are:

  • Flexible and modular feature components (Apps)
  • Flexible layout customization (Panels and Panopoly)
  • Mobile-friendly, responsive base theme (Zen or AdaptiveTheme)
  • Improved user, group, section, team permission system
  • Customizable notification and subscription system
  • Plugin API based upon Entities
  • Available as a distribution, or just a set of Modules

More than just an "Intranet in a box", Open Atrium 2 will be a Framework for integrating your existing systems into an intranet.  OA2 will come with very simple and basic "features" for collaborative discussion, file organization, events, tasks, etc.  However, in each case the "simple and basic" App can be removed and replaced by an App with a high-level of integration with existing best-in-class business systems.OA2 Architecture

New Features

Open Atrium 2 adds several new core concepts that make it even more flexible for your organization.  First, rather than seeing a set of "tabs" for each App (Discussion, Files, Calendar, etc.) a Group Owner can create custom "Section" pages and place any combination of available "widgets" on each page.  You can use the default section page layouts to recreate the OA 1.x tab pages, or you can creatively combine various elements into your own section page layouts.  For example, you can create multiple different Discussion areas within your group, or combine a view of Tasks with your Event Calendar on the same section page.

OA2 TeamsYou can also assign "Teams" to a "Section".  A "Team" is a collection of Users, similar to Members of a Group.  A Team might indicate a user's Organization, or Department, or any other collection.  Each User can be a member of multiple Teams.  When Teams are assigned to a Section, only users who are both a Member of the Group and a Member of an assigned Team can access the Section.  This allows a Group Owner to create sections within their group with different Team access, such as Private section pages.  For example, Mary might be a member of the NewWebSite Group and might be assigned to the ProjectManagers Team.  The Group Owner  could create a new section within the NewWebSite group and assign the ProjectManagers team to it.  Mary would be able to read and post content to this new section, but Bob, who is a member of the NewWebSite Group but not in ProjectManagers would not be able to view the section.

Beyond some of these new concepts within the core of OA2, the real power of OA2 comes from its modular App design.  In Open Atrium 1.x it was possible to create a new plugin Feature.  But the plugin architecture was poorly documented and difficult.  In addition, the theme used for Open Atrium made it difficult to customize for many customers.  In January, we will release the new Community Plugin Toolkit which will contain documentation and examples for creating Open Atrium 2 plugin Apps. This Toolkit should make it much easier for the community to contribute new Apps for OA2.

Moving Forward

In addition to releasing the Community Plugin Toolkit in January, the first Alpha version of Open Atrium 2 is planned for Spring 2013, with the initial Beta version to be released in time for DrupalCon Portland in May 2013.  If you are interested in helping sponsor work on Open Atrium 2, or wish to be involved early in building OA2 Plugin Apps, please contact us directly via email .  I am very excited about the future of Open Atrium 2 and look forward to delivering the Intranet product and framework that you have been dreaming about and waiting for.

Mike Potter is a Team Architect at Phase2 who loves to pair a solid technical solution with an intuitive client-focused design. Mike started his career as an experimental neutrino particle physicist before creating the first WWW home page for ...

Oct 29 2012
Oct 29

Posted Oct 29, 2012 // 0 comments

Here at Phase2, we are very excited for the long anticipated BADCamp 2012 (BAY Area Drupal Camp) to kick off in 2 days!  With even more attendees than last year, this event promises to be an epic Drupal-tastic adventure! As a proud contributing sponsor and Product Summit sponsor, we are looking forward to seeing our old Drupal friends and meeting new ones around the camp and at our booth, (so don’t forget to stop by!)

BADCamp is one of the largest free Drupal events in North America and therefore, a testament to the Drupal community’s devotion to accessibility and contributing back.  We know Drupal camps are integral to the growth and innovation of Drupal and that’s why we are committed to participating with sponsorships, volunteer organizers, and submitted sessions.   This time around we are shipping out a troop of some of Phase2’s finest! Here’s where you can find us:

Let’s Talk...

Business

Products:

Community:

Mapping:

Government in Drupal:

Theming:

Deployment and Infrastructure:

Content Management and Versioning:

We are looking forward to sharing our ideas but we are also excited to learn from everyone else! Check out the complete lineup of awesome sessions at BADCamp. We’ll see you there!

As marketing coordinator at Phase2, Annie is involved in the open source events in the New York metro area. She really enjoys engaging the lovely Drupal Community and promoting Phase2 to prospects, clients, staff members, and the greater ...

Oct 25 2012
Oct 25

Posted Oct 25, 2012 // 2 comments

 Earlier this year at NYC Camp and DrupalDay ATX, I got to talk about my favorite subject: products and distributions in Drupal. And at the upcoming BADCamp Product Summit on November 2, I'm going to get to share ideas and learn from the top firms building products and distributions in Drupal. 

Products and distributions occupy a really interesting space in the Drupalsphere. After seeing Drupal's growth into a mature framework and platform, the natural next question is: "Where can we take this now?" Can Drupal be used to power stand-alone products? Can it be the basis of SaaS-hosted site building platforms? Are distributions best suited as tool kits for developers? Or should they be used to build "site in a box" solutions that reach a larger market of site builders? These are the questions our own product teams grapple with regularly, and that drive our work on our own distributions. 

But Drupal (and open source, generally) presents a second, perhaps even more important question. Beyond "what CAN we build?" lies the question "How do we take Drupal products to market, the Drupal way?" How do we make sure we aren't sacrificing community goodwill, collaboration and contribution, and general open sourceyness, while still deploying the business models that will sustain these "Drupal products" and their further development? 

To address the multiple decision points and questions of when, how, and sometimes, what to build when considering a distribution, OpenPublic technical lead (and dear friend) Erik Summerfield and I built a decision tree, tracking the many motivations, aspirations, and assumptions that we have seen in building distributions in Drupal. Our disclaimer to this decision model, which we gave in New York and Austin: none of this is meant to say that at Phase2, we've avoided every pitfall and done it perfectly. Quite the contrary. This is the result of early missteps, some challenging internal conversations, some hard decisions, a little well-earned community criticism, and ultimately, a lot of lessons learned. We share it not to say "we know how to do this" but to say "we're all navigating this together -- let's do it smarter."

Without further ado, here's our decision tree. (oh, and if you'd like to "zoom" through it, feel free to click through the prezi version online. 

We started with the question "why" because so often, when we talk to people about using or contributing to distributions, the first thing we hear is "oh, we're thinking about building a Drupal distribution." And our natural next question is "Why?" Distributions are expensive to build, more expensive to maintain, and can be community suicide if handled poorly or neglected in the long run. Knowing up front whether you have a good reason to build a distro -- be it to build your brand and reputation, to create new offerings or business models, or to have a "base" for future builds, is vital to what you build and how you build it.

Once you know why you're building a distribution, there are a few decisions that might help to ensure that you're preparing for your distro to be a useful, sustainable, and well-supported product in our community. Checking to be sure that your team has built sites that solve the problem you're trying to solve and that you have people on your team who know Drupal, understand what it's like to contribute to Drupal, and know how to navigate the community can save a lot of time and energy down the road. 

Finally, thinking ahead of time about your distribution's total cost of ownership can mean the difference between a successful experience and a distro disaster. Thinking about what it will cost to build, maintain, document, support, train, and market your distribution, and where you'll find the revenue models to support that cost, is absolutely key. 

It's not an easy set of questions -- but when we're trying to find out "where can we take Drupal now?", it's vital to ask ourselves the hard questions (and a lot of them) in order to hold our work to the highest standard. If you want to jump into these questions (and more) I hope you'll join us at the product summit next week. We're excited to join the discussion among awesome, product-minded companies like Commerce Guys, Pantheon, Acquia, ThinkShout, Volacci, Gorton Studios, and Aten Design Group

As a product director with us, Karen Borchert keeps Phase2 growing each day; she focuses on the business strategy for our products, including OpenPublish and OpenPublic.

Thanks to her deep background in product strategy, Karen can ...

Oct 24 2012
Oct 24

Posted Oct 24, 2012 // 6 comments

We've recently released another beta release (beta5) of Openpublish. We've updates various modules and provided some minor bug fixes. The main addition in this release is that we've added a bulkupload functionality for the Photo Gallery in Openpublish. This allows content creators and editors to upload many photos quickly and easily into the field collection which makes up the gallery. This works very similarly to the way that filefield_sources_plupload module (and other plupload implementations work. It provides a drag and drop interface and multiple file select along with concurrent uploads and upload progress. See the embedded video for a very quick demo of how it works. We are still working to improve the gallery and image support in OpenPublish in a robust, predictable way that reflects the structure and usage of the data, and that is extensible and works consistently.

The gallery bulkupload is a feature that was requested from the issue queue. As we contrinue to improve and stabilize OpenPublish, community participation becomes increasingly important. Understanding what features are desired, what is working and what isn't and how OpenPublish can be improved, along with the reporting of bugs and any code contributions, drive OpenPublish forward. At Phase2 we have experience from our clients about what publishers want and how they use Drupal. We take this knowledge and use it to try to construct a base of a site, something that has the basic tools which we would use to build a publishing site. However, often we don't know exactly what others in the community use to build sites, what requirements they or their clients have, and what value various clients and users ascribe to a given feature. Having more use cases to base OpenPublish off of will help us to improve the overall quality of Openpublish and make it more usable for the community as a whole.

Now obviously we can't implement every feature, find every bug or accomodate every use case. However, the more feedback, bug reports and patches and community support, the more bandwidth we have to work with. Please continue to ask questions, post bugs and contribute in any way you can on the Drupal.org issue queues. In order to let others benefit from answers, known bugs and available patches and fixes, please keep all the bug reports and support requests in the Drupal.org issue queues.

Senior Developer Josh Caldwell specializes in pairing a beautiful, intuitive interface with a solid, well-designed backend product. His ability to identify open-source solutions and front-end capabilities allows him to write impressive, ...

Oct 23 2012
Oct 23

Posted Oct 23, 2012 // 0 comments

To better fulfill its mission to increase disaster preparedness in the U.S., the Department of Homeland Security (DHS) decided to migrate its public-facing website from a proprietary CMS (Teamsite) and onto a new, modernized, and open source platform.  DHS selected Drupal as this new CMS platform, and the OpenPublic distribution was an important part of standardizing the agency’s migration to Drupal. The new site was launched in August 2012, and took roughly 4 months to design, develop, and deploy.

The new DHS.gov site is a huge success for DHS, it's also another big milestone for open source in government.  One of the main reasons for the site’s success is that it leveraged the existing FEMA.gov platform (which was developed on OpenPublic), giving it a jump start toward a finished product.  DHS.gov is a case study for the concept of a “Shared Platform” approach, as outlined in the Digital Government Strategy (and embodied in earlier materials, such as the “Shared First” principles).

The DHS.gov Requirements

 Above all, DHS wanted a re-vamped website that improved their web content operations by providing the following:

  • Improved administrative interface
  • Upgraded technology
  • Enhanced functionality

Also, a goal of this project was to extend the existing FEMA.gov platform to better enable the various DHS subcomponents (e.g., Immigration and Customs Enforcement (ICE), Customs and Border Protection (CBP), Transportation and Safety Administration) to get into the Drupal platform. This is a great example of promoting shared solutions throughout an agency in a very concrete way. With this model, subcomponents that migrate onto the platform will promote an agency-wide web content “infrastructure” that is more easily and efficiently maintained.

Like all government sites, DHS had to comply with 508 compliance, FISMA, and cross-browser accessibility.

The Solution

 DHS selected Drupal and they also selected the OpenPublic Drupal distribution since it provides ‘out-of-the-box’  enhanced features that would benefit DHS right out of the gate. For example:  a slideshow and carousel rotator, a streamlined administrative dashboard, and flexible customization. OpenPublic also provided important head starts on security and accessibility features that were requirements for the DHS.gov site.  Moreover, since OpenPublic is built on the Omega base theme, DHS can easily get onto responsive design and make its content much more mobile friendly.

On the public facing side, the topic based taxonomy implemented, provides an easy way to navigate to site content and enables users to view pertinent related content. On the administrative side, DHS.gov uses the Drupal Workbench module to handle content administration workflows. With many users and roles, Workbench allows users to quickly move content through workflow and allows editors and publishers to be notified easily when content is ready for their review.  Another distinguishing element of this site is the flexibility in creating "sidebar" content for article pages.  A user can cross-reference content easily using node references, creating external links, or add their own content to create a useful sidebar to articles featured on the site.

OpenPublic is built and maintained in a way that keeps an eye out on federal government web regulations - specifically requirements surrounding the Open Gov initiative  and the Federal Cloud Computing Initiative.  Since it's built on OpenPublic, it provides the security, accessibility and usability that federal government sites require.  And, because Drupal is an open source platform, it saves the federal government from having to maintain annual licensing fees for expensive, proprietary CMS’s.

It was a pleasure working with the DHS team, DHS’s adoption of Drupal and OpenPublic is representative of innovative government within the face of constrained resources.

As Phase2’s Federal Practice Manager, Greg Wilson is responsible for the success and direction of the company’s support to federal government clients. In this role, he provides guidance regarding Phase2’s role in helping to ...

Oct 22 2012
Oct 22

Posted Oct 22, 2012 // 0 comments

Some time back, I wrote a blog post entitled Compound fields in Drupal 7 where I discussed how to create custom fields for your content types using Field API. Since then, I've often been asked how to create custom fields for use in forms (using Form API), outside of using those fields in entities such as nodes and taxonomy terms.

Assuming you've read that blog post, I'll now show you how to extend an existing custom field into a form element that you can use in any FAPI form.

Hooks

To extend your field, you'll need to add some additional hooks to your module. It's important to note that you can extend any field into a form element that exists in Drupal, not just something defined by your module.

hook_element_info -- This hook tells Drupal about your form element.

1
2
3
4
5
6
7
8
9
10
11
12
function dnd_fields_element_info() {
  return array(
    'dnd_fields_attribute' => array(
      '#input' => TRUE,
      '#tree' => TRUE,
      '#process' => array('dnd_fields_attribute_process'),
      '#element_validate' => array('dnd_fields_element_validate'),
      '#theme' => array('dnd_fields_element'),
      '#theme_wrappers' => array('form_element'),
    ),
  );
}

Process Functions

In hook_element_info, we named a processor function that will define how our new form element should be processed.

In this example, we are "faking" a field instance so that we can reuse the field widget defined in hook_field_widget_form (dnd_fields_field_widget_form). If you prefer, you can skip to the next code sample to create a standalone element processor function without relying on what requirements this Field API hook has.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function dnd_fields_attribute_process($element, &$form_state) {
  // Create a dummy field instance just to get the same output from our existing field widget
  $instance = array(
    'field_name' => 'dnd_fields_ability',
    'settings' => array(),
    'widget' => array(
      'type' => 'dnd_fields_ability',
    ),
  );
 
  $form = array();
  $field = array(
    'settings' => array(
      'abilities' => array(),
    ),
  );
  $langcode = LANGUAGE_NONE;
  $items = array();
  $delta = 0;
  $form_state['field'] = array(
    'dnd_fields_ability' => array(
      $langcode => array(
        'field' => array(
          'type' => 'dnd_fields_ability',
          'cardinality' => 6,
          'settings' => array(),
        ),
      ),
    ),
  );
 
  $element = dnd_fields_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
  return $element;
}

If you are creating a new form element that does not come from an existing field, you will want this instead:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function dnd_fields_attribute_process($element, &$form_state) {
  $fields = array(
    'ability' => t('Ability'),
    'score' => t('Score'),
    'mod' => t('Modifier'),
    'tempscore' => t('Temp score'),
    'tempmod' => t('Temp modifier'),
  );
 
  foreach ($fields as $key => $label) {
    $element[$key] = array(
      '#attributes' => array('class' => array('edit-dnd-fields-ability'), 'title' => t('')),
      '#type' => 'textfield',
      '#size' => 3,
      '#maxlength' => 3,
      '#title' => $label,
      '#default_value' => NULL,
      '#attached' => array(
        'css' => array(drupal_get_path('module', 'dnd_fields') . '/dnd_fields.3x.css'),
        'js' => array(drupal_get_path('module', 'dnd_fields') . '/dnd_fields.3x.js'),
        ),
      '#prefix' => '<div class="dnd-fields-ability-field dnd-fields-ability-' . $key . '-field">',
      '#suffix' => '</div>',
    );
  }
 
  return $element;
}

Technically, we're done. You now have a form element that you can define in any Form API code. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
function dnd_character_test_form($form, &$form_state) {
  $form = array();
  $form['test'] = array(
    '#type' => 'dnd_fields_attribute',
    '#title' => t('Attribute fields'),
    '#description' => t('Provide a description here.'),
  );
  $form['submit'] = array(
    '#type' => 'submit', 
    '#value' => t('Submit'), 
  );
  return $form;
}

Themeing your Element

The cool thing with your new form element is that you can theme it, even though this is not strictly neccessary, since the widget defined in the field will handle most of this for you. So feel free to skip this step if you're already happy with the Field API widget that you have.

The following code sample displays a generic form output, since the field that we defined is really just a special case of the 'textfield' form element type. However, you can feel free to get fancy here, and display literally any HTML output you want.

Also of note is that this is just like any other theme function in Drupal. You can refine this more using preprocess theme functions and .tpl.php files to theme your form element even more. However, for this example, I'm going to keep it simple.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function theme_dnd_fields_element($variables) {
  $element = $variables['element'];
 
  $attributes = array();
  if (isset($element['#id'])) {
    $attributes['id'] = $element['#id'];
  }
  if (!empty($element['#attributes']['class'])) {
    $attributes['class'] = (array) $element['#attributes']['class'];
  }
  $attributes['class'][] = 'dnd-fields-ability';
 
  // This wrapper is required to apply JS behaviors and CSS styling.
  $output = '';
  $output .= '<div' . drupal_attributes($attributes) . '>';
  $output .= drupal_render_children($element);
  $output .= '</div>';
  return $output;

As one of our superb Team Architects, Tobby Hagler expertise spans the gamut of technical capabilities -- from interface development to application layer engineering and system architecture.

Tobby’s specialties tend to focus on ...

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