Pages

This module contains the main functions you need to build a site with Jay.

If you're new to Jay, the guide is the best place to get started!

Pages a

Instructions for building the pages of a website. This includes actual pages such as an 'about' page or blog posts, but also assets like pictures and stylesheets.

bootstrap : Pages [Bootstrap]

Helper for generating a first Jay configuration, if you don't have one yet. At the root of the project directory create a build.roc file, with these contents:

#!/usr/bin/env roc
app [main] { pf: platform "github.com/jwoudenberg/roc-static-site" }

import pf.Pages

main = Pages.bootstrap

Now run the file with ./build.roc. Jay will rewrite the file with an initial configuration based on the source files in the project directory.

collect : List (Pages a) -> Pages a

Combine rules for different types of pages into one value representing the entire site.

Typically sites call this once in the main function.

main = collect [
    Pages.ignore ["README.md"],
    Pages.files ["assets/*"],
]

files : List Str -> Pages type

Takes a list of patterns, and adds all the source files matching one of the patterns to your site as a page.

photos = files ["photos/*.jpg"]

Combine files with other functions for source files requiring processing:

posts =
    files ["posts/*.md"]
    |> from_markdown

Patterns may contain multiple '*' globs matching part of a filename. '**' globs are not supported.

ignore : List Str -> Pages [Ignored]

Similar to files, ignore takes a list of patterns. Jay will ignore source files matching these patterns and not generate output files for them.

main = Pages.collect [
    Pages.files ["assets/*"],
    Pages.ignore ["README.md", ".git"],
]

from_markdown : Pages [Markdown] -> Pages [Html]

Process markdown source files, converting them to HTML files.

posts =
    files ["posts/*.md"]
    |> from_markdown

This function does not generate any html or body tags, only the HTML tags for the markdown formatting in the source files. You can use wrap_html to define a page layout.

Frontmatter

You can optionally add a frontmatter at the start of your markdown files.

{
  title: "A blog post about Roc",
}

The frontmatter needs to be a Roc record. Record fields may contain arbitrary Roc values. Check out the documentation for Raven to see what's supported.

Syntax Highlighting

Jay will add syntax highlighting for fenced code blocks. Jay currently has support for the languages the languages, with more planned. If you need highlight support for a particular language, feel free to create an issue on the Jay Github repo!

Syntax highlighting will generate span elements in the generated code blocks, which you can style using CSS. You can use this example code as a starting point.

Supported languages: Elm, Roc, Rust, Zig, Nix, Ruby, JSON, Haskell

Github-Flavored Markdown

Support for Github-Flavored Markdown extensions is planned, but not currently implemented.

wrap_html : Pages [Html], ( { content : Html, path : Str, meta : {}a } => Html) -> Pages [Html] where a implements Decoding

Wrap additional HTML around each of a set of HTML pages. This function is typically used to create page layouts.

posts =
    files ["posts/*.md"]
    |> from_markdown
    |> wrap_html layout

layout = \{ content, path, meta } ->
    Html.html {} [
        Html.head {} [ Html.title {} [ Html.text meta.title ] ],
        Html.body {} [
            Html.h1 {} [ Html.text meta.title ],
            content,
        ]
    ]

wrap_html passes a record to the layout function with these fields:

list! : Str => List { path : Str, meta : {}a }

Get information about all pages matching a pattern. This is intended to be used in combination with wrap_html or replace_html, for instance to create a navigation element with links to other pages.

See the documentation of wrap_html for an example of how to use this.

replace_html : Pages [Html], Str, ( { content : Html, attrs : {}attrs, path : Str, meta : {}a } => Html) -> Pages [Html]

Replaces matching HTML tags with generated HTML content. This is typically used to create widgets.

Suppose you want to create an index page of your blog, showing all your blog posts. Start by writting a markdown file:

# My Blog

A list of all my previous posts!

<list-of-posts/>

We can use replace_html to replace the custom list-of-posts HTML element with a list of posts. Here's how that would look:

home_page =
    files ["index.md"]
    |> from_markdown
    |> replace_html "list-of-posts" list_of_posts!

list_of_posts! = \_ ->
    posts = list! "posts/*"
    links = List.map posts \post ->
        Html.li {} [
            Html.a
                { href: post.path }
                [Html.text post.meta.title],
        ]
    Html.ul {} links

replace_html passes a record to the widget function with these fields: