View Source PolyPost

A publishing engine with markdown and code highlighting support.

Features

  • Loads files directly from configured paths
  • Stores content in single process-owned ETS tables
  • Supports markdown with structured metadata in JSON
  • Supports multiple directories with markdown files that can be specified as different resources
  • Supports code highlighting in code blocks using makeup
  • Update content during runtime by calling:

Installation

You can add poly_post to your list of dependencies in mix.exs:

def deps do
  [{:poly_post, "~> 0.1"}]
end

In any of the config/{config,dev,prod,test}.exs files you can configure each resources for your content:

config :poly_post, :resources,
  content: [
    articles: {Article, {:path, "/path/to/my/markdown/*.md")}}
  ]

Basic Usage

Loading and Storing Content

With a file called my_article1.md in the configured directory:

{
  "title": "My Article #1",
  "author": "Me"
}
---
## My Article 1

This is my first article

You can create an Article module to load your content by implementing the PolyPost.Resource.build/3 callback:

defmodule Article do
  @behaviour PolyPost.Resource

  @enforce_keys [:key, :title, :author, :body]
  defstruct [:key, :title, :author, :body]

  # Callbacks

  @impl PolyPost.Resource
  def build(reference, metadata, body) do
    %__MODULE__{
      key: reference,
      title: get_in(metadata, ["title"]),
      author: get_in(metadata, ["author"]),
      body: body
    }
  end
end

The only requirement is that the struct or map MUST contain a key called key that uniquely identifies this content. It MUST be a String.

When I call PolyPost.build_and_store_all!/0, it will:

  1. Load and parse all the markdown files and their metadata
  2. Replace all code blocks with highlighted versions if a highlighter is .
  3. Call Article.build/3 with the reference (filename), metadata and content
  4. Then it stores it in a corresponding PolyPost.Depot process.

Using Makeup to Style Code Blocks

If you wish to use makeup to style your code blocks, you must specify the needed dependencies in your mix.exs file.

For example, if you wanted to highlight Elixir, Erlang and HTML in your project, then I would specify the following:

defp deps do
  [
    {:makeup, "~> 1.1"},
    {:makeup_elixir, ">= 0.0.0"},
    {:makeup_erlang, ">= 0.0.0"},
    {:makeup_html, ">= 0.0.0"}
  ]
end

Then you can use tags in your markdown code blocks like so and it will automatically highlight them:

```elixir
def start_link(arg) do
  GenServer.start_link(__MODULE__, arg, name: __MODULE__)
end
```

Retrieving Content

You can retrieve content using the functions on the PolyPost.Depot module to access the associated ETS table that stores your data:

  1. find/2 - find a specific content by key for the resource
  2. get_all/1 - gets all content for a resource

For example:

PolyPost.Depot.find(:articles, "my_article1.md")
=> %Article{...}

and

PolyPost.Depot.get_all(:articles)
=> [%Article{...}]

Differences from NimblePublisher

This library was heavily inspired by NimblePublisher, but it IS different.

License

This software is licensed under the Apache-2.0 License.