Weave Software

Weave is a static website builder created in Swift. The the site text content is written in Markdown and uses Ink to convert the source texts into html. The Grovelife website is assembled by Weave. (See also Grovelife website refresh)

The resources that are used to make a website:

  • The Weave static website builder software
  • In a source directory
    • Source texts are converted by Ink into html code for use in structured html files.
    • Templates for html:
      • the top-level html documents ("templates")
      • fragments of document content (in markdown, called "inserts")
  • In the site directory
    • Images and other linked media files
    • also used by the grovelife site
      • CSS file
      • javascript utility file

How to use


Each source text file is converted into a page on the website. It may be linked by name from other pages. It is somewhat similar to a wiki although the format is Markdown.

  • Linking between pages on the site uses a modified form of Markdown reference links. Note that:
    • A normal Markdown reference link is of the form
      • [text of the link][refName].
    • It normally expects a line elsewhere in the same source document to have the refName and the associated link.
    • Conveniently if that link is missing, the unmodified refName text will remain in the URL position.
  • To link between pages on the site:
    • put the name of the target page in for the refName with a : (a colon) in front of it
      • this page name is the name of the source text file
      • only the name - omit path and file extender
      • e.g. [text of the link][:targetPageName]
    • note: don't put a matching ref line in the document
  • In the case a .pdf file is to be linked, the form is slightly different
    • put the name of the .pdf file in for the refName with a ! in front of it (no file extender)
      • e.g. [text of the link][!targetPdfName]
    • note again, don't put a matching ref line in the document
  • Images use the standard markdown link format, however put in (only) the name of the image without path or extender.

Inserts, Previews and Sub-Pages

Template and insert files are text files with the text "_template" or "-insert" in the name. A template is expected to already be in html; an insert is to be markdown which will be converted into html. A web page is constructed from these components starting from a top-level template. (The default template is named "base_template"). This template is to have one or more insert sections of the form {{insert_name}}.

  • static inserts come from insert template files
  • certain dynamic inserts are produced by the Weave software
  • source pages can supply inserts in section structures

Source text files can produce content other than the main section content. It does this by marking sections in the source content

  • a preview from the main content of a page.
    • It is to be marked with a "/preview" line. What is above this line will be available for other pages to use as an insert.
    • if nothing is on the line after the preview marker then
      • In the original page source, the /preview line will be removed and replaced with a short horizontal rule.
    • if "-exclude" follows the marker then
      • Only the material after the marker will be put in the main content of the page. This probably requires duplicating some portion of the preview text, but it gives more control of where the preview break occurs.
    • The preview can be inserted into other pages with a line entry of the form {(preview:xxx)} where xxx is the page name.
  • inserts and side column content
    • these are marked with either /annex-export or /annex-local
    • The name for the content follows on the same line. (No whitespace.) It will be saved for use as an insert if it has a name.
    • -export produces inserts that may be used by other pages.
    • -local produces inserts that may be used by the source page or its sub-pages
    • These items are removed from the main content source. They should all be at the end of the source text.
  • inserts
    • Inserts are supplied also out of the metadata of the page.
    • Inserts may be used in a template or content section with text in the form of {{insert_name}}.
  • side column content
    • This is obtained from local and external inserts.
    • Any local insert item with side in the name will be added to the side column
    • External inserts to be added to the side may be listed by name in a metadata side_items item. Multiples may be listed if they are comma-separated
    • There are two cases where a navigation insert is created and inserted automatically
      • for all sub-pages of a page
      • for all blog preview aggregation pages
    • Somewhat similarly, if a side item is exported from a page group it will automatically show up in all others of that group if there is no metadata side_items item.
  • additional html pages as sub-pages of a page.
    • These are marked with a /newpage Sub-Page-Title line
      • The Sub Page Title text can have spaces in it
    • In the original/first page, the content will be only up to the first /newpage
      • There is one special case: If there is no content before the first /newpage, then the main page content starts after the /newpage. This supports custom names for the main page in the side navigation insert.
    • sourcePageName_SubPageTitle   will be the form of the name of sub-pages after the first page.
    • Main Page Title - Sub Page Title   will be the form of the page & sub-page title
    • If there is nothing on the line to the right of the /newpage, the sub-page will be given a numbered name and title
    • The sub-pages will have content between the /newpage lines up to the end of the source text

The content of other pages in the built website is accessed either by a page link or by inserting a page preview

Using Metadata

The website source content files are expected to have a metadata section at the top in the form:

label: value
another_label: another value

Main markdown content text...

The Weave software supplies some hard-coded default metadata items. The metadata from the top of the page source file is added to this (replacing default values where name matching).

There are a few recommended page metadata items.

  • title : The title for the page. Missing this it will use the file name.
  • date : The posting date for the page, indicated at the bottom.
    • Missing this, it will use the file create date.
    • It is important for dating blog entries.
    • If the value is blank, then the create date won't be put on the page. This feature would be used for top-level pages where the post date is not relevant. The date can be recorded in the source file, but call it "hide_date" (for example) instead.
  • group : The top-level group the page is assigned to. This associates it to a top-level navigation group.
    • Missing this, it will be assumed to be in the "blog" group (but only for navigation button handling; it won't get added to the blog).
  • blog : Which of multiple blogs the page is in.
    • Existing and not specified otherwise, the page will be assumed to be in the blog group (for navigation handling)
    • Existing but having blank content, it is assumed to be "blog: blog".
    • Existing and matching content to the page name, it will be the top-level blog page

Other items:

  • update : A content update date, indicated at the bottom of the page.
    • Missing this, it will use the file modify date.
    • If the value for the entry is intentionally blank, then the update date won't be documented on the page.
  • out_name : replaces the name taken from the name of the source file, to be used for the name of the output .html file
  • path : replaces the default relative path to where the .html file will be written
  • tags : words (comma separated) that indicates topics the page is associated with
  • template : replaces the default page template
  • side_items : a comma-separated list of names of inserts for the side column, taken from the common (external) insert collection
  • episodic : Required to indicate the top-level linking page of a blog group. The argument is the name of the blog group name. The name of the page should be the same name.

Notes in pages

Footnotes are common in documents, but are difficult for the reader to navigate when they are far apart on the page. Instead Weave supports hidden notes in the main content. These notes are markdown like the rest of the source file text.

This depends on a javascript toggleNote function to hide and unhide notes when a button inline in the text is clicked. Weave creates the button html and it inlines the notes. The .css file is to hide the notes by default. The buttons use a .btn class (for formatting), and the notes used a .note class (which sets them to hidden).

Write notes anywhere in the source page (but usually at the bottom). They are to be marked with a line before the note text of the form [note id="uniqueIdName"]. After the text of the note can be another note identifier for another note. After the last note, there needs to be at least a [note] end marker. All these will be removed out of the page content by Weave.

The uniqueIdName can be any identifying text and should not have embedded whitespace.

In the text where a note button is desired, add [show id="uniqueIdName"] where uniqueIdName matches to the desired note . Weave will insert the note content into the page text after the paragraph containing the note button. (That is, after the next html </p> or </ul>characters. The text will be hidden by the css.)

Notes and tips:

  • This note removal and insertion is done after the source has been converted to html.
  • If a trailing [note] is not put after the last note, unexpected html will result (because the last note will consume to the end and remove some div closing tags).
  • Note that if a main text content line has two or more spaces at the end, Ink will put a <br> at the end instead of a </p>. This would cause unexpected note placements. Remove the extra spaces.
  • The show/hide buttons for notes are removed from preview inserts.

Starting a website

  • Develop a design language for the website
  • Develop how the website will built. This means a basic .html mockup and the .css for it.
  • Convert the mockup into a template
    • The template will need to be named "base_template.txt" - this is from the defaults at the top of the Weave main.swift file. (But this default can be replaced per-page via the metadata.)
    • There is a general concept of a set of top-level pages associated with groups of content. For instance the main landing page might be in the "home" group, the main blog page and blog items might be in the "blog" group. This idea is supported for top-level navigation bar highlighting.
      • The non-highlighted menu items should have a css class name of "xxx_group", as for instance "home_group".
      • When the page is assembled, the text of the page's associated group will be substituted with "here".
      • No class is required to exist in the .css for the "xxx_group" names, but a "here" class styling should exist to highlight the group that was selected.
    • The template will need an insert placeholder for the page's content. This is to be {{main_content}} in the template where the content is to be inserted.
    • For other insert items in the template, when a matching metadata name is found, the insert will be replaced with the metadata value.
      • again these are in the form {{some_item}}
      • If matching data is not found, the braces will be removed from around the insert text.
    • The template can have an insert placeholder for side-bar content for the page. This is to be {{side_content}} in the template where the content is to be inserted.
      • Selection of the side content comes from entries in the metadata for the page.
      • It will first look for an entry named "side_items" in the metadata of the page.
      • Failing this, it will look for a metadata item called "xxx_sideDefault", where the xxx is the name of the top-level group. (This might be supplied as a global metadata item.)
      • The data from this metadata will be used as the name of an insert to be substituted for the insert placeholder. Any groups without either of these defaults will replace the insert with an empty string.
  • Make content source pages for at least the top-level groups.
  • Special pages
    • A blog source page will be needed for each blog group. Since multiple blog groups are supported, each will need a page which triggers generation of the blog linking pages. The page requires an "episodic" item in its metadata. The content section of the page will be automatically replaced with the blog previews, and multiple (by year) pages will be generated to contain all the content of that blog.
    • A topics page will be needed to trigger generation of the page_topics page. (It depends on metadata in "tags".) It should have a main {{topics_links}} entry, and {{topics_alphabetical}} & {{topics_byQuantity}} entries for side content.
  • Create additional content. Blog items will be automatically linked into the blog lists and previews. Other items will need to be linked manually from other pages.

Additional tips

  • The Ink Markdown converter seems to expect that all html tags are closed. If not, it behaves strangely, producing unexpected conversion results (even with empty tags). It seems to be satisfied with putting a closing slash in the tag: like <hr /> . Browsers are OK with that too.
  • Two spaces at the end of a sentence in Markdown produces an HTML break rather than a paragraph (even though this is not visible). This produces unexpected results from Ink with mis-interpretatation of following lines until there is a paragraph close. Remove the spaces unless specifically desired.
  • Page preview inserts are disallowed to be included in blog posting pages or pages that divide into sub-pages. These are essentially expected to have their own content.