Jun 27 2016
Jun 27

The Workflow Initiative was announced just over a month ago and since then I have been working on the first phases full-time. Here’s what I’ve touched:

In Drupal 8.1.x the RevisionLogInterface was introduced, but not used. In 8.2.x the Node entity will use it. Also BlockContent entity will use it.

When we make everything revisionable we’ll need all entities to get their base fields from the base class. So from 8.2.x all content entities inherit their base fields.

To help people make sensible decisions Node revisions will now be enabled by default.

We got into a pretty annoying issue when trying to add revision fields to entities which already had data because the revision field couldn’t be set to NOT NULL. Andrei wrote an awesome patch to allow an initial from field to be set. We therefore set the revision id as the entity id.

When we make everything revisionable we’ll need an upgrade path, to test this the Shortcut entity is being upgraded to revisionable by a new service. This has still not been committed, so reviews are welcome.

We’re trying to get Workbench Moderation into core as Content Moderation. Still lots to do to make this happen, but the patch is there with passing tests.

Initial work has also started to get an archive field into all entities. This will allow us to have CRAP (create, read, archive, purge) workflow, create a trash system, and replicate entity deletion through environments.

Please enable JavaScript to view the comments powered by Disqus.

blog comments powered by Disqus
Nov 17 2015
Nov 17

It’s been awhile since Drupal 8 was first ready to try out. But even since then, I was checking out news, reading updated docs, working on my Drupal 7 projects… still waiting for something real. And it finally happened – during the keynote at DrupalCon Barcelona, Dries announced the first D8 release candidate and basically confirmed that it’s now ready for production sites!

road to the drupal 8

And there my journey had started; after all those weeks, I finally received a great opportunity to try out the real D8.

Getting started

You can download D8 here, which its configuration is not difficult – everything is well described in the official docs, I didn’t find any issues there. Just a small reminder: after applying configs in settings.php/services.yml (such as enabling twig debug), don’t forget to run the new drush command for cache clearing: drush cache-rebuild
Speaking of drush, for Drupal 8 you will need to update your drush up to the 8th version. If you want to keep both for purposes like executing drush commands on a remote server which runs older drush versions, just put drush8 in another folder and create an alias (more info). That is an easy and rather straightforward way, but there is also an automated way to do that, which could be useful in some cases.

Folder structure

Looking into the folders structure – it is a bit different to D7, but pretty logical, the main differences being: folder ‘core’ – Drupal’s heart has been moved here, and we don’t need to put themes and modules into the sites folder! We already have these folders in the root and from now on we should add custom/contrib subfolders there.

Opening my site – creating base content types, blocks (entities now! I like it, Bean module, thanks and goodbye – we’re finally able to create different block types and add fields. Breadcrumbs, site name and slogan are blocks now (+1 to karma from non-developers I think, as they don’t need to research what is code and how could they put this info in some other place) and, well, finally we don’t need the title = ‘’ for title hiding, for this purpose, a simple checkbox was added!).

Content

Content looks great (live editing on pages – this feature was even backported to D7 Quick Edit module, I guess it’s perfect for content editors), so I was pretty excited.

Deployment

It should be as easy and comfortable as it only could be for any person that will be deploying a project – even if it was not the same person that was working on this particular site in the past. For this purpose we have the Configuration Management – an interface for importing and exporting site configurations. And as almost everything (besides the content) is configurations, this tool means easy deployment and reusability (I think this is the fullest info base over CM). The Features module that we used in D7 is pretty heavy and was avoided rather often in small projects (eg. in those being coded only by one developer), leading to sacrificing usability with deployment. But the new, better workflow for deploying in D8 that’s in the core out of the box sounds great, and means easy deployment for any sized site!

Theming

Check out this introduction for a deeper look (I like this intro even a bit more than the official one).

Decided to try on a few pages and checked which variables do we have in preprocess_html, looked for devel – and turned out there was no stable release, which didn’t sound too well, so while I was researching devel issues track, I decided to config PhpStorm with xdebug for Drupal 8 – great instruction, thanks! So in case of no devel – I was ready to work, but it’s worth mentioning that devel’s beta worked fine in general, I usually used kpr($variables) – krumo submodule for d7, and so I found it similar in d8 – krumo($variables). devel 8 was extended with different debugging tools; there is also one more submodule – Kint – kint($variables), which looks really good and should overtake the role of the now unsupported Krumo.

No one has ever had any doubts that the Views module would be present in the next Drupal core, and of course it is in D8.

In general the core team does listen to devs’/users’ needs. A huge amount of great, often used and I would say expected functionality were added in Drupal 8: Ckeditor module for Rich text editor, Module filter, Date, Link, Email, Phone, Reference field types, entity cache module, custom view modes can be created for any entity (bye DS or custom code), admin pages are mostly views now and much more.

I was able to create all necessary functionality for a site without any problems or any lines of custom code in a module (I wasn’t able to enjoy OOP in Drupal fully – but I definitely will), and I don’t find the barrier to entry for Drupal 8 is much higher than D7 – so newbies go ahead, you have a lot of abilities in core, everything is pretty well documented and followed modern standards.

Theming took a bit more time than usual as there is a new theme layer here: HTML5 markups, naming convention, CSS architecture, the template engine in general (TWIG is great – a lot of people are already used it, but in addition to the general theme layer update in Drupal 8, it’s just a great pleasure to see improved and much cleaner code in templates, reduced amount of duplicated code and the ability for developers to extend base templates with necessary additions but not completely replace them as before; easy syntax, security – autoescaping by default, DB calls and PHP scripts couldn’t run in a template.

Small tip: config your IDE for syntax highlighting and autocomplete of .twig templates, PhpStorm has native support.

Also the idea to have 0 theme functions in core by the time Drupal 8 is released sounds interesting.

The future is here

drupal 8 is future

All these initiatives are great and finally Drupal is not so outdated and is using modern tools and best practices (we don’t need to excuse it because of its age anymore :-) ).

So, work on Drupal is in progress, it is well supported (D8 is really less “Drupal” specific and closer to modern standards, frameworks – hey, Symfony is here – and OOP in general; I bet all of that will grow Drupal’s community with high quality developers and as a result bring improvements), the core team and the community are strongly connected, devs and users are researching best practices and use cases, and Drupal 8 looks finally ready for production sites.

Tip: Don’t miss core changes – @drupal8changes

X-Team is hiring Drupal developers!
Click here to learn how to join the league of the extraordinary.

Feb 27 2015
Feb 27

If you are playing around with Drupal 8, you may want to install version 7 of Drush on your computer. However, Drush 7 is currently only available as the master branch at github, and you may not like to throw out your existing Drush 6 in favor of the Drush development version, which is not stable. I’d like to share with you a way you can have both installed at the same time. I used a Mac, though these commands should work well also under Linux. They will obviously not work on Windows.

1. Clone Drush master branch from git

We want to get the master branch from the Drush github repository. This will be placed under “usr/local/lib” as a new folder named “drush”. Launch your Terminal and type:

> cd /usr/local/lib/

> git clone --branch master https://github.com/drush-ops/drush.git

2. Get composer

Drush 7 requires composer to install, so you need to get that if you don’t have it already. We also want to move composer to /usr/local/bin/ so that it’s easier to use.

> curl -sS https://getcomposer.org/installer | php

> mv composer.phar /usr/local/bin/composer

3. Install Drush

We can now install Drush through Composer. At the end, Composer will generate some autoload files, though you can ignore the suggestions.

> cd drush

> composer install

4. Create an alias for Drush 7.

To make Drush 7 a bit easier to access, we can create an alias that you can use in the Terminal. Type:

> vi ~/.bash_aliases (Linux)

> vi ~/.bash_profile (Mac)

This will open the “vi” text editor. To move around, use your cursor keys. Type “i” to edit the text. When you’re done, type “esc” followed by “:wq” to save and close the editor. Inside this file, we want to add:

alias drush7='/usr/local/lib/drush/drush'

5. Go ahead and unleash the power of Drush 7

Now it’s time to test that everything we did works well. Type:

> drush7 version

It should return this text:

Drush Version   :  7.0-dev

Your Drush 6 will still be there and untouched by this installation. Enjoy!

So what’s new in Drush 7?

Drush 7 adds the following commands to your default arsenal:  browse, core-cli (php), image-derive (id), cache-rebuild (cr, rebuild), config-export (cex), sql-sanitize (sqlsan). Some of them are Drupal 8 specific. I’ll write about these commands in a future blog post.

Feb 27 2015
Feb 27

If you are playing around with Drupal 8, you may want to install version 8 of Drush on your computer. However, Drush 8 is currently only available as the master branch at github, and you may not like to throw out your existing Drush 6 or 7 in favor of the Drush development version, which is not stable. I’d like to share with you a way you can have both installed at the same time. I used a Mac, though these commands should work well also under Linux. They will obviously not work on Windows.

We want to get the master branch from the Drush github repository. This will be placed under “usr/local/lib” as a new folder named “drush”. Launch your Terminal and type:

> cd /usr/local/lib/

> git clone --branch master https://github.com/drush-ops/drush.git

Drush 8 requires composer to install, so you need to get that if you don’t have it already. We also want to move composer to /usr/local/bin/ so that it’s easier to use.

> curl -sS https://getcomposer.org/installer | php

> mv composer.phar /usr/local/bin/composer

We can now install Drush through Composer. At the end, Composer will generate some autoload files, though you can ignore the suggestions.

> cd drush

> composer install

To make Drush 8 a bit easier to access, we can create an alias that you can use in the Terminal. Type:

> vi ~/.bash_aliases (Linux)

> vi ~/.bash_profile (Mac)

This will open the “vi” text editor. To move around, use your cursor keys. Type “i” to edit the text. When you’re done, type “esc” followed by “:wq” to save and close the editor. Inside this file, we want to add:

alias drush8='/usr/local/lib/drush/drush'

Now it’s time to test that everything we did works well. Type:

> drush8 version

It should return this text:

Drush Version   :  8.0-dev

Your Drush 6 or 7 will still be there and untouched by this installation. Enjoy!

Drush 8 adds the following commands to your default arsenal:  browse, core-cli (php), image-derive (id), cache-rebuild (cr, rebuild), config-export (cex), sql-sanitize (sqlsan). Some of them are Drupal 8 specific. I’ll write about these commands in a future blog post.

Oct 20 2014
Oct 20

Recently 10 members of the Drupal development team at Capgemini went to Drupalcon Amsterdam. Having been to two Drupalcons before, I more or less knew what to expect, but something I hadn’t previously given much thought to was how big an event it is. Compared to most other web conferences, it’s a beast. For me personally, I wonder if it’s getting too big and too impersonal, and I think that I’ll be more interested in going to smaller events.

Some of the more interesting sessions for me were the BoFs - in particular a discussion of open source training material and apprenticeships provided a lot of food for thought, and hopefully we can get involved at some level. Capgemini already does a lot of work getting graduates and apprentices into our engineering practice, and with such a big Drupal team, I hope we can benefit from and contribute to the Open Drupal initiative in 2015.

Whenever I go to an event, I come back with a to-do list, and this was no exception. I’ll definitely be digging further into CasperJS following Chris Ruppel’s session on Automated Frontend Testing. I was also very interested to hear about the way that Lullabot spin up test environments for pull requests - it will be good to investigate the feasibility of incorporating this into our workflow.

The other talk that stood out for me was John Albin Wilkins on Styleguide-Driven Development. For a long time, I’ve had a bee in my bonnet about the value of component libraries over Photoshop comps, and it was good to be reminded that I’m not alone. In an interesting session, John outlined an approach to integrating component-based design and automated style guides to agile development projects.

It’s been said many times before, but it’s worth remembering that all too often, people are still thinking in terms of pages, rather than systems.

In the context of the work that we do, this is even more important. We’re a large development team, building CMS-driven sites for large corporate clients, where the design is done by a team working for another company. We’ve made some inroads into building a more collaborative process, but it’s still too easy to end up with the designers throwing things over the wall to the developers. Very often the designer isn’t closely involved during the build phase, and design tweaks are agreed between the client and the developer without the opportunity to go back to get the designer’s opinion.

This is the whole point of living style guides - component libraries that stay in sync with the code as it evolves. As Shay Howe has discussed, component libraries help everyone on the project.

Designers are reminded of the visual language of the project, and it’s easier for them to see when they’re about to reinvent the wheel.

Style guides help developers by defining and documenting standards, and make it easier to dig in and find the way you solved some problem six months ago.

The projects we work on are large and complex, with a long lifecycle, and as developers we need to value maintainability of the front end code. Part of John’s approach to this was his class-naming convention. Having seen Jonathan Snook present on SMACSS I’d thought it was interesting, but to a certain extent it felt like a fancy name for something that was basically common sense. John’s presentation brought the concept to life well, and persuaded me that there’s more to it than that, with an impressive display of flower power.

The other interesting aspect was splitting up SASS files into components, and using KSS to create the style guide - this is something I definitely intend to do on my next project.

Modularity makes sense - it’s how the back-end is going, it’s how Javascript is going, so why shouldn’t design and CSS go the same way?

UPDATED 3rd December 2014: Unfortunately we got Chris Ruppel’s name wrong in the original version of this post, calling him “Dave Rupl”. Sorry Chris.

Jan 26 2014
Jan 26

In April 2013, Wunderkraut Estonia was tasked to build a website platform for the Government of Estonia. The platform would be used to run the Goverment Office website, all of the 11 main public sites for the Estonian Ministries, and the central “Government site” called valitsus.ee (government.ee in Estonian).

We took our weapon of choice, Drupal, and decided to develop the platform as a Drupal distribution. It did end up having most of the characteristics of a Drupal distribution – installation profile, theme, a bunch of modules; but it also has some differences – it’s not (yet) publicly available, and it ships as a ready-to-go website, with most of the settings already configured.

I have been running this project from the developer side since April and we have now arrived at a stage where we are due to launch first of the sites soon, so this is a good moment to take a look back. This is Part 1 of the series of posts that describe the lifespan of this project. Part 1 concentrates on the reasoning – what is this project about, and why is it a good idea to build a unified platform for 13 important public sector websites?

The preparations

Before we had even heard of this project, there was a period of time during 2012 and beginning of 2013 when the Government Office did a spetacular job of bringing together all the interested parties, who, as a group, worked out the main principles and functionality of the forthcoming platform. Some decisions were made:

  • the platform will be developed centrally, ie. decisions are made as a group and tasks delegated to a single dedicated development team. This means that at least until the deployment phase, noone can press his specific needs into development without finding common ground within the group first.
  • the platform will be named “Government Portal” and will have to make the 13 sites look as parts of a single big information source, with similar visual language, some shared and aggregated content, and similar structure in menus and page layouts. However, it’s not a single website, but a separate site for each, installed in different servers, running on independent CMS cores.
  • the look and feel of the platform will be obligatory to all group members, but the specific technical solution (ie. Drupal) will be recommended, not forced.
  • everyone will try to migrate to the new platform together, the most optimistic deadline being the beginning of 2014.

These were all important decisions that set the tone for the platform-to-be. Whats probably just as valuable, is that the group got to know each other and made those decisions together. Estonia is a small country, but even here each of the Ministries is a huge administrative machine, with its own traditions, missions, structure, powerful leaders and so on. To make the centralized approach work, you can’t just throw a finished end product out there and force everyone to use it. It has to be made together, and has to feel like it was made together.

vp-frontpage

The design layout for the frontpage

Another part of the preparations was working out the detailed functionality and designing all the layouts for it. This came to be about 20 pixel-perfect views, from frontpage to news views to content page templates, all the webdesign this project would need (actually ended up being about 80% of the design it needed), with the functionality drawn into it.

Now, coming from the world of agile and modular Drupal, I have to be critical about this part. A Drupal project should start from Drupal – prototyping, choosing the right modules, eliminating or redesigning that 5% of the functionality which takes 30% of the effort, etc. As it turned out, we did end up facing some functionality that did not really make sense on Drupal and didn’t allow for the best user experience. Luckily, client was flexible and understanding enough that this didn’t turn out to be a major problem.

Understandably, a public sector organization cannot choose a development partner at random to have them onboard from the start. A better scenario here would have been if as soon as the main concept was in place, a single procurement process would have been called to find a design partner and development partner together. And then the detailed functionality and user interface would have been defined together with both of them.

Too much of the website functionality is still drawn up in Photoshop these days, without a developer present.

Why?

Why would you do a project like that, and in such a way as the described preparations suggest? Different stakeholders have their own answers to this question, but the following reasons are the way I see it.

CMS engine segmentation before Government Portal on Drupal

CMS engine segmentation before Government Portal on Drupal

Of course there is the efficiency – saving resources and money. Websites have a lifespan of 3-5 years, sometimes longer. All the 13 websites involved would need to be updated or remade at some point or other. Their look would decay, the technologies involved get hopelessly outdated, needs for new functionality arise etc.

5 of the sites were running on a CMS engine called Saurus, everyone else had a different backend. Even if those 5 wanted to share resources, they didn’t, because the sites were quite different.
Out of 13, maybe 4 could be updated, everyone else needed a remake, because the backend was discontinued or just too old.

So lets say a complete remake costs 100 apples, an update and a facelift  50. To get everyone done, one would need to spend 9×100 + 4×50 = 1100 apples. No sharing of resources.

Building the unified platform did cost about 300 apples, about 100 apples will be spent on various ways of deploying the sites. Thats 400 apples total.

This is, of course, a simplification, but the caliber is correct. And thats a lot of apples saved.

Another one is user experience. People of Estonia dont have to learn how to navigate 13 different public sites, which usually, based on good historical data, have the navigation scheme of a maze.  The news, search and contacts of the sites are now unified, helping to deliver the idea that the Government is actually a single large organization.

This also works on the product owner side – server administrators and content editors now have unified manuals, they can share knowledge and materials about how to run these sites. Training can be centralized.

Nobody gets left behind. Ministries with less resources or time are also helped or forced to the new platform. This contributes to a more modern, unified look across the whole government sector. Security is better. Updates are coordinated together, so that when a more technologically savvy Ministry goes for a new technology or functionality, others get part of it too.

I suppose there are some cons aswell – mainly that ministries lose some of their decision-making independence and making ministry-specific functionality is a bit tricky (more on that later). But in no way can I see that those cons would outweigh the pros.

So this is what the client wanted to build, and some of the reasons why make the effort. Next up, part 2 – highlights of the technical implementation.

Dec 01 2013
Dec 01

I’ve been leading Drupal web projects for some years now and yet have never heard a frontend developer say: “This design is meant for Drupal. It is so easy to implement it, the designer totally gets how Drupal works. I’m totally having coffee with this guy later today, we’re pals.” Instead, it’s often about how the designers only goal in life must be to think of ways how to drive the devs into insanity and ultimate extinction. What seems to be the problem?

Where to start from, would the themer say, putting down his half-smoked pipe and jQuery cheatsheet. Lets start from the beginning. The moment when you see Dropbox icon in update mode, and with a shaky cursor, open the design folder for the very first time. What will it be, Photoshop, Fireworks, or God save us all, an Illustrator file? Or is it just a bunch of .jpg’s with no means to separate backgrounds from text and shadows?

Whatever it is, the themer is usually left to discover his own way around the new landscape. Because the designer is off to a vacation, or too busy with his next project, or generally not involved, because his job is done, right? And it’s easy to understand that he is fed up with it. Because, yet again, the client puts him into a position where he not only has to make it look pretty, but also work out the UX process and half of the functionality while at it.

And grid. The grid is those cyan lines that help you align stuff in Photoshop. And Omega is a watch company. Keep the number of columns consistent through different responsive states, you say? Your stupid math has no place in my creative process, I say!

Finally you get throught the main laoyouts and move on to theme more specific functionality. The comment thread. The pager. The inputs. Is there design for those? No. And when you ask for it, the designer frustratedly spends his Saturday evening catching up and creates a pixel perfect design, that has no common ground with Drupal’s default layouts whatsoever, requiring thousands of characters of JS to make it work.

Lets breathe in

Its fun to rant, but all jokes aside, there’s some pretty simple stuff that would save a ton of time and money for everyone:

  • make nice layered source files, where all elements can be extracted separately. Please don’t send .jpg’s.
  • a Drupal project should be a team effort from the start. There is no independent graphic design phase. It does not make sense that the web designer is also the one who single handedly draws up the layouts and UX.
  • use consistent grid when doing responsive layouts.
  • when drawing up standard Drupal elements, look at the examples, get a basic knowledge of how the code works. Features are cheap, details expensive.
Oct 21 2013
Oct 21
Automating new dev sites for new branches

Over the past few years we've moved away from using Subversion (SVN) for version control and we're now using Git for all of our projects.  Git brings us a lot more power, but because of its different approach there are some challenges as well. 

Git has powerful branching and this opens up new opportunities to start a new branch for each new ticket/feature/client-request/bug-fix. There are several different branching strategies: Git Flow is common for large ongoing projects, or we use a more streamlined workflow.  This is great for client flexibility — a new feature can be released to production immediately after it's been approved, or you can choose to bundle several features together in an effort to reduce the time spent running deployments.  Regardless of what branching model you choose you will run into the issue where stakeholders need to review and approve a branch (and maybe send it back to developers for refinement) before it gets merged in.  If you've got several branches open at once that means you need several different dev sites for this review process to happen.  For simple tasks on simple sites you might be able to get away with just one dev site and manually check out different branches at different times, but for any new feature that requires database additions or changes that won't work. 

Another trend in web development over the past few years has been to automate as many of the boring and repetitive tasks as possible. So we've created a Drush command called Site Clone that can do it all with just a few keystrokes:

  1. Copies the codebase (excluding the files directory) with rsync to a new location.
  2. Creates a new git branch (optional).
  3. Creates a new /sites directory and settings.php file.
  4. Creates a new files directory.
  5. Copies the database.
  6. Writes database connection info to a global config file.

It also does thorough validation on the input parameters (about 20 different validations for everything from checking that the destination directory is writable, to ensuring that the name of the new database is valid, to ensuring that the new domain can be resolved).

Here's an example of how it's run:

drush advo-site-clone --destination-domain=test.cf.local --destination-db-name=test --git-branch=test
---VALIDATION---
no errors

---SUMMARY---
Source path         : /Users/dave/Sites/cf
Source site         : sites/cf.local
Source DB name      : cf
Destination path    : /Users/dave/Sites/test.cf.local
Destination site    : sites/test.cf.local
Destination DB name : test
New Git branch      : test

Do you really want to continue? (y/n): y
Starting rsync...                                             [status]
Rsync was successful.                                         [success]
Creating Git branch...                                        [status]
Switched to a new branch 'test'
Git branch created.                                           [success]
Created sites directory.                                      [success]
Updated settings.php.                                         [success]
Created files directory.                                      [success]
Starting DB copy...                                           [status]
Copied DB.                                                    [success]
Complete                                                      [success]

There are a few other things that we needed to put in place in order to get this working smoothly. We've set up DNS wildcards so that requests to a third-level subdomain end up where we want them to.  We've configured Apache with a VirtualDocumentRoot so that requests to new subdomains get routed to the appropriate webroot.  Finally we've also made some changes to our project management tool so that everyone knows which dev site to look at for each ticket.

Once you've got all the pieces of the puzzle you'll be able to have a workflow something like:

  1. Stakeholder requests a new feature (let's call it foo) for their site (let's call it bar.com).
  2. Developer clones an existing dev site (bar.advomatic.com) into a new dev site (foo.bar.advomatic.com) and creates a new branch (foo).
  3. Developer implements the request.
  4. Stakeholder reviews on the branch dev site (foo.bar.advomatic.com). Return to #3 if necessary.
  5. Merge branch foo + deploy.
  6. @todo decommission the branch site (foo.bar.advomatic.com).

Currently that last step has to be done manually.  But we should create a corresponding script to clean-up the codebase/files/database/branches.

Automate all the things!

Jul 26 2012
Jul 26

Posted Jul 26, 2012 // 0 comments

Over the past several months, we’ve been working with OpenPublish on many client projects, and working on improvements to the distribution as we go. We are happy to bring you the beta release of OpenPublish!

Gazette: Our New, Responsive Demo Theme

The first thing you’ll notice with the new version is the very beautiful new Gazette demo theme, designed by Samantha Warren and Dave Ruse.  Gazette was built upon OpenPublish’s Omega base theme and is completely responsive with support for tablet and phone breakpoints.  It features a new touch friendly photo gallery built with PhotoSwipe, allowing for easier image viewing on mobile devices.

Streamlined Content Management Experiences

We’ve bundled in some of our latest improvements from the revamp of Context UI, allowing editors to manage their page layouts by selecting blocks to add/place/remove as necessary on major Section Fronts.

Also, we’ve streamlined the experience of related content creation on Articles (i.e. the associated Author) via the incorporation of References dialog.

Robust Semantic Web Capabilities

We’ve updated many modules, including schema.org and a patch to provide for RDFa annotations for OpenPublish’s content types, enhancing OpenPublish’s semantic web capabilities, too.

Up Next: More Apps for Publishers!

We’re working on two new apps for OpenPublish that will offer an easy way to find, install, and configure optional functionality for your OpenPublish site.

Workflow App

The Workflow App helps streamline the installation and default setup of Workbench functionality for OpenPublish. This empowers editors to move content through a set of configurable workflow states and surfaces lists of content you’ve edited as well as a breakdown by workflow state.

Twitter App

The Twitter App makes it easy for folks to leverage Twitter Pull by providing a configuration page allowing users to enter a Twitter username/hashtag and specify where the resulting block full of related tweet should appear.

Getting Involved with OpenPublish

Let us know what you think, and keep any patches coming to the issue queue. And hey, if you’ve developed functionality that you think should be in OpenPublish, (or if you’re a third party service provider interested in integrating your service or module into OpenPublish,) we would love to talk to you. Building an app that integrates your module or service with OpenPublish can bring your awesome work to the thousands of people who download OpenPublish every month. Contact us if you’re interested in seeing the functionality you’ve built or services you provide in OpenPublish.

Dave has a seemingly innate ability to solve problems, anticipate potential pitfalls, and translate business objectives into functional requirements -- which is why he excels as a Solutions Architect at Phase2.

Dave has an essential ...

Jul 05 2012
Jul 05
New Spammer Registered

Rules is an especially useful Drupal module for all kinds of tasks. One use you might want to put it to is providing admin notifications of certain events on your site, e.g. user registrations and the creation of new comments and content by these “untrusted” users (assuming your use case allows them to create any content at all). I recently created such rules to help monitor the creation of users, content, and comments on drupal.cocomore.com/.de. Since we use the Project module (and supporting code) to host and track issues on some Drupal modules, we allow users to create accounts and “Issue” nodes. But there hasn’t been much recent change to the modules we host, so most of the “users” turn out to be spamming scumbags who post “issues” with links to questionable sites (you know the type). Since we allow anonymous users to comment on our blog posts, we also get our fair share of comment spam, but a tricky Captcha (we’re using Riddler, these days, to filter out visitors who don’t know or can’t take the time to search the answers to simple Drupal trivia questions) helps keep comment spam to a minimum. Keeping vigilant about stomping out spam is important since leaving spam published looks unprofessional and is bad for SEO… and since it also attracts more spam (spammers see that your site leaves spammy links in place); but of course it’s also important to keep an eye on the valid posts, too, and to respond to them in a timely fashion.

So we will assume that you have a site without a massive flow of new user registrations or new content and that you want to be alerted with some useful information whenever these events occur so that you can take appropriate action (block users and clean out the spam… or respond to valid content/comments). This article will lead you, step-by-step, through the creation of three different rules on both Drupal 6 and Drupal 7 -based sites, identifying particular set-up differences between these versions of Drupal/Rules. The three events we want to create Rules for are:

  1. New user registered
  2. New comment posted (by non-staff user or “untrusted” user)
  3. New content posted (again, by some kind of “untrusted” user)
In each case, we simply want to send an HTML email* to notify at least one member of staff (anyone with the admin role and, in the case of comments on blog posts, we want to also email the article’s author.) This article does not get into the various particulars of configuring your server to be able to send mail; there are a number of factors which might differ from server to server and it’s not really within the scope of a Drupal-related article.
*Note: This article also does not cover setting up HTML mail, but some modules, such as Mime Mail help make this a relatively pain-free process and provide a “send HTML mail” action for Rules. Adding specialized modules is probably not justifiable if you don’t plan to use HTML mail for anything more than admin notifications, but if you want to email users, such modules can help you create much more attractive and useful emails.

In every case, creating a new rule starts by going to the “add rule” page:
D6: admin/rules/trigger/add
D7: admin/config/workflow/rules/reaction/add

Notify admin when a new user registers

This is a simple rule which sends an HTML email with a link to a new user’s profile, along with their username. If you allow users to register themselves on your site, you will likely notice patterns that persistent spammers follow and be alert enough to just block the most suspicious user accounts before they even start spamming your site. I won’t specify the suspicious patterns I’ve been reacting to here (I don’t want to teach spammers how to be sneakier or more effective), but if you have a spam problem, you probably already know the patterns or will quickly recognize them.

*/

Adding a new rule to react to user registrations

The first step is virtually the same on both Drupal 6 and Drupal 7. Pick a name for the rule that you will not be confused by later, add tags (categories) if you have lots of rules, or plan to make lots, and select the event, “After saving a new user account” (“User account has been created” on Drupal 6).

Drupal 6 - Rules Event is a “new user account”Drupal 7 - Rules Event is a “new user account”

Click “Add action”

The “Add action” pre-step is also almost identical in Drupal 6 and Drupal 7 and we will skip over illustrating this in the following rules:

Drupal 6 - Rules “Add Action” buttonDrupal 7 - Rules “Add Action” button

Add action “Send mail” or “Send HTML mail”

In Drupal 6, the options for sending an HTML mail (provided you have Mime Mail installed) are separate from the rest of the “Send mail…” options. In Drupal 7 they all appear together in the “System” options. Either way, you can choose to send an email to an appropriate person or group of people. The “arbitrary email address” options can be useful if you want to send email to more than one person, regardless of their site roles. You could, for example, send a mail to the author of content that received a comment (using a “replacement pattern”, i.e. “token”) and/or to a particular person. More than one email address (or token substitute) can be added to recipient fields as long as the addresses are comma-separated.

drupal6-rules-send_html_mail.pngDrupal 7 option - Send HTML mail with Rules

Complete the email subject and body

The email “subject” and “body” fields can accept a variety of tokens or “replacement patterns”. In Drupal 7, these are apparently separate from “Tokens” provided by the Drupal contrib module, Token, which of course you also have installed; the Rules replacement patterns are available even if Token is missing or disabled, but in Drupal 6, you need the Token module enabled in order to have “replacement patterns” available for use.

Drupal 6 - Configure Rules message for new user registrations drupal7-configure-message-new-user-4.png

Download import code for this rule

Rules allows you to export and import rules from saved code, so I have attached an export of this rule. Even if you don’t want exactly the same action, this could be useful as a starting point for a new rule on your site. There are four versions of the import code attached, two each for Drupal 6 and Drupal 7 (for each version of Drupal, there is one version of the rule which uses HTML mail for the admin notification email, and one which just sends a plain mail.)

Troubleshooting

I suggest initially triggering a very simple rule to send a very simple email (to test that you get your message) and then build up the complexity a small step at a time, testing as you go.

AttachmentSize 1 KB 666 bytes 1.99 KB 2.76 KB
Jun 28 2012
Jun 28

Alfresco Activiti Workflow Automation

Posted on: Thursday, June 28th 2012 by Victor

Last time I blogged about how to start a workflow explicitly via webscript. In our Canopy solution, if desired, the workflow can be started automatically upon a document submission from Drupal to Alfresco as well. The document upload is usually done via CMIS Alfresco. This approach will enable the workflow automation between CMIS client such as Drupal, Joomla etc and Alfresco.

How to set up a rule inside Alfresco Share

Please check out an example of rule for workflow.

How to start a workflow programmatically

Please install the following script run_js.wf in Alfresco's /Data Dictionary/scripts. The script will start Alfresco's out of box Review and Approve workflow when the new document is uploaded to Alfresco. The highlights are:

  • Read a custom property "canopy:reviewer" via document.properties.The value of "canopy:reviewer" should be set by CMIS client upon document upload.
  • Set the bpm:assingee attribute of the workflow to the reviewer with JavaScript API people.getPerson() so that the reviewer will process the workflow accordingly.


var workflow = actions.create("start-workflow");
workflow.parameters.workflowName = "activiti$activitiReview";
workflow.parameters["bpm:workflowDescription"] = "Please assign approvers for "+document.name;
var reviewer=document.properties["canopy:reviewer"];
logger.debug("canopy:reviewer="+reviewer);
workflow.parameters['bpm:assignee']=people.getPerson(reviewer);
workflow.parameters["sendEMailNotifications"] = false;
workflow.execute(document);

Drupal document upload via CMIS

Drupal CMIS module can be enhanced to support the custom property for document upload.

Jun 19 2012
Jun 19

It’s been a busy past several days in Barcelona (for the Drupal Developer Days) and most of us who’d been sprinting during the week before seemed to be in the same condition by Sunday—rapidly running out of energy from progressive sleep deprivation from an increasingly later return to our hotels. But it’s been an exciting week for Drupal core (and contrib) development and significant work has been completed on the Drupal core (mostly building up Drupal 8, but also some for added features in Drupal 7) while a lot of important decisions have been made which will likely shape development in a number of initiatives for the coming months until the sprints at DrupalCon Munich.

In addition to the Sprint I was primarily involved in (I was just trying to get my feet wet with assisting the Drupal 8 core development process by joining the multilingual sprint, but I did write my first committed core patch—admittedly this was a very basic patch), there were also sprints running for “Views in core”, Entity API, Media initiative, Mapping in Drupal 7, configuration management, abstracting social networking, search-related sprints, the Drupal.org upgrade… and possibly more still. I’ll cover some of the highlights of the week that I’m most knowledgeable about.

Multilingual Initiative

The multilingual initiative sprinted all week before the Developer Days sessions, and even continued through the weekend. And a lot of key decisions were made and important code changes committed and pushed to the central Drupal 8.x repository.

New user interface translation improvements in Drupal 8

This is something I got to do a bit with, but Swiss developer, Michael Schmid (Schnitzel on d.o), of Amazee Labs, was the primary developer working on this task during the Sprint. He and his colleague, Vasi Chindris, were among the stars of the week. It was a real privilege to get to look over their shoulders and to get Michael’s support when it came to using Git to manage code in the sandbox we were using for the issue. (Thank you, once again, Michael!) Once everyone was happy with the work, it got committed to core. This new sandbox workflow, used for larger issues, helps avoid a lot of bugs creeping into the main branch, as has happened during previous periods of intense core development. Of course the tests and test bots catch a lot of issues which could otherwise be major headaches for all concerned (automated testing was also a part of Drupal 7 development). If you recall, the long wait for Drupal 7’s release was due to hundreds of critical bugs. Now this should be a thing of the past since we have an established threshold for critical issues; and the core team only commit new patches to the central repository when we are below that threshold (15 “critical” bugs, 100 “major” bugs… among other thresholds specified).

New system for translating Drupal’s user interface

The new user interface translation system allows you to keep imported (community contributed) translations separate from customized translations and search for a particular translation within either or both categories as well as filter by translated strings, untranslated strings, or both. If you have any unsaved translations, they are highlighted to help remind you not to leave the page without saving them and there discussion about providing a dialogue to prevent a site admin from accidentally leaving the page with unsaved changes, too. There is also an issue to allow the string search to be non-case-sensitive (checkbox) to find more strings that contain a particular word or phrase, regardless of text case. Since this feature came up in discussion after the rest of the user-interface changes had already been made, we elected to put the discussion about adding this feature in a separate issue. If you have ideas for what might further improve the Drupal 8 user-interface translation workflow, your input is valued.Customized and imported (community) translations are stored separately

*/

New content language options

Drupal 8 has new language settings per content typeYou can enable translation for a particular content type and also choose to hide the language selector (automatically selecting the language for a new piece of content by any of a number of contextual rules). The automatically selected language for a new piece of content can be any particular language enabled on your site, “not specified”, “not applicable”, “multiple”, the “site’s default language”, the “current interface language”, or the “author’s preferred language”. While all these settings might arguably be a bit confusing for new users, they should help smooth the content creation and translation workflow for most sites. Of course the option to “enable translation” is hidden if the default language for the content type cannot be resolved to a single language (i.e. for “not specified”, “not applicable”, or “multiple”), since translation does not make sense here.

Translate the English UI to… English!

Drupal 8 — Enable English UI translationIn the edit preferences for the English language, you can enable translation to English and then it’s easy to change, for instance, the “Log out” link to “Sign out” (or “Disembark”, “Abandon ship”, “Terminate session” or anything else you might want on a particular site). Of course this could also be useful for fixing any oddities you find in the UI strings provided by contributed modules if you find a mistake in a field description, for instance, you don’t need to wait for a module developer to commit your patch or add a “site English” custom language just to modify a few strings.

Configuration Management related to Multilingual sites

Drupal core team leads and other sprinters discussed multilanguage configuration

One of the biggest issues of the week was determining how multilingual configuration would be handled in Drupal 8. The core team knew that they wanted to store language configuration in files rather than in the database, so that it’s easy to “push” new language configurations to an established site that already has content, among other benefits of this approach. But this brought with it a number of challenges which the Multilingual Initiative team, Configuration Management Initiative team, and other interested parties discussed in several sprint discussions through the week. Many of the standard configurations for a site might also differ, depending on the language: you might, for example, want a different site name or site slogan or logo for each language. There were three different proposals for how to handle multilingual configuration, and to keep a long story short, the final decision was to go with “Plan B” (or a minor variant, thereof). You can still lend your voice to the “review” process in the main issue for the language configuration system in Drupal 8. If you would like an overview of the plans, there is a nice graphic by Gábor Hojtsy (the Multilingual Team lead) which outlines the differences between the three proposals and some variants.

Drupal 8 Configuration Management

Greg Dunlap (“heyrocker” on drupal.org) presented the new configuration management

Angie Byron, aka “webchick” gave a quick overview of the configuration management initiatives goals, tooOne great session from the weekend was the Introduction to the Drupal 8 Configuration Managment System by Greg Dunlap (“heyrocker” on Drupal.org), the Configuration Management Initiative team lead. There has been some good progress in determining what this is going to look like, some of which took place during the sprints in Barcelona. Basically, this will be a bunch of smaller files stored within a logical directory structure in the sites/[…]/files directory. The new configuration system is currently planned to be YAML-based (rather than PHP or XML, which were used in earlier visualizations of the system). And the goal, as described by a slide in Angie Byron’s Sunday-morning keynote, “Drupal 8: What you need to know” is to be like “Features in core, only better”. The aim is to help us remove the complications involved in pushing configuration changes, modified in a development or staging environment, to a site that already has user-created content that we don’t want to lose. The main problem with the current system is that there is no consistent system: configuration settings are scattered across multiple tables, variables, files, and other locations and there is no consistent structure in any case. The idea is now to have a contexts, which Drupal responds to, when determining which configurations files to use.

Angela Byron (“webchick”) talks about the problems the new configuration management system aims to solve

What it should look like when loading a configuration from module code, is something like this:

  $config = config('image.style.large.yml';
  $config->get('effects.image_scale_480_480_1.data');

And when setting and saving configuration data:

  $config = config('system.performance');
  $config->set('cache', $form_state['values']['cache']);
  $config->save();

The YAML code for the image example, which saves configuration for the “large” image style would look something like this:

  name: large
  effects:
    image_scale_480_480_1:
      name: image_scale
      data:
          width: '480'
          height: '480'
          upscale: '1'
      weight: '0'
      ieid: image_scale_480_480_1

This should be pretty easy for developers and site builders to learn to work with and of course an interface is planned which should automatically build the configuration files, when edited by site builders. Configurations will be loaded into the “active store”. Changes are saved back to the active store and back to the YAML files so they can easily be moved between sites (staging and production sites, or completely different sites if they should have some settings in common). Building up an ideal import/export system for configurations is one of the major remaining hurdles. Update: heyrocker’s presentation slides are now available for download, so you can see other examples of Drupal 8 configuration.

Other Drupal 8 news

Twig library committed to core!

Drupal 8 now has Twig in the core/vendor directoryOne of the new developments which has received some press is that Twig, the templating system designed by Fabien Potencier, the innovator behind Symfony, which also bundles Twig, has now been added to the Drupal core repository.

However, the fact that the Twig library is in the repository does not mean that it’s ready for any kind of use yet, except for those who are working to build a new templating engine for Drupal, which uses it. How this works is still open to discussion; according to webchick, it may be that we keep both PHP-based and Twig-based templating engines to ease the pain of this change. On the other hand, while there is a learning curve involved, there are many advantages to Twig, especially in terms of security (removing PHP vulnerabilities from themes, altogether), and the saying that “the drop is always moving” applies here. It may be that Twig is the only templating engine which will be supported by Drupal 8, but if you feel strongly about this or have ideas for how to do this “right”, it’s a good time to get involved.Twig vs PHP template syntax

Context-based layout and blocks

Angela Byron lays out the plan for Drupal 8 layout with contexts

Everything in Drupal 8 will be a block or a layout area and blocks can have multiple contexts which determine their behavior (and whether or not they are displayed). This is going to be a major change which should produce much more flexible layouts and site designs. Of course this will touch on every major Drupal initiative: configuration, HTML5, mobile, multilingual… all are involved.

Drupal 8 will have clean, semantic HTML5 (and will abandon IE)!

Say goodbye to the messy nested div hell! Drupal 8 code is going to be much smaller and cleaner which will make designer/themer types love Drupal and make it possible to produce code that renders nicely, regardless of display size. Oh, and don’t worry about trying to support older versions of Internet Explorer; the community has decided it’s time to put that tiresome task to rest. Yay!

Drupal 8 development needs you!

Webchick, heyrocker, Gábor Hojtsy… all made the same point: As a community effort that’s still underway, the Drupal 8 effort needs more of the community at large to get involved and find ways to help out. There is a lot of complexity, but there will be smaller tasks that anyone could work on, so there’s going to be something for everyone. Even non-coders can help by testing, filing bug reports, helping manage the issue queues, making suggestions, documenting finished features and APIs. There are several places where you can get involved:

  • The core initiatives overview page provides information about when the different teams meet in IRC and in which channels among other information which can help people who want to find ways to get involved.
  • Drupal Ladder is a project aimed at helping more people learn how to contribute to Drupal
  • [ … ] (Comment below if you have other tips for where to get involved)

Big thanks to the organizers, sprint leads, and session speakers

The Drupal Developer Days in Barcelona were a big success because of all of you pulling together to make things happen. The local organizers made us all feel welcome and provided a lovely venue and took us out on the town just about every night. The sprint leaders helped find ways for everyone to play a part in building Drupal 8 or contributing in other ways, and the sessions were awesome.

Jun 14 2012
Jun 14
Morning stand-up meeting at the Drupal 8 Multilingual Sprint

I was supposed to get into Barcelona at 10:30PM on Tuesday evening, but with delays in my flight, it wasn’t till after midnight that our plane landed; it was after 1 a.m. by the time I reached my hotel. Normally travel, when it runs late and long, makes me feel exhausted, but I was excited to be joining my first Drupal core sprint. I’ve been wanting to do a bit more to help build Drupal and it’s great to not only be somewhat aware of what’s coming in Drupal 8, but to also know that I’ve at least played a small part in making it happen.

I wasn’t sure I would attend the Drupal Dev Days in Barcelona till a couple of weeks ago, but I’m glad I’m here. We have a fairly sizable group of developers here at the Citilab helping work on cutting through the issues for Drupal 8 Multilingual Initiative (D8MI). I’ve been helping with some user interface quirks and since it had been long enough since I’d actually done string translations of the user interface, I started out yesterday as a “tester”… at least trying to look at the problem of translating the interface (e.g. translating “Add content” to German) as if I had never done anything like that before. And we did find some issues and, even better, we were able to address and correct those issues during yesterday’s coding. Others have been working on multilingual issues related to the new configuration management system, and a number of other issues which you, too, can help with, if you’d like to join us remotely (or in person, if you happen to already be in Barcelona — the Sprints continue through Friday, too). There are currently about 40 of us in the IRC channel for i18n and I'd say that at least half of those are working on the Sprint. There are about a dozen (give or take, since people are working on other sprints, too) who are here in Barcelona working on D8MI.

You can help make Drupal 8 better, too!

Jump on IRC (#drupal-i18n) and look at the focus issues for Drupal 8 Multilingual Initiative if you’d like to join use remotely. There is a lot going on right now and it’s not all on Multilingual issues, so if you have some time, I’d like to encourage others to join me in helping ease the burden on the few who do so much and at least do a small bit to make Drupal 8 as awesome as it can be.

May 30 2012
May 30

Posted May 30, 2012 // 1 comments

Most websites have their own set of strict requirements around how they want their content to reach the end user. Some require nodes to just be published or unpublished. Others require a rudimentary workflow that adds one extra step between a node being unpublished and a node being published. On the far end of the spectrum, some organizations have very granular, company-specific approval processes. In any of these cases, a developer can easily create a custom State Flow/State Machine plugin that can meet a variety of business needs. State Machine is a contributed module created by Frederic Mitchell that adds workflow to content publishing in Drupal.

In this post, I'm going to go over the steps to create your own custom module workflow plugin. For this example let's consider the following to be our requirements:

  1. The Workflow has 5 states - Draft, Needs Review, Approved, Published, Unpublished
  2. There are 5 events or "transitions" - Submit for review, Approve, Request updates, Publish, Unpublish
  3. Only certain roles can approve/publish/unpublish content
  4. Some custom code needs to be executed when the node is moved into the "Approved" state

Getting Started

First, download and install State Machine and State Flow in your contrib modules directory. Then in your custom modules folder create a folder for your custom module. Let's call it "phase2_workflow." My contrib module is at sites/all/modules/contrib/state_machine and my custom module is at sites/all/modules/custom/phase2_workflow. Inside my custom module I'll make the info file, module file, install file and a plugins directory. Inside the plugins directory I'll make a file called "phase2_workflow.inc." Your module should look something like this so far.

Be sure to make a dependency to state_flow in the info file

Defining the plugin

In my plugin file I'm going to define a class called "Phase2Workflow" that extends the StateFlow class that comes with the contrib module. Inside I'm going to start with making an empty init function.

Defining States

Start defining the states outlined in the requirements with the create_state() function provided by the StateFlow class.

Defining Events

You can define transitions using the create_event() function. create_event() accepts the machine name of the event as it's first parameter and a configuration array as the second. In the configuration array you must define what states have access to this event through origin and target values.

Notice in the "Request Updates" event the origin is an array instead of a string. The origin and target values of the configuration array can either be a single string or a mult-valued array to illustrate that this transition is available to many states. In this case, I want to be able to transition something that is "published", "needs review", or "approved" with the "Request Updates" transition.

Setting the permissions

We've roughly satisfied our first two requirements with the states and events we've defined so far so let's take a look at the third: Only certain roles can approve/publish/unpublish content. Let's start by implementing hook_permission() in the module file so we have those permissions to refer to when making transitions. For now we're just going to make the two needed for the requirements:

Once these permissions are defined you can refer to them in guard functions. Guard functions are callbacks you define when creating events that check if the user has the permission to execute that transition. In our example, we want to make sure only users with our defined permissions can use our events. So, in the create_event() function for "approve", "publish" and "unpublish" we can put a guard callback:

Define these guard callbacks in the module file. I've created a helper function to help making the check for the user permission a little easier.

Now, only people that have roles that have these permissions can make these transitions.

Executing custom code on state change

To satisfy our last requirement let's go back to the states we created in the init of our custom StateFlow class. create_state(), like create_event(), can also accept a configuration array as a second argument. You can specify custom callbacks defined in your custom class to run when an item enters or exits a certain state. In our example, I'm using the on_enter event to execute a function I've defined.

Bringing it all together

I wrap things up by implementing hook_state_flow_plugins() and hook_state_flow_machine_type_alter(). The first is to make my module aware of the plugin in the plugins directory and the second is to tell the CMS which content types should adhere to this workflow. If you only want this workflow to be for a specific content type, do a check first on the $node argument's type.

That's it! This is just a rudimentary example but I hope it provides you with a jumping off point! I've posted the code on github here: https://github.com/phase2/state-flow-plugin-example

John (aka "JR") specializes in module development and implementation architecture, with an affinity for converting custom Drupal module work from projects into contributed modules. Recent contributed modules include the Data Visualization API ...

Mar 30 2012
Ela
Mar 30

We have a major upcoming project here at Cocomore which is in the initial planning phase. It’s too early to provide the finer details of the project, but it involves creating a product database for a large publishing house and Drupal 7 has been chosen as the project framework. By mid-June, we will likely have four developers working on it, full-time. Of course, anyone who deals with software development almost certainly knows the problems that tend to occur during the planning of large-scale, long-term projects like this one: in the beginning, the client is often not yet 100% certain of their needs or desired end results, so new requirements and ideas arise in the middle of project development. This means that projects built to the initial specifications often fail to completely meet the client’s needs, which can be disappointing for everyone involved.

Hoping to avoid this scenario, we (our software development team, and project and senior management) proposed implementing the project using Scrum. This allows us to flexibly respond to changes in requirements and keeps the customer closely tied to the project development process so we can avoid unpleasant surprises at the end of development. At a recent Cocomore “KnowledgeLab”, I presented a brief overview of Scrum methodology, a topic which is certainly too broad to cover, in-depth, in an hour-long presentation. So I limited the scope of my presentation to the most essential elements of the Scrum process: roles, events, and artifacts; then used Lego Scrum to try to better illustrate the model. This article provides an overview of the same basic concepts covered in our workshop session and describes how I helped immerse team members who had not previously worked with Scrum in the concepts and processes. We have been using Scrum for other “ambitious” Drupal projects and plan to provide in-depth case studies for some of them, with details about more specifics related to Drupal; this article provides a general foundation for understanding these upcoming case studies.

Scrum: a process model for agile software development

Agile software development is characterized primarily by an iterative procedure with alternating planning and development phases. The advantage this provides is that parts of the system are developed early on and can be tested before implementation of other parts. This reduces the risk that project development heads in the wrong direction. Rather, responding quickly and flexibly to changes in the requirements, the components of a system can be redefined to best meet a client’s real needs.

agile_workflow_with-url_03.png

The background of Scrum

The term “Scrum” originally comes from the sport of rugby and means “crowd”. Team-members work closely in a circular pack while their opponents try to prevent them from gaining ground. To the casual viewer, this may look merely like a disorganized shoving match, but it is based on a strict set of tactical rules and involves strategy and planning. The comparison is quite appropriate, because, as in rugby, in this form of development there is a team of players who stick together and adhere strictly to a few, well-defined rules. In general, the team plays the main role in Scrum. Unlike the classical approach to software development defined in the waterfall model, the team estimates how long it will take to implement the tasks requested by the product owner and decides which tasks can be accomplished during the timeframe of a sprint.

“Roles” in the Scrum process

Similar roles exist in Scrum. In addition to external roles such as “customer”, “manager”, and “user”, there are three primary roles involved in Scrum: the “Product Owner”, “ScrumMaster”, and “Development Team”:

  • The “Product Owner” provides the team with a vision for the product that must be developed. She is in close contact with the customer. This role defines the product’s features and prioritizes them. After each sprint, she is responsible for accepting or rejecting the functionality delivered by the Team.
  • The “Development Team” builds the product’s functionality, as requested by the Product Owner. It is responsible for compliance with an agreed set of quality standards for each component and jointly determines the required duration needed to implement each task. The Team also determines how many features it can deliver in a sprint.
  • The “ScrumMaster” assists in the implementation of the Sprint’s goals. In order to do so, the ScrumMaster does not actually participate in the development process, nor does she influence the team’s decisions. Rather, she helps eliminate problems which hinder the team’s productivity and aids in guiding the sprint to ensure that the Scrum process is followed.

Meetings & “Artifacts” in the Scrum process

Before development begins, the Scrum Team commits the Definition of Done (DoD), in short, they decide, in advance, what will determine whether a feature has been completed, to specification. The Product Owner defines the tasks necessary to achieve the desired objective. These tasks are included in the “product backlog”. Ideally, these backlog items are defined with the help of “user stories”, with requirements which are are user-oriented rather than technology-oriented. For each user story, there should be at least one “user-acceptance test”. This not only helps during the development process, but also during the sprint review for accepting delivered functionality.

Backlog items in a Drupal-based project might typically involve tasks to assess which goals will entail new content types, whether existing “contrib” modules will satisfy elements of the use case, etc. The acceptance criteria might contain what fields these content types will need, how forms have to be validated, what happens after a submission, etc. The DOD might then involve adding modules to the project repository, configuring modules and content types with a Feature or installation profile, following the Drupal Coding standards, applying tests, etc. Of course some backlog items will often require custom modules, some of which might be ideal candidates for a Product Owner to sponsor as a new contribution to the Drupal community, the benefits to the Product Owner including likelihood of community involvement leading to functional improvements over time as well as building “good will” in the Drupal community—taking from it and giving something back.

In Sprint Planning Meeting 1, the Product Owner identifies individual backlog items and explains them. The Team is encouraged to question ambiguities and thus to get an accurate idea of​what the Product Owner expects of them. Subsequently, the Team estimates how long they will need for the implementation of an item in the backlog, a step which commonly involves the technique. According to these estimates, the Product Owner re-prioritizes the backlog items and determines the goals for the first sprint.

In the following Sprint Planning Meeting 2, items are again chosen for the sprint backlog. If the individual tasks are too large, the Team attempts to break them down into smaller sub-tasks, with the aim to ensure that all tasks on the backlog can be managed in a day or less. The Sprint Backlog is used during the Sprint to document which team member has been assigned to which tasks and what the status of each task is. For this purpose, a “Scrum Wall” or “task board” is often used, with columns for sprint members to quickly see the status of each task: columns or sections are created for “To-do”, “In progress”, and “Done”, allowing tasks to easily be sorted.

A sprint is always the same length, which should be between 14 and 30 days. Every day there is a “Daily Scrum”; this is a short meeting which attendees try to keep to a maximum of 15 minutes: each team member says what they accomplished the day before and what they plan to do during the current day; problems and obstacles are addressed. If determining a solution to an obstacle will take longer than the allotted time-frame, the ScrumMaster documents this in her “Impediment Backlog”—a list of obstacles impeding the accomplishment of the sprint goals—and works to find a way to resolve them (outside of the daily scrum meeting).

Each sprint ends with a “Sprint Review”. This is a meeting in which the team presents their work. The Product Owner verifies that the tasks fulfill her requirements. The review accepts only those tasks that are truly ready; unstable or untested items migrate back into the product backlog. Work progress is recorded in a “Burndown Chart” where time is on the x-axis and the y-axis includes outstanding tasks. The Burndown Chart helps to provide an overview of progress in working through the project backlog. But, as already mentioned, the issue is relatively complex and not really suited to a brief explanation. Now for the fun part…

LEGO Scrum

As the acting Product Owner in our Scrum workshop, I established a project to build a “city”. Having dug out my old Legos from the cupboard (I hope nobody resented that they were a little dusty), I considered what I’d like to have built in my Lego town. I wanted: houses, a school, a bus stop, a Simpsons statue, and a few other things. I wrote these objectives on slips of paper and put them on our backlog “task board”. During the Team’s Planning Poker session, there was much debate about the size of each item, e.g. whether an elementary school is “bigger” than a church. The Team then considered what could be implemented in a sprint and the sprint backlog items were transferred to the backlog.

Our Scrum task board

During our mini-model of the sprint process, each sprint was set at 3 minutes and we had three sprints to complete the project. After each sprint, I was allowed to mercilessly tear down built elements which did not meet my acceptance criteria. Of course there were heated discussions at these times about whether a building was not yet ready and there was haggling about windows, doors and church crosses. But in the end, the decision to accept or reject features was left to me, as the Product Owner, so some “completed” tasks migrated back into the product backlog. And so we continued to the next sprint planning, the next sprint, and so on. In the end, only the church and primary school were left with small defects, which I accepted; the rest of the city was just as I’d desired.

The whole process was certainly fun for everyone involved and I believe it contributed to an improved understanding of the steps in the Scrum development process, too.

And here’s the result, our beautiful, colorful Lego city!

scrum-3.jpeg

scrum-4.jpeg

scrum-6.jpeg

scrum-5.jpeg

Mar 14 2012
Mar 14

When we last discussed State Machine, we highlighted how easy it was for developers to create custom workflows via the State Machine API.

The goal of State Machine is to provide an API first approach to workflows within Drupal. A simple user interface is included, but the developer ultimately has power and flexibility to extend and customize their workflows across various environments as they see fit.

We also reviewed State Flow, a sub-module packaged with State Machine which provides you with a base workflow, and showed how Energy.gov extends State Flow for its own custom needs.

We’re happy to share that State Machine has released a 2.x branch sporting some great new features to make your workflows even better.

Easier to Alter

The method for implementing a custom workflow changed from using variable_set() for defining the node types that should implement your custom workflow to using hook_state_flow_machine_type_alter(). Using Energy.gov as an example, we simply assign the machine type to match the key we declared in hook_state_flow_plugins().

/**
 * Implements hook_state_flow_plugins().
 */

function

energy_workflow_state_flow_plugins

() {
$info = array();
$path =

drupal_get_path

(‘module’, ‘energy_workflow’) . ‘/plugins’;
$info[‘energy_workflow’] = array(
‘handler’ => array(
‘parent’ => ‘state_flow’,
‘class’ => ‘EnergyWorkflow’,
‘file’ => ‘energy_workflow.inc’,
‘path’ => $path,
),
);
return $info;
} /**
 * Implements hook_state_flow_machine_type_alter()
 *
 * @param string $machine_type
 * @param object $node
 */

function

energy_workflow_state_flow_machine_type_alter

(&$machine_type, $node) {
$machine_type = ‘energy_workflow’;
}

You can also easily have multiple workflows by adding logic to change the machine type based on node type, instead of having to declare them as variables.

Bulk Revision Editing

A new administration page puts more power in users hands by allowing publishers to use your defined states and events on many items at once.

Similar to the philosophy of Views Bulk Operations, this is a neat feature for users who may want to fire events across multiple revisions.

For example, if you have micro-sites or a group of pages that all need to be launched simultaneously, State Flow includes a set of batch operations to publish those node revisions at once.

Revisions are administered by filters and operations. The filters dictate which revisions are selectable by administrators when they are applied. The operations serve as actions to perform on the revisions once they are selected.

For developers, these filters and operations are completely alterable and are packaged with their own hooks! This provides an opportunity to create unique bulk administration pages for your users.

Want to create a custom filter? Simply invoke hook_node_revision_filters() and add your filter to the form array. You can then invoke hook_query_node_revision_alter() to enact whatever logic you want for that custom filter.

Use cases include filters for revisions by taxonomy, the existence of certain field value, or even user access.

Here is an example of a tags filter and its query callback:

/**
 * Implements hook_node_revision_filters()
 */

function

mymodule_node_revision_filters

() {
$filters = array();

  //function to get tags
  $options = mymodule_tags_callback();

  $filters[‘mymodule_tags’] = array(
    ‘form’ => array(
      ‘#type’ => ‘select’,
      ‘#title’ => t(‘Content Tag’),
      ‘#options’ => $options,
    ),
  );

  return $filters;
}

/**
 * Implements hook_query_node_revision_alter()
 */

function

mymodule_query_node_revision_alter

(

QueryAlterableInterface

$query) {
// Get the filter form the session
if ($filters = $query->getMetaData(‘filters’)) {
if ($filter = isset($filters[‘elc_workflow_tags’])

?

$filters[‘mymodule_tags’] : NULL) {
/**
        * Custom code to join other tables
        */

}
}
}

This also true for custom operations. Utilizing hook_node_revision_operations(), we can easily create custom actions, in bulk, with the revisions exposed in this administration page.

Scheduling

Last, but not least, State Machine 2.x introduces workflow scheduling to allow users to set a day and time via the Date Popup module of when a node should transition to a defined state. This is done via a new submodule called State Flow Schedule.

State Flow Schedule extends State Flow to provide you with a default Scheduled state and Schedule event. Once a date and time is defined, the value is passed as a log message so users can easily view the workflow log of a node and check when it will transition.

Scheduling is heavily tied to cron. This means content won’t actually transition to the desired state until cron runs, so you should setup your environment accordingly.

Scheduling can also be extended. In Energy.gov, we had an additional event called Immediately Schedule to allow those with the appropriate permissions to skip the workflow for content starting in the draft state.

To utilize this, simply define the new event, then add it to array of definable scheduling events via hook_state_flow_schedule_events_alter().

/**
 * @file
 * Energy.gov implementation of State Flow, an extension of the State Machine class
 */

class EnergyWorkflow extends StateFlow {

  public function init() {
    // Initialize states
    $this->create_state(‘draft’, array(
      ‘label’ => t(‘Draft’),
    ));
    $this->create_state(‘needs review’, array(
      ‘label’ => t(‘Needs Review’),
    ));
    $this->create_state(‘approved’, array(
      ‘label’ => t(‘Approved’),
    ));
    $this->create_state(‘unpublished’, array(
      ‘label’ => t(‘Unpublished’),
    ));
    $this->create_state(‘published’, array(
      ‘label’ => t(‘Published’),
      ‘on_enter’ => array($this, ‘on_enter_published’),
      ‘on_exit’ => array($this, ‘on_exit_published’),
    ));
    $this->create_state(‘scheduled’, array(
      ‘label’ => t(‘Scheduled’),
      ‘on_exit’ => array($this, ‘on_exit_scheduled’),
    ));

    // Initialize events
    $this->create_event(‘for review’, array(
      ‘label’ => t(‘For Review’),
      ‘origin’ => ‘draft’,
      ‘target’ => ‘needs review’,
    ));
    $this->create_event(‘immediate publish’, array(
      ‘label’ => t(‘Immediate Publish’),
      ‘origin’ => ‘draft’,
      ‘target’ => ‘published’,
      ‘guard’ => ‘energy_workflow_guard_publisher’,
    ));
    $this->create_event(‘approve’, array(
      ‘label’ => t(‘Approve’),
      ‘origin’ => ‘needs review’,
      ‘target’ => ‘approved’,
      ‘guard’ => ‘energy_workflow_guard_editor’,
    ));
    $this->create_event(‘reject’, array(
      ‘label’ => t(‘Reject’),
      ‘origin’ => ‘needs review’,
      ‘target’ => ‘draft’,
      ‘guard’ => ‘energy_workflow_guard_editor’,
    ));
    $this->create_event(‘publish’, array(
      ‘label’ => t(‘Publish’),
      ‘origin’ => array(‘approved’, ‘scheduled’),
      ‘target’ => ‘published’,
      ‘guard’ => ‘energy_workflow_guard_publisher’,
    ));
    $this->create_event(‘unpublish’, array(
      ‘label’ => t(‘Unpublish’),
      ‘origin’ => ‘published’,
      ‘target’ => ‘unpublished’,
      ‘guard’ => ‘energy_workflow_guard_publisher’,
    ));
    $this->create_event(‘to draft’, array(
      ‘label’ => t(‘To Draft’),
      ‘origin’ => array(‘needs review’, ‘approved’, ‘unpublished’, ‘scheduled’),
      ‘target’ => ‘draft’,
    ));
    $this->create_event(‘schedule’, array(
      ‘label’ => t(‘Schedule’),
      ‘origin’ => ‘approved’,
      ‘target’ => ‘scheduled’,
      ‘guard’ => ‘state_flow_guard_schedule’,
    ));
    $this->create_event(‘immediate schedule’, array(
      ‘label’ => t(‘Immediate Schedule’),
      ‘origin’ => ‘draft’,
      ‘target’ => ‘scheduled’,
      ‘guard’ => array(‘energy_workflow_guard_publisher’, ‘state_flow_guard_schedule’),
    ));
  }

  /**
   * Other class info
   */

}

/**
 * Implements hook_state_flow_schedule_events_alter()
 *
 * @param array $scheduled_events
 */

function

energy_workflow_state_flow_schedule_events_alter

(&$scheduled_events) {
$scheduled_events[] = ‘immediate schedule’;
}

State Machine 3.x

These are great new features, and State Machine 3.x is promising to be even better!

The plan is to refactor State Flow to be entity agnostic and ultimately connect with Workbench Moderation 2.x.

Come out to the 2012 Drupalcon Denver workflow-based module collaboration sprint with Steve Persch and myself to get on the ground floor of this very unique and important collaboration.

Mar 09 2012
Mar 09

With the widening release of Pantheon, one of the features developers ask about most frequently is SSH access. Because of the nature of the DROPs platform, we can't simply provide a traditional shell login, and for a lot of developers that's like tying one hand behind their back. It's especially terrible if you're debugging: pushing speculative git commits to see if you can spot a problem is tiresome, and just plain feels wrong.

So we got to work.

Thanks to several different improvements in our binding capabilities, service containerization, upgrades to the dashboard and to the API, we were able to develop and now deliver what we feel is a solid first step (and just a first step, mind you) towards On Server Development. Check it out:

There's a bit more background on how you can use SFTP (and also rsync), as well as information for setting up on-server development in our public documentation base.

To enable the interface demonstrated above interface, you currently need to opt-in. Rather than rolling all new features out to everyone at once, we're adding a new UI element the account screen where the adventurous can try out the new stuff. It's a bit buried for now, but should be there if you dig for it:

Look waaaaay down and to the right on the account screen

Pantheon Labs

The Pantheon Labs section will let you toggle features that are new and/or experimental, which will start picking up pace in the spring. Currently there are two items on offer:

Custom SSL Certs: for customers who are ready to go live and pay, we offer a self-service UI for adding an SSL certificate for your domain. This is a paid-only feature since it relates to your live domain, and because it requires us to requisition a dedicated IP address for you to use. However, it should allow you to add your own domain's SSL certificate on your own timetable and schedule. No more waiting on support.

On Server Development UI: this is the UI you see above. It might not work perfectly in older browsers, but let is know your experience as we'll be making improvements over the coming weeks to tighten it up.

As always, we truly appreciate all the feedback, questions, and feature requests we get from our users. We're looking forward to a solid year of developing more killer features like this, so let us know how you think your Drupal development process could be improved with Pantheon.

Jan 05 2012
Jan 05

Hey Drupal developers and site administrators! Ever spend your time handling things like block placement and microsite deployments at the request of your content editors?

Hey content editors and managers! Ever wish you could just do this stuff without relying on your developers and administrators–or becoming a de facto site administrator yourself?

This one’s for you.

Three of our modules from 2011–co-sponsored by Energy.gov–empower content editors with greater independence and more effective execution tools.

BEAN

BEAN gives editors an easy way to plug blocks into any page on a website without the typical administrative wrangling.

On the technical side, the module creates blocks as entities. Fields are used to define block types (similar to node types). Just like nodes, instances of blocks can be created and placed into pages. More geekery in this Neil Hastings post on the BEAN module.

State Machine

State Machine provides content editors with additional options for non-disruptive content revisions via the State Flow base implementation. By creating a draft version of existing content, ongoing revisions can occur without interfering with site performance. When a revision is ready to publish, the published version (when applicable) is automatically archived and replaced with the latest approved copy.

Developers get a treat as well–the State Machine module is really an API. Through this API, State Machine extendable and exportable through plugins. Code-based workflows can be created for multiple sites and easily tested–without affecting existing content and functionality. Fredric Mitchell breaks it down (with extensive code samples) here.

OG Tasks

OG Tasks is an add-on for the Organics Group Module. OG Tasks automates many of the tasks associated with creating new groups–such as when launching a microsite. Instead of relying on developers or site administrators, content editors can manage pre-configured group creation with just a few mouse clicks.

Neat, right? Kudos to Neil Hastings, Fredric Mitchell, Roger Lopez, Joe Turgeon, and Tim Cosgrove for their work on bringing these modules to fruition!
Nov 11 2011
Nov 11

TL; DR: [spam]Please vote for my DrupalCon Denver proposal on Drupal workflows in the enterprise.[/spam]

For the last few months I've been working for Technocrat on a new Drupal based site for the Insurance Australia Group's Direct Insurance brands. The current sites are using Autonomy Teamsite.

The basics of the build are relatively straight forward, around 1000 nodes, a bunch of views and a bit of glue to hold it all together. Where things get complicated is the workflow. The Financial services sector in Australia is subject to strict control of representations being made about products. The workflow system needs to ensure IAG complies with these requirements.

During the evaluation we found that generally Drupal workflows are based around publishing a single piece of content on the production site. In the IAG case a collection of nodes need to be published as a piece of work, along with a new block. These changes need to be reviewed by stakeholders and then deployed. This led us to build a job based workflow system.

We are using the Features module to handle all configuration, deploy for entities and some additional tools, including Symfony, Jenkins and drush to hold it all together.

I've proposed the session for Drupal Downunder in January and will refine the session based on feedback from there in preparation for Denver. If you want to learn more about Drupal Workflows in the Enterprise, please vote for my session.

Bookmark/Search this post with

Jan 18 2011
Jan 18

This release fixes the critical outstanding issues with Maestro. There are still some would-likes that will make it into 1.1, which is planned for release candidate around February 18th.

Among all the fixes the most important is the fix for the content type task, which was stalling after uploading a file. Version 1.0 has been fully tested in both MySQL and MSSQL Servers alike. For more information, check out the Maestro page. You can download Maestro on our project page on Drupal.org.

Changes include: - Fixed error if you don't supply an workflow id at admin/structure/maestro/edit
- fixed issue #1004354
- fix for content type upload issue if your site is named maestro (ie, http://localhost/maestro)
- fixed bug with getTrackingID, else case was identical to the if case. also sql field name process_id was changed to simply id.
- Fixed a bug in the project_content mechanism
- added $context parameter for hook_maestro_post_action_handler

Jan 07 2011
Jan 07

In light of the recent Drupal 7.0 release, we have finished testing Maestro with D7.0 and are ready to announce the first Maestro release candidate. We will continue to test for bugs, and if no critical issues arise then version 1.0 will be upon us soon!

In particular, this version of Maestro has a number of fixes for MS Sql Server users. For more information on Maestro, check out the Maestro page. You can download Maestro on our project page on Drupal.org.

Changes in this version include:
- Update to orchestrator information
- Fix for an SQL Server issue where the adjacent lines delete routine fails.
- Altered the delete routine for SQL server compatibility. Multiple replacements in a query seem to fail.
- Added a post-trigger/action execution hook called module_maestro_post_action_handler. This will allow devs to act upon the newly triggered process if need be
- Fix for issue #1018804 for all flows view being broken in SQL Server.
- Added API method to set a flow's title/description after it has been spawned.

Please feel free to contribute to the testing as well! The more eyes the better. And don't forget to follow us on Twitter for the latest news on Maestro as well as other Nextide products, @NextideInc.

Dec 26 2010
Dec 26

In the previous instalment of my $100 Drupal site series I covered resources and infrastructure. In this post I will be covering the development tools I think you need in order to build and sell Drupal sites at the $100 price point. Given that Drupal 7 is close to release, it is assumed that the sites will be built using D7. I don't believe that it is smart to invest heavily in Drupal 6 for new long term projects, given D8 could be out in 18 months and D6 would then be unsupported.

git

You are going to need a version control system for storing all of the code. There are many different version control systems available, but I think git is the most flexible and powerful option. Git allows for distributed development, offline commits and best of all, Drupal is switching to git. Gitorious is an open source clone of github which allows you to browse your git repository and manage integration of code from all of your developers.

If you are new to git I strongly recommend you get a dead tree copy of the book Pro Git.

drush

Drush is the DRUpal SHell, a command line interface for Drupal. It is an invaluable tool for developing and maintaining Drupal sites. Simple things like running "drush cc all" to clear all caches when developing sites, through to being able to sync databases from one server to another, or one continent to another, save many hours. Even if you're only running a handful of sites, you should have drush installed on all of your servers.

Modules

There are a few modules which you should be using if you want to be able to create polished Drupal based platforms. My list includes:

  • module allows developers to package up configuration as a Drupal module, including access to all the normal hooks that a module can implement. Feature is version control friendly and includes the ability to reset to a known good state, either via the Drupal web GUI or by using drush on the command line.

  • exports values from Drupal's variables table, allowing sane defaults to be set. This means your site will always be configured the way you want it to be.

  • allows you to manage contextual conditions and reactions for different portions of your site. It gives you control over displaying blocks,hierarchy of breadcrumbs, themes and other context sensitive configuration options.

  • is a menu module which makes it quick and easy to access items. (Disclaimer: I co-maintain the module)

  • can perform static analysis of your code to ensure it is secure and complies with the Drupal coding standards. The module can also be used to upgrade code from one major version of Drupal to the next.

  • is a collection of tools to help developers create Drupal sites and modules. Devel integrates with Admin to provide easy access to the devel actions.

  • provides a pluggable framework for integrating rich text editors into a Drupal site. Given the target market for the $100 sites, we can't expect our users to hand craft HTML, they'll be expecting "something like Word".

  • provides a way for end users to apply predefined CSS to designated parts of a site, without the user having to understand CSS.

Installation Profiles

When most people install Drupal for the first time they are blissfully unaware that they are using an installation profile. An installation profile sets out a base configuration for a site that is installed by Drupal. Until recently installation profiles contained a list of modules to install and a large chunk of hand crafted PHP code which setup all the configuration for a site. These days most of the configuration can live in Features and so an installation profile can be very lightweight. It is worth reviewing some of the more popular installation profiles, such as Open Atrium, Managing News or Drupal Commons, for inspiration. Installation profiles have changed a lot in Drupal 7, so you will need to port the ideas to the new way of doing things.

Drush Make

Drush Make is a tool for building Drupal platforms. Drush Make allows developers to specify all the components of their site in a text file, then use the command line tool to "make" the site. It is possible to specify a version of Drupal core (including Pressflow), contrib modules and themes, third party components, patches and external libraries.

Aegir

Aegir is a Drupal site deployment and management tool built using a collection of Drupal modules. With Aeigr you can manage your DNS, http (web) and database servers from a common UI. It is possible to move a bunch of sites from one server to another in a matter of minutes, not hours and the downtime will be measured in seconds. When security fixes are released, testing can involve a few minutes of work then a few more clicks to deploy it to all of your sites.

Workflow

Instead of me explaining development workflows, I'll defer to Miguel Jacq (aka mig5). Miguel's blog post entitled "Drupal deployments & workflows with version control, drush_make, and Aegir" is considered by many to be the key work on modern Drupal development workflows.

What's Next

Many of the tools I've covered today should be in your Drupal developer's tool bag. My next post will cover what I think are the important considerations in building the platforms for the service.

Nov 11 2010
Nov 11

There are many options for moderating posts in Drupal. A tried and true method is with the use of the modr8 module.

I used Drupal's core trigger module, the contributed workflow module and a custom action to accomplish a similar functionality.

I enabled the workflow module, and created the "course queue" workflow, with states "accepted", "pending" and "declined".

When editing the workflow, you can specify what states the author can transition the workflow to, for example you can specify that only admins can make the state to 'accepted'

Workflow access allows control over which roles can access nodes in a certain workflow state.

In my custom module, I use the text entered into a custom cck field that only the admin can enter, to email the message to the author.

<?php
/**
* Implementation of hook_action_info().
*/
function mymodule_action_info() {
return array(
'mymodule_send_approval_message_action' => array(
'description' => t('Send approval message'),
'type' => 'mymodule',
'configurable' => FALSE,
'hooks' => array(
'nodeapi' => array('view', 'insert', 'update', 'delete'),
)
),
);
}

/**
* Sends a message to course/workshop creator
*/
function mymodule_send_approval_message_action(&$node, $context) {
$u = user_load($context['node']->uid);
$to = $u->mail;
$settings['subject'] = $context['node']->type .': '. $context['node']->title;
$settings['body'] = $context['node']->field_message[0]['value'];

$message = drupal_mail('mymodule', 'author_message', $to, language_default(), $settings);
if (! $message['result']) {
watchdog('mymodule', 'Email not sent email to %recipient', array('%recipient' => $to));
}
}

/**
* Implementation of hook_mail().
*
* Set's the message subject and body as configured in the $settings of the action.
*/
function mymodule_mail($key, &$message, $settings) {
if ($key == 'author_message' || $key == 'unpublish_xth') {
$message['subject'] .= str_replace(array("\r", "\n"), '', $settings['subject']);
$message['body'][] = $settings['body'];
} elseif ($key == 'unpublish_xth') {
$message['subject'] = $settings['subject'];
$message['body'][] = $settings['body'];
}
}
?>

After enabling the custom module, you will see the action listed in the actions settings admin page.

The last step is to administer the triggers page, and add the action to each workflow state change. For example, when the workflow state is changed to accepted, besides emailing the author that the state has changed, with the admins custom note, you can also add the action to publish the node. Whereas moving the node to declined, the action can be added to unpublish the node, as well as email the author of the state change.

Mar 11 2010
Mar 11

Yesterday I saw this post with a video on the new P2 theme for Wordpress and how Automattic* is using that as a real time microblog like tool for status updates in their company. And it got me thinking...

For some time now we've been using Open Atrium in Pronovix for project management. But until today all of our real time communication takes place through Skype. At some point we tried to replace Skype with XMPP (because Skype didn't properly work on Linux) but once Skype worked again for all the colleagues Jabber got abandoned.

One of the reasons why we were interested in Jabber was to integrate activity updates into our communication tool (e.g. posting comment, case, commit messages). So that we would be able to have a discussion and have a bot post newly created cases into our chat channel.

Right now our workflow is as follows:

  • while in a Skype chat realize there is a new issue
  • go to Open Atrium
  • open a case submission form
  • fill it out and submit it
  • copy the created url
  • post it in Skype

Wouldn't it be cool if you could have 1 interface with the activity/chat river of your team where you could create new cases without having to go into another context and then have that case submitted into the activity stream where your colleagues can react on it, either through inline comments (if you want it to be stored in the ticket history) or just chat messages?

Today we did a short brainstorm on that in the office. We examined the following issues:

  • scalability: using nodes for each submitted message is not going to work for big groups (unless you throw hardware at it of course). Doing a pull system with a full Drupal bootstrap for every user's request, every second or so will eat even a decent server if you have enough users.
  • immediacy: Drupal bootstrap time and network latency will slow down the interaction.
  • security: you want to be able to make sure only people with the right permissions can see your content.

The schema below explains how we are now thinking of solving these questions:

  • For scalability we want to make a hybrid Drupal/XMPP system: this way it doesn't matter how many users are subscribed to a certain group.
  • The XMPP server has channels for all groups in the Open Atrium install.
  • Users with the permission to view content of certain groups get subscribed to the respective channels.
  • The client for the XMPP messages is a webpage in Drupal.
  • The page has a submit box for posting chat messages that get sent to the appropriate channel on the XMPP server.
  • Javascript shortcuts let you perform some of the most common operations like selection of next/previous messages; creation of the different content types available in Open Atrium.
  • Node submission forms are loaded in an overlay with the node form (this could be implemented using the modal frame API as it's done in Drupal 7).
  • A prominent context box (that's always visible) displays the last group context you viewed a message from (possibly other context too). Using prepopulate this context gets transfered to new forms you open.
  • Upon submission Drupal sends a message with the new information to a Jabber channel (this would probably be JSON)
  • XMPP messages get parsed and displayed on the webpage (comments on nodes could be displayed in a threaded way).
  • A set of filters lets you filter for streams from only certain groups.
  • A message that hasn't been selected yet, is coloured differently to indicate that it hasn't been read yet.

This is a first draft of the specification, there are still a couple of things that need to be worked out and tested. For example:

  • We still need to figure out how we will archive the stream so that users can go back in time and see messages/activities that got posted before they opened the stream page.
  • We also need to do a thorough security review of the whole system.
  • We'll also be able to add add private messaging to the interface...

PS: one thing that is getting me even more excited about this feature is the possibility to display activity streams from groups on other Open Atrium sites: with this system we could make it possible to have federated activity streams from all the Open Atrium sites you are registered on...
PPS: This model will of course also work for non-Open Atrium Drupal sites

Bookmark/Search this post with:

Apr 02 2009
Apr 02

Play Video

Movie link (right-click to download) Problem with this video? Contact me

The definition of a workflow, according to Wikipedia, is a "depiction of a sequence of operations". When taken at face value, a workflow is typically something you want to automate in Drupal. In other words, what we're talking about is Drupal Automation and my guess is, you'll want to automate things in Drupal based on certain events.

The confusing part of Drupal automation is the fact that you need to know what works together to accomplish such automation. With the modules of Workflow, Actions*, Triggers* (* Part of Drupal 6 core) and Rules, it can be quite confusing when it comes to automation.

Put simply, in Drupal 6, you can still use the Workflow module (which I don't show in the video) but you can also get by with the default Triggers and Actions (as mentioned, already installed with Drupal). However, unless you know you need to install Workflow module to achieve the automation you're seeking, and potentially install Triggerunlock module (which you don't really need if you install Workflow in Drupal 6), things can get really confusing, really fast.

So, aside from trying to confuse you with the above paragraph (I did that on purpose), about all the setup and things you do or don't need, I focused a bit more on the Rules module because it's a one-stop-shop for automation which goes beyond what you can do with Triggers, Actions and Workflow.

Even though I'm a convert to Drupal's Rules module, my compliments go out to John VanDyk (whose book helped me learn Drupal even better) for creating Workflow and Actions (which I started with in Drupal 4.7) and to Wolfgang Ziegler for creating the ever powerful Rules module. I can only hope this video will provide you with most everything you need to know to automate things so you can achieve your ultimate Drupal workflow!

Note: If you're still working with Drupal 5, then Workflow, Actions, and Workflow-Ng (also by Wolfgang) will give you the automation you need. In most all cases, you'll definitely want Token module installed so you can do the cool stuff the big boys do.

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