Keegan is a Web Developer, focused mostly on building sites using Drupal and/or front-end JavaScript frameworks (like React.js), and is also a Drupal core contributor.
Keegan's longest-lived hobbies are being in nature, sonic-doodling, and studying the history and philosophy of science and technology. Having a degree in Environmental Science and Technology, Keegan learned early that there is no deficiency in the capabilities of modern technology to create a more equitable and sustainable global infrastructure, but a lack of funding. Hence, Keegan believes that the future of societal health depends on collective efforts to provision and employ information and communications infrastructure that is owned and controlled by the people who use it—not by the full-fledged military contractors that big tech comprises—so that love, democracy, community, and eco-friendly infrastructure can thrive.
Keegan is inspired, as a worker-owner of a tech coop, to have recognized the practical benefits of Libre software and of the cooperative model toward the respective protection and cultivation of attentional liberation, and is always beyond delighted to hear whenever someone else has made the same or similar discoveries. Most of all, Keegan is humbled to be immersed in a positive work-culture that emphasizes action-oriented ethical practices, and to be surrounded day-to-day by brilliant friends and mentors.
This is an advanced course that requires familiarity with the Drupal migration concepts. Our Drupal 11 content migrations training will give you all the background knowledge that you need. Alternatively, you can read the 31 days of migrations series in our blog or watch this video for an overview of the Migrate API.
Having a Drupal 7 and Drupal 11 local installation is required to take this course. We offer this DDEV-based repository configured with the two Drupal installations used in the training. Alternatively, you can use a tool like Lando or Docksal. You will have to be able to restore a MySQL database dump containing the Drupal 7 database. Drupal 11 site needs to be able to connect to the Drupal 7 database. Drush needs to be installed in order to run migrations from the command line.
This training will be provided over Zoom. You can ask questions via text chat or audio. Sharing your screen, but you might want to do it to get assistance on a specific issue. Sharing your camera is optional.

Attendees will receive detailed instructions on how to setup their development environment. In addition, they will be able to join a support video call days before the training event to make the the local development environment is ready. This prevents losing time fixing problems with environment set up during the training.
The Climate Justice Action Map (CJAM) is a custom mapping tool that pulls 350 events and groups from multiple data sources (eg: ActionKit, EveryAction, CiviCRM) and displays an interactive map supporters can use to get involved.

It can be embedded within websites with many customization options (eg: preset the map center to a location,, show the map’s text and buttons in a different language, show only events related to a particular campaign, etc.).
It uses Mapbox for the map, OpenStreetMaps for the tileset, and Google Maps for the search lookup.
The CJAM Extract, Transform Load (ETL) Application is a data processor written in Python that runs every 15 minutes and pulls in data from those many sources (eg: EveryAction, CiviCRM) via APIs and direct SQL queries. It writes the combined event and group data to a JSON data file hosted on Amazon S3, which is then consumed by the CJAM JavaScript.
We met with 350 in mid-June, with the strikes set for September 20th and organizing pushes in July and August. With tight deadlines, a new team and a new codebase, we quickly got to work understanding the goals of the map, its current implementation and what needed to be done for each milestone.
On projects demanding quick turnarounds it's tempting to dive head first into the issue queue. We know though, that a project is only successful if everyone is aligned on the overall goals of the project. Luckily, the product team already had excellent documentation (they even had a slideshow!) on what the purpose of the climate action map and its key audiences.
350.org had a slideshow detailing the goals and audiences, helping us gain the background knowledge needed to effectively collaborate.
Goals
Key Audiences
These documents were great to have coming into our kickoff call.
Getting familiar with the inner workings of the climate action map was particularly challenging because the code was essentially in two states: the main branch with the original custom JavaScript and a refactor branch where the transition to React.js was happening. React is one of the most popular and widely used frameworks. Converting the application to React made the code easier to maintain and build upon. The original volunteer developer had begun this process of conversion and there were new features written in the new React way, unavailable until the refactoring was complete.
Mauricio and Chris met with him to get clear on how to see the transition to the end. They then set to familiarizing themselves with the codebase and refactoring along the way. By understanding, for example, a long complex function, and then rewriting it into smaller discrete functions, we were able to simplify the code, wrap our head around its inner workings and make it easier to work with for the next developer to join the project.
When first working with a codebase it takes time to understand why a new change isn't sticking or why an error is occurring. Logs are a developer's best friend when it comes to debugging. Unfortunately, the logging available was stark. The ETL had a running log, but wasn't saving to a file for future reference or easy retrieval. Chris made the error log easy to reference and even added Slack integration sending a message to the team whenever an error occurred - helping people quickly respond to issues.
350.org has hundreds of chapters, spread across seven continents, with members speaking dozens of languages. Their mapping tool was built with this diversity in mind. It serves as a powerful storytelling device (goal number one), with a single map conveying the impressive reach of the movement, and not making assumptions as to where a visitor is or what they're looking for.
On the other hand, mobilizing is most effective when it comes from people we know, from communities we're part of. As such, the map can live in more localized contexts, showing just events and groups relevant to a particular scenario. For example, the 350 Colorado chapter can display a map zoomed into the Mountain West, while 350 France can show a map with just events in French.
These custom maps are created using embed parameters. To do this, a 350.org organizer pasted the map onto a page using an iframe, passing in parameters such as language, location and data source by including a query parameter in the url.
However, this approach was cumbersome, technically prohibitive and error prone. We dropped the iframe approach and replaced it with a series of shortcodes, a more intuitive method, that make direct calls to the Climate Action Map API to render a map specific to an organizer's needs.
We added support for the following short codes:
Now organizers can create any number of maps with criteria meeting their campaign or community's specific needs.
With so many different events happening at any given time, the map risked overwhelming visitors looking to get involved. 350.org's designer Matthew Hinders-Anderson came up with the solution of applying different map pin styles to events depending on when they were happening. Past events have a subdued teal, while current and future events have a strong teal. To emphasize the storytelling (goal number) of the map, current events throb.
To accomplish this, we needed to calculate an event's date and time relative to the current time. Unfortunately, many of the events had no timezone associated with them. However, they did all have some form of location available. Chris found a handy Python tool called timezonefinder that calculates an event's timezone based on latitude and longitude.
With the timezone in hand, Mauricio could then apply the different colors (and flashing) based on the event's time relative to now.
We used Python to calculate an event's timezone based on its latitude and longitude.
With so many events organized, we wanted potential strikers to find an event to attend quickly. Map embedders found though, that sometimes searches would result in an empty map, despite events being nearby. This is one of the many challenges of designing interactive maps. One example was a visitor living in a nearby suburb of Boston. A search for Allston would turn up nothing, despite there being multiple events within a 5 mile radius. We fine tuned the zoom in behavior to better show nearby events.
There were still edge cases though. We addressed this by showing a "Zoom out" button if a visitor came up empty. Clicking that zooms a user out to the nearest result.
If a visitor gets no results from their search, they can zoom out to the nearest event or group.
The mobilization plan was to push activists and organizers to plan events from June through August. Then rally as many people to RSVP to the newly created events from August up until the big days: September 20th and September 27th. We rolled out the embed code functionality in August which organizers put to good use, embedding local and regional specific maps on local 350 group pages and climate strike specific websites they had built.
The map was so popular, that other organizations asked if they could embed it on their own sites - increasing the mobilization points and audiences reached. That we were able to do this speaks to the importance of defending the open web and free and open source software that allows for the decentralized sharing and using of tools.
On the first day of the strikes the pin styles came to life, lighting up the many walkouts, rallies and protests happening that day. It was a go to graphic for journalists and supporters on social media to share when reporting on the unprecedented participation.
Ultimately, the numbers we saw was a testament to the long, hard work organizers constantly engage in and the urgency of the moment we are in. However, with tools like the Climate Justice Action Map, built by technology activists alongside the organizers using them, we deepen and widen the mobilizing possible. And in these times of massive wealth inequality, deep political corruption, and closing window of time for the bold action we need, disrupting the status quo is more important than ever before.
Special thanks to the 350.org product team members Kimani Ndegwa, Matthew Hinders-Anderson, Nadia Gorchakova, and suzi grishpul for their vision, management of the project and design and development leadership.
Those could be separated by a comma using CSS. For example, "By Clayton Dewey, Ben Melançon, David Valdez."
A more natural display, though, would be "By Clayton Dewey, Ben Melançon, and David Valdez." If, instead of three people, two people wrote the article (as is the case), we would want to display "By Clayton Dewey and Ben Melançon."
Before, a sitebuilder would have to abandon structured content for a text field which an editor would use instead. In other words, instead of using a reference field to display the authors (even if present on the edit form), the sitebuilder would add a regular text field for the content editor to write out the list in a more human-friendly way and that is what would be output, or the content editor would write the byline into the body field.
Now, displaying lists of structured content naturally is possible with the In Other Words module.
(More featureful listings are also possible with Twig templates, but that does not empower sitebuilders— it bogs down themers!)
For text list fields and entity reference fields, In Other Words provides the In Other Words: List field formatter. Its settings page looks like this:
This block on the home page lets you easily highlight any piece of content or landing page on your site. You can easily update the image, this text and the link to where it points.
As Elon Musk destroys Twitter, a lot of clients have asked about alternative social media, especially 'Mastodon'— meaning the federated network that includes thousands of servers, running that software and many other FLOSS applications, all providing interconnecting hubs for distributed social media. Agaric has some experience in those parts, so we are sharing our thoughts on the opportunity in this crisis.
In short: For not-for-profit organizations and news outlets especially, this is a chance to host your own communities by providing people a natural home on the federated social web.
Every not-for-profit organization lives or dies, ultimately, based on its relationship with its supporters. Every news organization, it's readers and viewers.
For years now, a significant portion of the (potential) audience relationship of most organizations has been mediated by a handful of giant corporations through Google search, Facebook and Twitter social media.
A federated approach based on a protocol called ActivityPub has proven durable and viable over the past five years. Federated means different servers run by different people or organizations can host people's accounts, and people can see, reply to, and boost the posts of people on the other servers. The most widely known software doing this is Mastodon but it is far from alone. Akkoma, Pleroma, Friendica, Pixelfed (image-focused), PeerTube (video-focused), Mobilizon (event-focused), and more all implement the ActivityPub protocol. You can be viewing and interacting with someone using different software and not know it— similar to how you can call someone on the phone and not know their cellular network nor their phone model.
The goal of building a social media following of people interested in (and ideally actively supporting) your organization might be best met by setting up your own social media.
This is very doable with the 'fediverse' and Mastodon in particular. In particular, because the number of people on this ActivityPub-based federated social web has already grown by a couple million in the past few weeks— and that's with Twitter not yet having serious technical problems that are sure to come with most of its staff laid off. With the likely implosion of Twitter, giving people a home that makes sense for them is a huge service in helping people get started— the hardest part is choosing a site!
People fleeing Twitter as it breaks down socially and technically would benefit from your help in getting on this federated social network. So would people who have never joined, or long since left, Twitter or other social media, but are willing to join a network that is less toxic and is not engineered to be addictive and harmful.
Your organization would benefit by having a relationship with readers that is not mediated by proprietary algorithms nor for-profit monopolies. It makes your access on this social network more like e-mail lists— it is harder for another entity to come in between you and your audience and take access away.
But the mutual benefits for the organization and its audience go beyond all of this.
When people discuss among one another what the organization has done and published, a little bit of genuine community forms.
Starting a Mastodon server could be the start of your organization seeing itself as not only doing good works or publishing media, but building a better place for people to connect and create content online.
The safety and stability of hosting a home on this federated social network gives people a place to build community.
But organizations have been slow to adopt, even now with the Twitter meltdown. This opens up tho opportunity for extra attention and acquiring new followers.
Hosting the server could cost between $50 to $450 a month, but this is definitely an opportunity to provide a pure community benefit (it is an ad-free culture) and seek donations, grants, or memberships.
The true cost is in moderation time; if volunteers can start to fill that you are in good shape. A comprehensive writeup on everything to consider is here courtesy the cooperatively-managed Mastodon server that Agaric Technology Collective chose to join at social.coop's how to make the fediverse your own.
You would be about the first for not-for-profit or news organizations.
You would be:
And it all works because of the federation aspect— your organization does not have to provide a Twitter, TikTok, or Facebook replacement yourselves, you instead join the leading contender for all that.
By being bold and early, you will also get media attention and perhaps donations and grants.
The real question is if it would divert scarce resources from your core work, or if the community-managing aspects of this could bring new volunteer (or better, paid) talent to handle this.
Even one person willing to take on the moderator role for a half-hour a day to start should be enough to remove any person who harasses people on other servers or otherwise posts racist, transphobic, or other hateful remarks.
Above all, your organization would be furthering your purpose, through means other than its core activities or publishing, to inform and educate and give people more capacity to build with you.
Not surprisingly, Drupal has already figured this out!
Thanks to Tony Groff, Agaric has a ticket to DrupalCon Denver to give away to a reader of the Definitive Guide to Drupal 7 who sends in a story (or picture!) of a favorite use of the 1,110 page book— today!
Did Jacine Luisi's tour de force break a barrier to Drupal 7 theming for you? Did Károly Négyesi's 4-page "Developing from a Human Mindset" chapter change the way you do Drupal? Did you win a bet because your favorite module was mentioned? Did the book save your life by absorbing the impact of a small meteorite when you took it to the beach for some light reading? Let us know!
In other DGD7 news, Greg Anderson has posted Drush 5 updates to his fantastic Drush chapter. Check it out, and don't forget to sign up for updates like this and new tips and material (low-volume newsletter; fewer than once a month).
Even if you are already going to, or cannot make, the March 20-22 DrupalCon Denver party with more than 3,000 of some of your closest friends already signed up, including many Definitive Drupal authors, we'd love to hear about your successes – or frustrations – with the best-selling, best-value book on Drupal 7.
We can't help out with travel or lodging, but we hope getting the con itself covered can prompt you, on this leap day, to take a fortuitous leap and see if DGD7 can't be a step up further into Drupal in yet another way. Thanks for reading!
Former school teacher turned technologist, Clayton now applies his background in linguistics, community organizing and web development as a user experience architect for Agaric and co-founder of Drutopia.
Clayton has worked with universities, open source companies, tech diversity advocates, prison abolitionists, and others to translate their organizational goals into impactful digital tools with meaningful content.
Aside from content strategy and information architecture, Clayton also enjoys being a goofy dad and always appreciates a good paraprosdokian.
It could be in Articles of Organization, ByLaws or a simple contractual agreement between members or even a handshake. A cooperative or collective is defined by the members.
Talk to people in your personal network about your goal.
Let former co-workers know you are forming or seeking to work with a cooperative.
There are meetups (meetup.com) or you could start one in your area.
Reach out to mailing lists you are on and ask if people are interested in working collectively.
Food:
Worker coops:
usworker.coop - member-directory
Open Directory search for all types of coops:
and Twitter - https://twitter.com/hashtag/cooperatives
Encourage pooled funds from successful cooperatives to help bootstrap new proposed cooperatives
Get involved in conversations, and create conversations. Let others know you are interested in cooperative work experiences and you are seeking information and connections.
There are four principles, freedoms, that define free software, the building blocks of this Digital Commons resource we all rely on.
When software is built this way, it protects us as users from malicious backdoors compromising our security, proprietary algorithms obscuring what we see and don't see, and predatory vendors locking us into expensive contracts. It also democratizes our technology - making it free for anyone to install and make use of. Examples of software in the digital commons include the Firefox browser, Linux operating system, and MediaWiki (which powers Wikipedia).
Using free software doesn't automatically mean that one is fully participating in the Digital Commons. For example, we use Drupal, Django, and WordPress to build websites. It is common for sites to then add on custom code, or configure their site in unique ways - source code that is hidden from the general public.

The diagram above shows an example website that has most of its software within the Digital Commons. However, there is some custom code (code written by someone that hasn't been released back into the commons) and some proprietary software integrating with the site.

Taking a closer look at who is maintaining and contributing to the various projects, we see that the software in the Digital Commons has many more people behind it. When something is free and open, then communities of literally thousands of people can help maintain the software. When something is custom code, only the original creator and their coworkers can maintain it (poor David). And when it comes to proprietary software, we're handing complete control over to the company who owns it.
Freedom 1, the freedom to study how a program works, ensures that site visitors and users know exactly what a website or app is doing. Even if a website starts out using free software, it's possible to extend it to do all sorts of malicious things. Sharing one's code with the world is a way to communicate transparency. Note that, this is separate from one's data, such as user passwords and personal information - that stays under lock and key.
Keeping all code written out in the open also adds a layer of auditability regarding quality. We follow software development best practices and to back that up, we share that code with the world. Besides, best practices aren't always cut and dried, and there are often opportunities to make good code, great.
When possible, we write and use what is called "contributed code." This is code that has been written in a generalizable way so that others can also benefit from it. Often, a tool already exists to solve a problem. Other times a tool might get a project 90% of the way there. Some might decide to meet their unique case by building something from scratch. We, however, prefer to build upon existing solutions.
For example, when we built the ability for Portside to cross-post their articles to Twitter, we did that by improving the Social Post Twitter module - a tool anyone running a Drupal site can use as well. We could have written that as custom code, only for Portside to use. However, we took the time to contribute this back to the community.
Contributing code to the Digital Commons is not just a kind thing to do; it helps strengthen the software we rely on. As mentioned above, now the Social Post Twitter module is available for others to audit and make improvements to. While custom code is maintained by whoever initially wrote it, contributing code back to the commons opens that software up to maintenance and improvement from a wider community. The more sites using that software, the more attention and care it receives.
It can take more time to contribute code back to the commons than creating a one-off solution. For nonprofits and other organizations on small budgets, it may seem impractical or foolish to take the extra time to contribute code. However, we've found that the stability and future improvements gained by keeping the code in the commons is well worth it. It also ensures your software is maintainable moving forward. We've seen nonprofits get burned time and again by developers who choose to write custom code that is then difficult for others (or even the original authors!) to come in and maintain. By keeping your software in the commons, you protect your projects with the strength of the free software community.
Funding a solution that will then be shared and available for others to use for free can again sound foolishly selfless. Why should we let other organizations use for free what we had to commit significant resources to? It can feel odd to sponsor work others get for free. However, it's important to keep in mind that no software is built from scratch. We all stand on the shoulders of those who came before us. The functionality free software already provides, was paid for by someone else – either with money or volunteer time. When our clients are generous enough to agree to contribute their solutions back to the commons, we are sure to recognize them for it. This both lets others know the stewardship and leadership they're making in the Digital Commons.
Now that you know more of the Digital Commons you are part of, we hope you join us in taking care of and benefiting from it. If you're a freelancer or agency, look for opportunities to change your workflow to deepen your participation in the commons. If you're an organization, audit your existing technology stack. Are there tools you use which are proprietary that you could be using free software for instead? Do you have custom solutions that would be better off contributed to the commons? Is your website or app's source code posted for people to audit and learn from? The next time you budget for a new improvement, discuss how that could be contributed back. Being part of the Digital Commons makes the software we all use stronger.
Select ID and click Add and configure contextual filters.

IndieWebCamp is a movement dedicated to growing the independent web, or IndieWeb: a people-focused alternative to the corporate web. The movement is called IndieWebCamp because it is built in large part over an on-going series of two-day camps. At these camps and online, the community emphasizes principles over particular projects or software— any web site can be a part of the IndieWeb. Here's how to take a first step into the IndieWeb with Drupal.
All the benefits from brewing your own website touted by IndieWebCamp are indeed great. Your content belongs unambiguously and in real and practical ways to you; at the least it won't disappear when yet another company shuts down or is acquired and tells its fans "thanks for supporting us on our incredible journey". Above all, you are in control of what you post, how it is presented, and how others can find it. All this may be familiar to web developers as the concept of "having a web site."
If that was all there was to the movement, IndieWebCamp would be a call to do it like we did it in 1998. Instead, IndieWebCamp goes the next step by recognizing that people use the corporate web of Facebook, Twitter, Tumblr (Yahoo), Blogger (Google), Flickr (Yahoo), LiveJournal (SUP Media), YouTube (Google), and others in large because of the experience they provide for interactions between people. IndieWebCamp takes on the challenge of designing user experiences and formats and protocols which make following, sharing, and responding just as easy on the independent web of personal sites and blogs.
To this end of making social interaction native to independent sites, IndieWeb principles and practice teach a couple of new tricks to old web sites. One of these tricks, which we will not cover today, provides a bridge from independent sites to the monolithic services most people use today by implementing the approach of Publish (on your) Own Site, Syndicate Elsewhere (POSSE). This means that posting on your own site provides an advantage in that your posts and status messages can go to all services rather than get stuck inside only one.
The first steps of getting on the IndieWeb (after joining the #indiewebcamp IRC channel) are very familiar to web developers: Put up a web site. We were all set with a domain name for Agaric and with web hosting, so we could skip right to setting up our home page and signing in.
All you need to do for this step is to add rel=me to a link to an online profile that links back to your home page, identifying yourself in both places as you. In our case, we added the rel="me" attribute to a link to our Twitter profile. Twitter puts rel="me" on the web site link on their profiles. We did have to make sure we linked to Twitter with https not http so that the redirect didn't interfere with verifying our web sign in capability with IndieWebify.me. The link to Agaric's Twitter account on our page looks like this:
<a href="https://twitter.com/agaric" rel="me">Twitter</a>
Next up is giving the independent web some basic facts of our identity using the h-card microformat. I've never heard anyone claim that microformats have the most intuitive names, but all the properties are documented. We edited our page.tpl.php template to add the h-card class to a h1 tag surrounding our logo, to which we added the class u-logo and our site name with linking to our homepage, to which we added the classes p-name and u-url. Again using IndieWebify.me we verified that the h-card could be read. The markup looks like this:
<h1 class="container h-card"><a href="http://agaric.com/" id="logo" rel="home" title="Agaric home"><img alt="Agaric home" class="u-logo" height="80" src="http://agaric.com/sites/all/themes/agaric_bootstrap/logo.png" width="80" /></a> <a class="p-name u-url" href="http://agaric.com/" rel="home me" title="Home">Agaric</a> <small>We build online.</small></h1>
Finally, blog posts themselves are each marked up as an h-entry and elements of each blog post with h-entry properties. (The IndieWebCamp wiki has a stub article for h-entry and the markup IndieWeb makes use of, but we found the h-entry listing on microformats.org to be clearer.) For blog posts' markup we did a lot of work in template preprocess hooks. For example, here we add the h-entry class itself, the p-name class for the blog title, and (with a bit of reconstruction of Drupal's $submitted variable) the dt-published class for the date and time the blog post was published:
/**
* Implements hook_preprocess_node().
*/
function agaric_bootstrap_preprocess_node(&$variables) {
if ($variables['type'] == 'blog') {
$variables['classes_array'][] = 'h-entry';
if (!isset($variables['title_attributes']['class'])) {
$variables['title_attributes_array']['class'] = array();
}
$variables['title_attributes_array']['class'][] = 'p-name';
$datetime = format_date($variables['node']->created, 'custom', 'Y-m-d h:i:s');
$formatted_date = '<time class="dt-published" datetime="' . $datetime . '">' . $variables['date'] . '</time>';
$variables['submitted'] = t('Submitted by !username on !datetime', array('!username' => $variables['name'], '!datetime' => $formatted_date));
}
}
Here's the IndieWebify.me validation for this very blog post. The markup looks like this:
<article about="/blogs/marking-drupals-blog-posts-indieweb" class="node node-blog h-entry clearfix" id="node-262" typeof="sioc:Post sioct:BlogPost">
<h1 class="p-name"><a class="u-url" href="http://agaric.com/blogs/marking-drupals-blog-posts-indieweb" rel="bookmark" title="Marking up Drupal's blog posts for the IndieWeb">Marking up Drupal's blog posts for the IndieWeb</a></h1>
<span content="2015-05-04T11:58:16-04:00" datatype="xsd:dateTime" property="dc:date dc:created" rel="sioc:has_creator">Submitted by <a about="/people/benjamin-melan%C3%A7on" class="p-author h-card username" datatype="" href="http://agaric.com/people/benjamin-melan%C3%A7on" property="foaf:name" rel="author" title="View user profile." typeof="sioc:UserAccount" xml:lang="">Benjamin Melançon</a> on <time class="dt-published" datetime="2015-05-04 11:58:16">Mon, 05/04/2015 - 11:58</time></span>
<div class="e-content">…</div>
</article>
What do you think of the IndieWebCamp movement and its goal of making distributed sharing and following easy, while not prescribing which platforms or technologies to use? How about Agaric's far-from-automated approach to making a Drupal site part of the IndieWeb? And do you think Drupal should try to be more IndieWeb-ready as we expect another burst of growth with the release of Drupal 8?