Ricardo's Blog

by Ricardo Morin

Venezuelan Red List of Ecosystems (Libro Rojo de los Ecosistemas Terrestres de Venezuela)

New Project Results

Back in September, I got involved in a new project with the Provita Non-Government Organization (NGO) to publish the content of the Venezuelan Red List of Ecosystems (Libro Rojo de los Ecosistemas de Venezuela) on the web.

Today, after a few months of teamwork, I am excited to share the results:

The project sources can be found here.

I would like to thank the Provita team for giving me this opportunity. I would also like to thank Marlene Alvarado for contributing the graphic design of the site.

Tools and frameworks

I ended up using exactly the tools and frameworks that I described in my previous post, with the small addition of a few helper libraries and Vue components (listed at the bottom of the post).

Tool Purpose
Vue Base development framework, components, HTML templating and Javascript
Gridsome Content transformation, feed to Vue templates and static site pre-rendering
Leaflet/vue2‑leaflet Interactive mapping
Bulma/Buefy CSS, styling, look and feel
Netlify Hosting
Netlify CMS Content Management

Site organization

We organized the site to make it easy to browse, by grouping related content under three menu groups in the navigation bar: Vegetation, Methods, and Risk of Collapse, as shown on the diagram below. The circled numbers map to the book chapters that contain the source content.

The source data comes from the original 325 page PDF document (63 MB). The text was copied/pasted into markdown files, with structured fields in yaml front matter. Simple tables were re-created using markdown and complex tables were re-created using HTML embedded in the markdown. In addition, the original images were retrieved by Provita from their archive storage.

Content organization

The content of the site is organized in page bundles. A bundle is a directory which contains one or more markdown files (.md) and a collection of media files (.jpg, .png, .svg) referenced in the markdown.

Bundles are laid out in the directory structure shown below, for easy access and maintenance. Each leaf node corresponds with a content bundle.

We use the @gridsome/source-filesystem plug-in which, upon site build, transforms the content files into GraphQL entities that are available for use in Vue templates, pages, and components.

Let’s walk through an example using one of the case bundles in a “collection” of cases. The subdirectory content/cases/c1 contains a single markdown file (content.md) and a number of .jpg files referenced in the content for the page /casos/c1.

The Gridsome configuration file (gridsome.config.js) includes the following code which instructs Gridsome to take the content.md files, transform them into GraphQL objects, and associate them to the CaseCard.vue template using the url path which includes the case field as “key”:

{
  use: '@gridsome/source-filesystem',
  options: {
    path: 'content/cases/**/content.md',
    typeName: 'CaseCard',

    ...

  }
}

...

templates: {
  ...

  CaseCard: '/casos/:case'

  ...
}

The template CaseCard.vue is then used to build the pages based on the field case (case identifier). In the CaseCard.vue template we use a GraphQL page query to retrieve the data associated with the corresponding case, as follows:

<page-query>
  query CaseCard ($path: String!) {
    caseCard: caseCard (path: $path) {
      title
      authors
      citationPre
      citationPost
      content
      cardimage
      ...
    }
  }
</page-query>

The data is then available for use in the CaseCard.vue template (e.g., $page.caseCard.title) for all cases in a “collection.”

For individual pages, i.e., pages that are not part of a “collection,” such as the About page or the Contact page, the corresponding .vue pages simply issue a GraphQL query using a unique Id known to the page (e.g, the About page uses the GraphQL HomeData object with an Id of “home”).

Vue Components

I developed a number of Vue components to maximize reuse, eliminate redundancies and ensure consistency:

  • PageBanner - Lays out the page hero banners in a consistent way throughout the site.

      

  • BannerInfo - Displays the banner image caption information icon and the correspoding dropdown content.

      

  • InteractiveMap - Displays a Leaflet map and its associated legend block.

      

  • TextWithRefsAndPhotos - Post-process markdown output to inject dropdown references, inline images, and image modals.

      

  • References - Displays list of references associated with the page.

      

  • SideBar - Provides the open/close sidebar functionality used to navigate collections such as Lansdcape Units, Risk Cards and Case Studies.

      

  • CollapsibleList - Lays out hierarchical navigation lists that are placed inside of the sidebars with the capability of expanding/collapsing child items.

      

Third Party Components

In addition to the base frameworks and tools, I incorporated a number of 3rd party components that provide useful functionality saving both effort and time:

Component Purpose
Axios HTTP client used to access remote data (e.g., map geojson files)
Clipboard Used to copy content to the clipboard (e.g., citations)
v‑runtime‑template Adds the ability to use Vue components in a template generated at run time
vue‑backtotop Sticky button used to scroll to the top of the page
vue‑compare‑image Used to compare two images using a slider; note: I contributed a Pull Request to this component to add image labels
vue‑social‑sharing Used to share links on Twitter and Facebook

In future posts I will be discussing a variety of topics, including: CMS configuration, Netlify deployment, lessons learned, pros/cons of the frameworks chosen, and improvement opportunities.

For now, that’s all folks!

Stay home, stay healthy!

comments powered by Disqus