Archivist

Archivist is a straightforward blogging utility for generating article content at compile time from version-controlled article and image files. It is built to be used in conjunction with the Arcdown plaintext article parser library.

Archivist is inspired by the general approach of Cẩm Huỳnh's great Nabo library with some key differences:

  • Archivist articles are formatted in Arcdown format by default, allowing for more robust articles and article features.

  • Archivist allows articles to be organized into nested topic directories for better organization. Topic directory and sub-directory naming will be translated into a hierarchical system-wide topic and sub-topic structure.

  • Archivist currently doesn't parse article content as markdown, but will add optional content parsing in future versions (like 0.3.x).

  • Archivist adds default attributes for author names and email addresses, as well as sorting content by author.

  • Archivist exposes its article sorting mechanism as an anonymous function, allowing users to implement custom article-sorting strategies at compile-time.

  • Archivist allows you to set a created_at and published_at timestamps to give you greater control over content and how it's used.

  • Archivist allows you to tag your articles however you'd like, and provides functions for sorting and collecting all tags used across your archive.

  • Archivist generates lists of tags, topics, and authors at compile-time, giving you more flexibility in your content's front-end presentation without having to perform additional parsing at runtime.

Installation

The package can be installed by adding archivist to your list of dependencies in mix.exs:

def deps do
  [
    {:archivist, "~> 0.2"}
  ]
end

Usage

The heart of Archivist is the Archive module, which acts as a repository for exposing query functions for articles, slugs, topics, etc. You can create an Archive out of any Elixir module by using Archivist.Archive like this:

defmodule MyApp.Archive
  use Archivist.Archive
end

# the alias is just a nicety here and isn't required by any means
alias MyApp.Archive

Archive.articles()
Archive.topics()
Archive.tags()
Archive.slugs()
Archive.authors()

Archivist version 0.2.x expects you to create your article content directory at priv/archive/articles at the root of your elixir library, like this:

priv/archive/articles/journey_to_the_center_of_the_earth.ad

If you'd like to customize any of your archive's behavior, you can define any of the following options when it is used in the target archive directory. The values shown are the defaults:

defmodule MyApp.Archive
  use Archivist.Archive
    archive_dir: "priv/archive",
    content_dir: "articles",
    content_pattern: "**/*.ad",
    image_dir: "images",
    image_pattern: "**/*.{jpg,gif,png}",
    article_sorter: &(Map.get(&1, :published_at) >= Map.get(&2, :published_at))
end

Archivist will read any files with the .ad extension in your content directory or in any of its subdirectories, and parse the content of those files with the parser you've selected (Arcdown by default)

If you'd like to store your archive somewhere besides priv/archive you can assign a custom path to your archive like this:

defmodule MyApp.Archive
  use Archivist.Archive, archive_dir: "assets/images",
end

Usage notes for Version 0.1.x

Archivist version 0.1.x expects you to create your article content directory at priv/articles at the root of your elixir library, like this:

priv/articles/journey_to_the_center_of_the_earth.ad

The following options are availble in Version 0.1.x. Values shown are defaults:

defmodule MyApp.Archive
  use Archivist.Archive
    content_dir: "priv/articles",
    content_pattern: "**/*.ad",
    image_dir: "priv/images",
    image_pattern: "**/*.{jpg,gif,png}",
    article_sorter: &(Map.get(&1, :published_at) >= Map.get(&2, :published_at))

Arcdown

Arcdown supports the following features for articles:

  • Article Content
  • Article Summary
  • Topics
  • Sub-Topics
  • Tags
  • Published Datetime
  • Creation Datetime
  • Author Name
  • Author Email
  • Article Slug

Here is an example article written in Arcdown (.ad) format:

The Day the Earth Stood Still <the-day-the-earth-stood-still>
by Julian Blaustein <julian@blaustein.com>

Filed under: Films > Sci-Fi > Classic

Created @ 10:24pm on 1/20/2019
Published @ 10:20pm on 1/20/2019

* Sci-Fi
* Horror
* Thrillers
* Aliens

Summary:
A sci-fi classic about a flying saucer landing in Washington, D.C.

---

The Day the Earth Stood Still (a.k.a. Farewell to the Master and Journey to the
World) is a 1951 American black-and-white science fiction film from 20th Century
Fox, produced by Julian Blaustein and directed by Robert Wise.

0.1.x versions of Archivist will parse and return article content as Archivist.Article structs. The parsing output of the above article example would look like this:

%Archivist.Article{
  author: "Julian Blaustein",
  content: "The Day the Earth Stood Still (a.k.a. Farewell to the Master and Journey to the\nWorld) is a 1951 American black-and-white science fiction film from 20th Century\nFox, produced by Julian Blaustein and directed by Robert Wise.\n",
  created_at: #DateTime<2019-01-20 22:24:00Z>,
  email: "julian@blaustein.com",
  published_at: #DateTime<2019-04-02 04:30:00Z>,
  slug: "the-day-the-earth-stood-still",
  summary: "A sci-fi classic about a flying saucer landing in Washington, D.C.",
  tags: [:sci_fi, :horror, :thrillers, :aliens],
  title: "The Day the Earth Stood Still",
  topics: ["Films", "Sci-Fi", "Classic"]
}

Development Notes

A quick review of the Archivist.Archive implementation would reveal additional options that aren't otherwise mentioned in this README:

defmodule MyApp.Archive
  use Archivist.Archive
    content_parser: Earmark,
    article_parser: Arcdown,
    application: nil
end

These options are currently placeholders for future functionality but do not serve any purpose to the user for the time being. Some notes on forthcoming features:

  • While Earmark is included with Archivist, functionality for parsing content as Earmark has not yet been added. Future versions (like 0.3.x) will add something like a parsed_content attribute to the parsed articles flag, which will contain content parsed as Earmark. Setting this value to nil will cause the article parser not to parse the content at compile-time.

  • The intent of the application flag is to be able to define an OTP app as the target for the archive, allowing for the archived data to be called from a besides the one in which Archivist.Archive is used. Please note that this functionality is currently not working and should not be used until further notice in this README.

  • Also note that that swapping out the content and article parsers with different modules currently is not supported. ContentParser and ArticleParser behaviors will be implemented in future versions (likely 0.3.x) and will support implementing custom parsers for these elements.

Please find additional information about known issues and planned features for Archivist in the issues tracker.

Todo

Issues and Todo enhancements are managed at the official Archivist issues tracker on GitHub.

Availability

Source code is available at the official Archivist repository on the FunctionHaus GitHub Organization

License

Archivist source code is released under Apache 2 License. Check LICENSE file for more information.

© 2017 FunctionHaus, LLC