Skip to main content

Blog

This blog post is about Drutopia right now, not about all the ways we can improve it.

Daily use

Building your website on Drutopia has the advantage of allowing multiple people to create content of different defined types that can be clearly related to one another, listed and presented in different ways, and filtered. This is the super-power of structured content.

Drutopia's main disadvantages are that free-form changing how it looks is slow and takes specialized knowledge (unlike Wix or Squarespace which are primarily page builders), and it does not have many themes to choose from (which WordPress has).

The defined types of content available in Drutopia are:

  • Article for time-sensitive content like news or press releases, where the perspective is representative of the whole organization.
  • Blog for personal or journal-like posts, where authorship is more important.
  • Person for featuring people on your site such as staff, volunteers, or contributors.
  • Event Events have a date and time, an event type, and all the usual Drutopia fields (title, image, description, topic, and tags).
  • Resource can be text and images like any content; an attached file, such as a PDF; or a link, such as a website URL; or an embedded video.
  • Campaign: A campaign includes background information as well as ability to list demands and updates.
  • Action: An action is a specific, single action a user can take.

All of these types of content can be connected by Topic, for site-wide curated categorization and by Tags for site-wide free-form categorization. Most content types can be further distinguished by type (article type, person role or type, event type etc).

Content is composed of sections, which can be the usual WYSIWYG text editor that allows insertion of images and other media, or more specialized sections for image, video, or file. This capability to mix different kinds of sections on pages is under-utilized at present in Drutopia but can be extended to be able to embed forms, including donation forms, or listings of other content.

Additional content types, which do not have the benefits of automatic listing pages with faceted search because they are meant for one-off or unique content, are:

  • Basic page for static content such as an ‘About us’ page or the privacy policy.
  • Landing page for custom pages, including potentially replacing the home page. Landing pages do not currently have a meaningful distinction from basic pages and are deprecated, but may be brought back with a special full-page free-form editor such as the Gutenberg editor developed by WordPress.

Long-term

A lot of the long-term advantage is having structured content you can make use of in ever-evolving ways, rather than having an undifferentiated mass of pages that can only be sorted through slowly and with difficulty.

But here we are taking a step back and looking at the platform more generally.

Drutopia is open source free software

In summary

Weebly, Wix, Squarespace, or inferior options bundled with other services such as Mailchimp Website Builder and GoDaddy Website Builder, do not allow creating content of carefully defined types, with relationships and connections between content. There are also usually limitations or extra costs associated with having multiple user accounts, or multiple people logged in at the same time. They let you change how the whole site and different pages look pretty easily. Moving your content to different hosting but keeping the software that runs the site is impossible, and switching to another platform and keeping your content is difficult.

WordPress allows some structured content and some customization of the look of the whole site pretty easily. WordPress can be hosted in different places (beware proprietary plugins though). WordPress content exports well if you want to change to a different software platform. Drutopia can import WordPress content.

Drutopia comes with a set of useful kinds of content already defined, complete with listing pages that can be filtered by cross-site topics and within-section types. Drutopia has limited visual customization currently available without knowing HTML, CSS, how to make templates, and how to work with a local development environment. Drutopia content exports well if you want to change to a different software platform, although to get the full benefit the other platform will need Drupal's capability to have structured content with rich relationships among content.

Donate.

So often an organization's online donation system is divorced from their website. For staff, it means one more tool to use and manage. For supporters, it can result in a donation experience that is tedious or clunky. There are free software tools like CiviCRM and CommitChange which do a good job of feeling integrated into your site, despite being a separate system. However, for smaller groups these tools can be overkill. We built the Give module to provide a lightweight donation solution built right into your Drupal site.

 

 

This blog post series, cross-posted at UnderstandDrupal.com as well as here on Agaric.coop, is made possible thanks to these generous sponsors. Contact Understand Drupal if your organization would like to support this documentation project, whether the migration series or other topics.

Websites powered by Find It connect people to all that their communities have to offer.  Developed under the guidance of the Cambridge Kids' Council, Find It ensures that people from all backgrounds can easily find activities, services, and resources.

Find It's design was informed by hundreds of hours of research, including over 1,250 resident surveys and over 120 interviews with service providers. Six years of research and development and continuous improvements has resulted in the Find It approach and platform, ready to be implemented in cities and communities around the world.

Whimsical simple silhouette of adult figure with magnifying glass followed by a child figure.

Find It Platform

An Open-Source Program and Event Locator for Communities

Dave Onion has been building Drupal sites since the mid 2000s when his work with independent media, and various organizing projects led him to learn Drupal (starting around the release of Drupal 4.7) as a tool to be able hand off the reigns to non techies who needed to manage their own web sites. 

Since then Dave has worked with a wide range of organizations providing front line web building support for social movements, from struggles to shut down prisons, independent news papers, the Occupy movement, movement gatherings and social spaces and more.

Dave has also been involved in a number of other tech projects including autonomous community controlled cell phone networks in Mexico, off grid solar projects supporting community struggles and land occupations and local mesh networks in his home town of Philadelphia.

He believes technologies should be firmly in control of communities who use them.

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!

Group photo of DrupalCamp Lagos y Volcanes

 

Camp volunteers passing out t-shirts to attendees.

 

Lucas Hedding lead a sprint on Saturday morning. Most sprinters were people who had never worked with Drupal before the camp. They learned how to contribute to Drupal and worked on a few patches. One pleasant surprise was when Lucas went on stage with one of the sprinters and proceeded with the live commit ceremony. I was overjoyed that even with a short sprint an attendee’s contribution was committed. Congrats to Jorge Morales for getting a patch committed on his first sprint! And thanks to Holger Lopez, Edys Meza, and Lucas Hedding for mentoring and working on the patch.

Súper contentos de tener un live commit como resultado del sprint liderado por @lucashedding en el #DrupalCampNi2017. ¡Mil gracias Jorge por tu contribución a #Drupal! pic.twitter.com/w9wspKZGUH — Drupal Nicaragua (@drupalni) November 18, 2017

 

 

Swag

Northern Lights DrupalCamp decided to change the (physical) swag for experiences. What we lived was epic! For our camp, we went for a low cost swag. The only thing we had to pay for was t-shirts. Other local communities recommended us to have them and so we did. The rest was a buffet of the things I have collected since my first DrupalCon, Austin 2014: stickers, pins, temporary tattoos. It was funny trying to explain where I had collected each item. I could not remember them all, but it was nice to bring back those memories. We also had hand sanitizer and notebooks provided by local communities. Can you spot your organization/camp/module/theme logo on our swag table?

¿Cuántos no aman los stickers?

Pase y llévese los que quiera 👀#DrupalCampNi2017 pic.twitter.com/EMiX8u9No8

— Drupal Nicaragua (@drupalni) November 17, 2017

 

Los stickers volaron ayer 🚀 Hoy les traemos pines, agendas y sanitizates de mano😎 ¡Vengan antes que se acaben! 😱 pic.twitter.com/oZmbdJWBa9 — Drupal Nicaragua (@drupalni) November 18, 2017

Attendee showing off the DrupalCamp Lagos y Volcanes t-shirt.

 

 

Free software communities

We were very lucky to have the support of different local communities. We learned a lot from their experiences organizing events. They also sent an army of volunteers and took the microphone to present on different subjects. A special thank you to the WordPress Nicaragua community who helped us immensely before, during, and after the event. It showed that when communities work together, we make a bigger impact.

Photo of attendees with final slide to their right.

Muchas gracias a la comunidad de #WordPress Nicaragua por su apoyo en el #DrupalCampNi2017 👏 Trabando juntos para promover la adopción del #software #libre en el país. 🤝 @wpnicaragua pic.twitter.com/OxPI0U7tmI

— Drupal Nicaragua (@drupalni) November 18, 2017

 

Keeping momentum

Two weeks after the camp, we held two Global Training Days workshops. More than 20 people attended. I felt honored when some attendees shared that they had travelled from distant places to participate. One person travelled almost 8 hours. But more than distance, it was their enthusiasm and engagement during the workshops that inspired us. The last month has been very exhausting, but the local community is thrilled with the result.

Nuevo amigos en el mundo de #drupal. Compañeros del taller Drupal desde cero en Leon, Nicaragua #DrupalGTD pic.twitter.com/f9zaRBrORH — Lucas Hedding (@lucashedding) December 4, 2017

 

 

Gracias por acompañarnos hoy en el taller #drupal desde cero en #Managua, #Nicaragua. Introduciendo nuevas personas al mundo web. #DrupalGTD pic.twitter.com/461dcZgm7i

— Drupal Nicaragua (@drupalni) December 2, 2017

 

A blooming community

The community has come a long way since I got involved in 2011. We have had highs and lows. Since Lucas and myself kickstarted the Global Training Days workshops in 2014 we have seen more interest in Drupal. By the way, this edition marked our third anniversary facilitating the workshop! But despite all efforts, people would not stay engaged for long after initially interacting with the community. Things have changed. In the last year interest in Drupal has increased. We have organized more events and more people have attended. Universities and other organizations are approaching us requesting trainings. And what makes me smile most… the number of volunteers is at its all-time peak. In the last month alone, the number of volunteers have almost doubled. The DrupalCamp and the Global Training Days workshops contributed a lot to this. We recognize that the job is far from complete and we already have plans for 2018. One of the things that we need to do is find job opportunities. Even if people enjoy working with Drupal they need to make a living. If you are an organization looking for talent consider Nicaragua. We have very great developers. Feel free to get in touch to put you in contact with them.

Volunteer at the table.Attendee at their laptop.

  En el #DrupalCampNi2017 además de aprender también nos divertimos mucho. 😂 pic.twitter.com/ulfFzEvJ4H — Drupal Nicaragua (@drupalni) November 18, 2017

 

 

A personal thank you

I would like to take this opportunity to say thanks to Felix Delattre. He started the Drupal community in Nicaragua almost a decade ago. He was my mentor. He gave me my first Drupal gig. At a time when there was virtually no demand for Drupal talent in my country, that project helped me realize that I could make a living working with Drupal. But most importantly, Felix taught me the value of participating in the community. I remember creating my drupal.org account after he suggested it in a local meetup.

His efforts had a profound effect on the lives of many, even beyond the borders of my country or those of a single project. Felix was instrumental in the development of local communities across Central and South America. He also started the OpenStreetMap (OSM) community in Nicaragua. I still find it impressive how OSM Nicaragua have mapped so many places and routes. In some cities, their maps are more accurate and complete than those of large Internet corporations. Thank you Felix for all you did for us!

Group photo of attendees raising up their arms in excitement.

We hope to have you in 2018!

The land of lakes and volcanoes awaits you next year. Nicaragua has a lot to offer and a DrupalCamp can be the perfect excuse to visit. ;-) Active volcanoes, beaches to surf, forests rich in flora and fauna are some of the charms of this tropical paradise.

Let’s focus on volcanoes for a moment. Check out this website for a sneak peek into one of our active volcanoes. That is Masaya, where you can walk to the border of the crater and see the flow of lava. Active volcanoes, dormant volcanoes, volcanoes around a lake, volcanoes in the middle of a lake, lagoons on top of volcanoes, volcanoes where you can “surf” down the slope... you name it, we have it.

We would love to have you in 2018!

Y el #DrupalCampNi2017 llega a su fin. ¡Gracias a tod@s los patrocinadores, ponentes, voluntari@s y asistentes por este gran evento! Nos vemos en el 2018. 🙌 pic.twitter.com/tP3Um2yThw

— Drupal Nicaragua (@drupalni) November 18, 2017

 

In this album there will be more photos of the event.

Today we will learn how to migrate content from a Comma-Separated Values (CSV) file into Drupal. We are going to use the latest version of the Migrate Source CSV module which depends on the third-party library league/csv. We will show how configure the source plugin to read files with or without a header row. We will also talk about a new feature that allows you to use stream wrappers to set the file location. Let’s get started.

Getting the code

You can get the full code example at https://github.com/dinarcon/ud_migrations The module to enable is UD CSV source migration whose machine name is ud_migrations_csv_source. It comes with three migrations: udm_csv_source_paragraph, udm_csv_source_image, and udm_csv_source_node.

You can get the Migrate Source CSV module is using composer: composer require drupal/migrate_source_csv. This will also download its dependency: the league/csv library. The example assumes you are using 8.x-3.x branch of the module, which requires composer to be installed. If your Drupal site is not composer-based, you can use the 8.x-2.x branch. Continue reading to learn the difference between the two branches.

Understanding the example set up

This migration will reuse the same configuration from the introduction to paragraph migrations example. Refer to that article for details on the configuration: the destinations will be the same content type, paragraph type, and fields. The source will be changed in today's example, as we use it to explain JSON migration. The end result will again be nodes containing an image and a paragraph with information about someone’s favorite book. The major difference is that we are going to read from JSON.

Note that you can literally swap migration sources without changing any other part of the migration. This is a powerful feature of ETL frameworks like Drupal’s Migrate API. Although possible, the example includes slight changes to demonstrate various plugin configuration options. Also, some machine names had to be changed to avoid conflicts with other examples in the demo repository.

Migrating CSV files with a header row

In any migration project, understanding the source is very important. For CSV migrations, the primary thing to consider is whether or not the file contains a row of headers. Other things to consider are what characters to use as delimiter, enclosure, and escape character. For now, let’s consider the following CSV file whose first row serves as column headers:

unique_id,name,photo_file,book_ref
1,Michele Metts,P01,B10
2,Benjamin Melançon,P02,B20
3,Stefan Freudenberg,P03,B30

This file will be used in the node migration. The four columns are used as follows:

  • unique_id is the unique identifier for each record in this CSV file.
  • name is the name of a person. This will be used as the node title.
  • photo_file is the unique identifier of an image that was created in a separate migration.
  • book_ref is the unique identifier of a book paragraph that was created in a separate migration.

The following snippet shows the configuration of the CSV source plugin for the node migration:

source:
  plugin: csv
  path: modules/custom/ud_migrations/ud_migrations_csv_source/sources/udm_people.csv
  ids: [unique_id]

The name of the plugin is csv. Then you define the path pointing to the file itself. In this case, the path is relative to the Drupal root. Finally, you specify an ids array of columns names that would uniquely identify each record. As already stated, the unique_id column servers that purpose. Note that there is no need to specify all the columns names from the CSV file. The plugin will automatically make them available. That is the simplest configuration of the CSV source plugin.

The following snippet shows part of the process, destination, and dependencies configuration of the node migration:

process:
  field_ud_image/target_id:
    plugin: migration_lookup
    migration: udm_csv_source_image
    source: photo_file
destination:
  plugin: 'entity:node'
  default_bundle: ud_paragraphs
migration_dependencies:
  required:
    - udm_csv_source_image
    - udm_csv_source_paragraph
  optional: []

Note that the source for the setting the image reference is photo_file. In the process pipeline you can directly use any column name that exists in the CSV file. The configuration of the migration lookup plugin and dependencies point to two CSV migrations that come with this example. One is for migrating images and the other for migrating paragraphs.

Migrating CSV files without a header row

Now let’s consider two examples of CSV files that do not have a header row. The following snippets show the example CSV file and source plugin configuration for the paragraph migration:

B10,The definite guide to Drupal 7,Benjamin Melançon et al.
B20,Understanding Drupal Views,Carlos Dinarte
B30,Understanding Drupal Migrations,Mauricio Dinarte
source:
  plugin: csv
  path: modules/custom/ud_migrations/ud_migrations_csv_source/sources/udm_book_paragraph.csv
  ids: [book_id]
  header_offset: null
  fields:
    - name: book_id
    - name: book_title
    - name: 'Book author'

When you do not have a header row, you need to specify two more configuration options. header_offset has to be set to null. fields has to be set to an array where each element represents a column in the CSV file. You include a name for each column following the order in which they appear in the file. The name itself can be arbitrary. If it contained spaces, you need to put quotes (') around it. After that, you set the ids configuration to one or more columns using the names you defined.

In the process section you refer to source columns as usual. You write their name adding quotes if it contained spaces. The following snippet shows how the process section is configured for the paragraph migration:

process:
  field_ud_book_paragraph_title: book_title
  field_ud_book_paragraph_author: 'Book author'

The final example will show a slight variation of the previous configuration. The following two snippets show the example CSV file and source plugin configuration for the image migration:

P01,https://agaric.coop/sites/default/files/pictures/picture-15-1421176712.jpg
P02,https://agaric.coop/sites/default/files/pictures/picture-3-1421176784.jpg
P03,https://agaric.coop/sites/default/files/pictures/picture-2-1421176752.jpg
source:
  plugin: csv
  path: modules/custom/ud_migrations/ud_migrations_csv_source/sources/udm_photos.csv
  ids: [photo_id]
  header_offset: null
  fields:
    - name: photo_id
      label: 'Photo ID'
    - name: photo_url
      label: 'Photo URL'

For each column defined in the fields configuration, you can optionally set a label. This is a description used when presenting details about the migration. For example, in the user interface provided by the Migrate Tools module. When defined, you do not use the label to refer to source columns. You keep using the column name. You can see this in the value of the ids configuration.

The following snippet shows part of the process configuration of the image migration:

process:
  psf_destination_filename:
    plugin: callback
    callable: basename
    source: photo_url

CSV file location

When setting the path configuration you have three options to indicate the CSV file location:

  • Use a relative path from the Drupal root. The path should not start with a slash (/). This is the approach used in this demo. For example, modules/custom/my_module/csv_files/example.csv.
  • Use an absolute path pointing to the CSV location in the file system. The path should start with a slash (/). For example, /var/www/drupal/modules/custom/my_module/csv_files/example.csv.
  • Use a stream wrapper. This feature was introduced in the 8.x-3.x branch of the module. Previous versions cannot make use of them.

Being able to use stream wrappers gives you many options for setting the location to the CSV file. For instance:

  • Files located in the public, private, and temporary file systems managed by Drupal. This leverages functionality already available in Drupal core. For example: public://csv_files/example.csv.
  • Files located in profiles, modules, and themes. You can use the System stream wrapper module or apply this core patch to get this functionality. For example, module://my_module/csv_files/example.csv.
  • Files located in remote servers including RSS feeds. You can use the Remote stream wrapper module to get this functionality. For example, https://understanddrupal.com/csv-files/example.csv.

CSV source plugin configuration

The configuration options for the CSV source plugin are very well documented in the source code. They are included here for quick reference:

  • path is required. It contains the path to the CSV file. Starting with the 8.x-3.x branch, stream wrappers are supported.
  • ids is required. It contains an array of column names that uniquely identify each record.
  • header_offset is optional. The index of record to be used as the CSV header and the thereby each record's field name. It defaults to zero (0) because the index is zero-based. For CSV files with no header row the value should be set to null.
  • fields is optional. It contains a nested array of names and labels to use instead of a header row. If set, it will overwrite the column names obtained from header_offset.
  • delimiter is optional. It contains one character column delimiter. It defaults to a comma (,). For example, if your file uses tabs as delimiter, you set this configuration to \t.
  • enclosure is optional. It contains one character used to enclose the column values. Defaults to double quotation marks (").
  • escape is optional. It contains one character used for character escaping in the column values. It defaults to a backslash (****).

Important: The configuration options changed significantly between the 8.x-3.x and 8.x-2.x branches. Refer to this change record for a reference of how to configure the plugin for the 8.x-2.x.

And that is how you can use CSV files as the source of your migrations. Because this is such a common need, it was considered to move the CSV source plugin to Drupal core. The effort is currently on hold and it is unclear if it will materialize during Drupal 8’s lifecycle. The maintainers of the Migrate API are focusing their efforts on other priorities at the moment. You can read this issue to learn about the motivation and context for offering functionality in Drupal core.

Note: The Migrate Spreadsheet module can also be used to migrate data from CSV files. It also supports Microsoft Office Excel and LibreOffice Calc (OpenDocument) files. The module leverages the PhpOffice/PhpSpreadsheet library.

What did you learn in today’s blog post? Have you migrated from CSV files before? Did you know that it is now possible to read files using stream wrappers? Please share your answers in the comments. Also, I would be grateful if you shared this blog post with others.

Next: Migrating JSON files into Drupal

This blog post series, cross-posted at UnderstandDrupal.com as well as here on Agaric.coop, is made possible thanks to these generous sponsors: Drupalize.me by Osio Labs has online tutorials about migrations, among other topics, and Agaric provides migration trainings, among other services. Contact Understand Drupal if your organization would like to support this documentation project, whether it is the migration series or other topics.

We partnered with the City of Cambridge to redesign Find It Cambridge, an online opportunity locator serving city residents, in a unique way— designing and developing out in the open, and releasing the software under an open-source license so that other cities can spin up their own Find It platforms.

Cambridge, like many cities, has a wide array of programs and events happening to serve residents. However, it can be difficult for people to find and compare the many offerings out there. The city website has a calendar of events and list of departments. These are limited to government-run programs, though. There are myriad nonprofits and community groups that run programs and events that go unlisted. Social media platforms like Facebook have filled the gap in some areas, but promotion of these opportunities relies in many ways on people's social connections— leaving those most in need of services out of the loop. Find It Cambridge solves this problem by aggregating the many different opportunities happening into one website.

The upgrade and migration from Drupal 7 to Drupal 8 (ready for Drupal 9!) afforded Cambridge and Agaric the opportunity to make the directory of organizations, events, and programs better for families and their children and all involved, grounded in research and testing.

Intuitive, Structured Authoring Experience for Service Providers

The value of a directory are the listings within it and it's truly a community effort to assemble enough accurate and up-to-date resources in a single place, for it to be useful. For Cambridge, the service providers that work at government agencies and nonprofits are the lifeblood of the directory. Without them, there would be no Find It Cambridge.

The challenge then, is building a system that is easy enough for people (many already pressed for time) to take the time to enter their information into, while structuring the data to be easily searched and filtered on.

Through user research, we mapped the information architecture to the mental models that service providers hold for their events and programs.

Input Fields Grouped by Key Questions

Most service providers thought of their events in terms of what the event is about, how to contact the organizers, who it is for, when it is happening, where it is happening, how much it costs, and if there is any sort of registration required. So we organized fields into working tabs to match: About, Contact, For whom, When, Where, Cost, and Signup.

Autosave and Soft Required Fields

Even with fields grouped by tabs, the form can take some time to complete. That's why we introduced autosave and soft save features. When working on a form, the site automatically saves the current draft every few seconds. Service providers can also save a draft to return to later. Fields that are required for publishing, are optional for a draft.

Draft States to Save Work for Later

Service providers have many responsibilities to juggle. It's important that they can start creating an event or program, save it and return to it later before publishing it.

Drupal has powerful workflow states, which we've put to use to help service providers clearly know the status of their content.

A service provider can either save their content as a draft or publish it immediately. If saved as a draft, a banner appears on the page clearly indicating that the event or program is not yet published.

Screencast of save as a draft workflow.
Authors can save their work as a draft, bypassing required fields until they're ready to publish.

Authors can also create a draft alongside a published version. This allows new versions to be worked on, while maintaining the current page for site visitors.

Screencast of workflow for having a draft while a previous version of a page stays publishe
Authors can have a published version of a page and also have a working draft that eventually becomes the new version.

Help text and character counts for guidance

There are particular ways to write and format content on events and programs to make the most of Find It's features. We provide help text along the way to clue providers in on the best ways to write their content. We also include a character count so providers know if they're staying within the recommended limits for certain text fields.

Bulk Select for Quick Data Entry

Certain fields have many options. In some cases the majority of them apply. For example, many educational events are for all ages up to 18. In that scenario, having a "Select All" option speeds up the data entry process. The Selectize JavaScript library adds elegant toggle and check all options to multivalue fields. We created the CheckboxesJS Drupal project so that other Drupal sites can easily incorporate these features on fields of their choosing.

Conditional Fields to Show Only What is Relevant

Some fields on Event and Programs only need to show under certain conditions. For example, if an event doesn't require registration, then there's no need to worry service providers with a registration link field. Using conditional logic keeps forms simple and streamlined.

Multiple Dates

There was a lot of discussion on whether to support repeating rules or instead allow multiple dates. We decided on multiple dates as experience has shown that even repeating events oftentimes have exceptions (and because the events we import from Cambridge Public Libraries are a list of arbitrary dates rather than a recurring rule, and somehow no one in computer science has created a library to produce a best-effort recurring rule from a list of dates).

Multiple date fields.
Multiple date fields allow for flexibility on events and programs that happen more than once.

Easy but Powerful Search for Residents

Find It search is powered by Apache Solr, a popular open-source enterprise search platform. We use its numerous features to make the search results as relevant as possible for site visitors.  It's an ongoing process of tweaks; here are some of the things we've done so far.

Weighted Fields for Relevance

On content with lots of data like the events and programs of Find It, certain fields carry more importance than others. The title of an event, for example, is one of the most important. The transporation notes, on the other hand, carries less significance in search queries. When someone types the keyword "music lesson", an event with music lesson in the title or summary shows up before a program for English lessons.

Synonym Matching

When someone searches "childcare" but a program uses "child care", the search engine should know these are equivalent. The same is true for "STEM" and "science education."

Find It supports synonyms. The site manager can define synonyms so that when site visitors search for a certain term, results with matching synonyms show up as well.

Key Information in Search Results

We used the results of our user research to show the critical information people need to pin point the right opportunities: title, neighborhood, and a short summary.

Filters for Sophisticated Queries

Filters help users narrow a search query down to specific criteria. In our testing, we found that age and neighborhood were most important, especially for low-income caregivers. For those of us that rely on public transportation, events and programs need to be nearby. We placed these filters accordingly towards the top of the page.

Naming conventions in Cambridge are unique, which is true for other cities too. Residents might not know the official name of their neighborhood or live at the border between two. We've included a labeled, clickable map to help users choose the right neighborhood. We built this so that other Find It platforms can upload their own SVG map to show their neighborhood.

Informative Opportunity Pages

Find It comes out of the box with four different types of opportunities: Events, Places, Organizations and Programs.

Organization

The organization serves as the foundation for opportunities posted on a Find It page. Every event and program posted to Find It, belongs to an organization. This helps an organization's page serve as a mini-website. When an event or program is published, it automatically shows up on its organization page.

Organizations can also have "child" organizations, which is helpful for larger groups that might have distinct sub-committees or departments that have sub-departments.

Related programs field.
An organization can have a parent - child relationship.

Event

An event is an opportunity with a clear start and end date. When an event is published it shows up on the Homepage, Events page, Search page and on the organization's page.

Visitors can sort opportunities by start date to find upcoming events.

Find It event page.
An event's multiple dates is converted into human friendly language.

Program

A program is similar to an event. In fact, most fields are shared between the two. A program though, implies more longevity and commitment than an event. Rather than requiring a specific date or dates, a program can simply be "ongoing." There is the option to include specific dates though.

Find It program page.

Place

In the first version of Find It Cambridge, a new opportunity surfaced that didn't quite fit into the event, program, or organization categories. Parks, neighborhood pools, and other destinations were a good fit for Find It's library of opportunities. They have open hours, but many of the event fields were irrelevant. The same went for Programs. In fact, sometimes these places have events or programs happening at them.

These are community-minded destinations people can go to. In other words, places.

Find It place page.

Bring Find It to Your City!

Find It is helping Cambridge residents connect with activities and services to improve their lives. We would love to help do the same for other cities, counties, and other communities. The platform is open-source and flexible so that communities can customize it to their needs.

Whether you are city IT staff, a developer that works with cities, or are a resident that could use a Find It in your community, we'd love to talk.

 

Agaric Newsletter image.

Agaric is sending out our first Newsletter since we formed 15+ years ago! Get on the list to receive our missives in the future. 

 

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(&amp;$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']-&gt;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' =&gt; $variables['name'], '!datetime' =&gt; $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?

Screenshot from an Android phone, with a picture of a store window sign "Wirth Co-op Grocery" and the line "Yelpers report this location has closed"

Sign up if you want to know when Mauricio and Agaric give a migration training:

A long, mobile version of the CRLA website's financials page.

Custom Trainings

We can modify any of the above courses to best suit your needs! We are also capable of teaching about many other aspects of Drupal. Look here to get a better idea of our teaching experience and expertise and how we can craft custom trainings for you and your team.

Why Agaric

Clients and colleagues know Agaric developers for taking on the hard tasks when we collaborate on larger teams. We combine this expertise with the desire to raise people up. From our first projects fifteen years ago, our goal has been to make our clients need us as little as possible, to put as much power as possible in our client's hands. That is why we started using content management systems in the first place, and it is a tradition we uphold through developing with free/libre open source software, through writing documentation and blog posts, and above all through providing trainings.

Agaric is active in the Drupal community at-large and has presented at various Drupal Camps. We have also taken initiative in organizing Global Training Days in Nicaragua since 2013.