Doing things only to some pages
Soupault is meant to be a website generator for Web 1.0. One of the key freedoms the Web 2.0 approach took away is the freedom to make different pages look different. To live up to the Web 1.0-friendly promise, a tool must make it easy to do again. Soupault includes a number of features to make it easier.
Omitting widget's target from the page
First of all, as already mentioned, if a widget has a target selector, it will only run if it finds an element matching that selector. If there's no element where it could insert its output, it will do nothing. In the functional programming jargon, widgets are “lazily evaluated”.
For example, suppose you have this config for footnotes:
[widgets.footnotes] widget = "footnotes" selector = "div#footnotes" footnote_selector = ".footnote" footnote_link_class = "footnote" back_links = true link_id_prepend = "footnote-" back_link_id_append = "-ref"
If you want footnotes in every page, you can include a <div id="footnotes">
in templates/main.html
and never have to think about it again (fun fact: that div needs not be at the bottom of the page, for a practical joke you can place it at the top
or in the middle).
However, if you want it only in some pages, you can omit that div from the template, and insert it only in pages where you want footnotes.
Limiting widgets to specific pages
Omitting widget's target from a page is not always an option, or at least not the best option. Sometimes the target is too generic and cannot be
omitted. For example, if you want to add a custom CSS style, using a link
tag in the head, you'd have to leave the template to
just <html> </html>
, which is a very bad option for websites with more or less uniform-looking pages, since you'd end up
with a lot of redundant code in the page content files.
This is why soupault has options for explicitly limiting widgets to certain pages or sections (i.e. subdirectories). For example, suppose you have a separate
file with site news in templates/news.html
that you only want to include in the main page of your website (i.e. site/index.html
.
You can do it by adding a page = "index.html"
option to the widget config:
[widgets.site-news] page = "index.html" widget = "include" file = "templates/news.html" selector = "body"
You can also specify more than one page there. For example, this is how you could apply a special CSS style to cv.html
and about.html
:
[widgets.special-style] page = ["cv.html", "about.html"] widget = "insert_html" html = '<link rel="stylesheet" type="text/css" href="/special.css">' selector = "head"
I'm using single quotes for the HTML string here because they allows you to write double quotes inside strings without escaping.
You can also apply a widget to all pages in one or more sections using the section
option. This is how you can do something to all pages in
blog/
:
[widgets.some-widget] section = "blog/" ...
If this is not flexible enough, you can use a regular expression, that option is called regex
. The syntax is mostly Perl-compatible, but
without backtracking support.
You can find a live example in my personal website config.
The page in question, baturin.org/tools/bnfgen/ is a web application for playing with formal grammars,
and it's a 90Kbyte JS file. No other page needs that file, so including it in every page would cause every visitor to download 90K of useless JS.
That's why it's limited only to its own page with a regex option (it could use page
instead, but that website doubles as a test suite
for soupault dev builds, and I needed to use the regex option somewhere).
Excluding pages from widgets
Each of those options has a negative counterpart that allows you to do something to all but some of your pages. Those options care called
exclude_page
, exclude_section
, and exclude_regex
.
This is how you can set a style for every page except your main page:
[widgets.common-style] exclude_page = "index.html" widget = "insert_html" html = '<link rel="stylesheet" type="text/css" href="/common.css">' selector = "head"