The State of #flagOnD8

 

For over a year now I've been working on porting Flag module to Drupal 8. We've come a long, long way.

Possibly the Oldest Drupal 8 Contrib Project Around

I started working on the module when I realized I was facing a "Reverse Sisyphus" problem in contributing to Drupal 8 directly. Instead of pushing the boulder up the hill and having it roll back down again, Drupal 8 already had a lot of momentum behind it. Each time I tried to contribute, I had to chase it down the hill in the hope that maybe I'd be able to impart some sort of momentum. I was caught in The Valley of Dearth: While I could go back to writing issue summaries, rerolling patches, or making minor code updates, I wanted to contribute "real code".

Around Drupalcon Portland, it occurred to me that goal was impossible. With only a few hours a night to work on Drupal, there was no way I could catch up. The boulder just rolled further and further away no matter how hard I ran.

So instead, I decided to start porting Flag module. While I was a co-maintainer of the module at the time, I never quite got it. The module just didn't make any sense to me. Porting it to Drupal 8 was a way for me to become familiar with the code, write a new version, and hopefully catch a few core bugs in the process.

Where is Flag at Today? What works?

Creating, editing, and deleting flags. At the core of the module is the flag configuration entity. Administrators can create, edit, and delete flags on the site through a similar UI to the D7 version. There are minor changes in how you create a new flag, but I find the UI much better. As configuration entities, flags may be exported to YAML and be put under version control. The flag entity is also fieldable for expansion by other modules.

Flag type plugins. These are new for Flag module. This plugin defines how the flag config entity relates to the entity type that can be flagged (the "flaggable"). Plugin derivatives are used for most entity types and can be easily expanded to include new types.

Link type plugins. The D7 version of Flag also had link types, but they weren't plugins. The link type defines how the flag link is displayed on the entity. Both the D7 and D8 versions have the same three link types out of the box: A normal HTML link, an AJAX link, and a link that opens a confirmation form. All three work. The AJAX link type was actually surprisingly easy to implement.

As plugins, both the flag type and link type may be easily expanded by other modules. In fact, it should be even easier than before. Base classes are provided for the plugins on which you can base your own flagging behavior. A @FlagType and an @ActionLinkType annotation is provided by Flag to make any expansions very, very easy to discover.

Flaggings. Once you define your flag, the link type is used to attach a rendered link to the target entity type as a pseudofield. This means you can change where the flag link will appear just by changing the field order of the flaggable. As you expect, when you click a flag link, the display changes indicating the entity is now flagged. A Flagging content entity is created behind the scenes to store the user's action. You can flag and unflag entities with your choice of link types.

#flagOnD8 at the Austin Extended Sprints

That was where Flag was prior to Drupalcon Austin. I attended Symphony training the first day. The next three days were very busy between sessions, hallway conversations, and talking with potential employers. While I was lucky enough to have a free place to crash, it was over an hour away via public transit. By Friday I was exhausted. I wanted to spend the day mentoring, but a few hours in, I was drained completely. I'm still angry at myself for that.

It seemed I was working on Flag during each keynote during the con. Most of the work was updating the module to deal with the most recent changes in core. It wasn't until Saturday, however, that I was able to sit down and devote my full attention to the module.

Views support was the next target. While you can use flag stuff, views allows you to build flaggings into features on your site. I had been banging my head against views for weeks before Austin but it simply wasn't clicking. While the first day of the Extended Sprints started slowly, I managed to sit down with Tim Plunkett for an hour. That hour made all the difference.

Sometime just after lunch I managed to get the keystone of the entire Flag views system to work -- the Flag relationship. The relationship specifies which flag you want to import into view. Without it, you can filter by flaggings, by flaggables, provide flag link fields, nothing. The problem with views in Drupal 8 is that the entire feature still feels...alien.

When working in Drupal 8, I was accustomed to classes, interfaces, and the entire orchestra of object-oriented constructs PHP 5.4 provides. When I hit the patch of D8 that was views, however, it was as if I had taken a wrong turn. It's like a scene out of the 1966 Batman TV show. From the street, everything was perfectly normal. Once you walk into the villain's hideout, however, the world was at a perilous Dutch angle. Much of 8.x views is merely a straight port of the 7.x version from a contrib developer's perspective. Since D7 never quite clicked with me, grappling with views remained difficult.

Once I made the critical breakthrough, however, things began to fall into place. The following day I made even more progress, porting much of Flag's views functionality. One particular sprinter, develCuy, made several pull requests to the module removing old code, and cleaning up other parts of the module.

What's left? What's the plan?

Complete views functionality. Several issues popped up with the views functionality. I've made a good amount of progress in the following weeks to resolve them. What's left is the flag views argument handlers. There may also be other bits and pieces of views functionality I'm missing. Which is why I have the next two tasks.

Get Flag Bookmark working. Flag Bookmark is an example module for Flag. In Drupal 8, it's an empty module file, an *.info.yml, a default flag entity, and two views. The bookmark flag and the views are also YAML. I've built most of it already, but I'm still getting inconsistent import behavior, especially for the views. In time I'm sure I'll sort it out. You might not think a Bookmark flag is all that useful, but it is essential for...

Tests. Most of Flag module's original test suite was behavior driven. A flag was created (usually via Flag Bookmark), and then flagging and unflagging was performed on key mock entities. While there are portions of the module that may be unit tested, the majority of Flag's tests will remain SimpleTest. If Behat gets in, that may change however.

The idea behind implementing views, then bookmark, is ensure that Flag 8.x will support the existing Flag ecosystem of modules. While bookmark is a small case, once that's completed my plan is to begin a parallel port of Flag Friend -- another module I maintain. Furthermore, it will help to identify any remaining functionality that is yet to be implemented in the 8.x version.

Was Drupalcon Austin worth it?

For that one hour with Tim Plunkett alone, yes. Being at Drupalcon itself had the side effect of removing me from the responsibilities and stresses at home, allowing me to focus and make some serious progress. Being at the con also helped me to raise more awareness for the module which in turn, has spawned several more pull requests and enhancements to Flag already.

And, I admit, it provided me a huge opportunity to network. My hope is that I'll find a job with a Drupal company that will allow me to devote more time to Flag, Drupal 8, and to aid other contributors. Nothing substantial has occurred yet, but I'm hopeful. This deserves more than just the few hours an evening I can scrape together.