Declare a simple structured blog to be published with org-publish.
This package offers an all-Emacs solution to maintaining a web site
(except for uploading via rsync, which defblog triggers through
org-publish).
This file describes defblog version 0.1.0.
Requires Emacs 27.1 or later, specifically for the make-decoded-time
function introduced with that release.
Also requires the anaphora-anywhere library available
here.
To use defblog, you must structure your Org files as follows:
- The
index.orgfile, if it exists, is the front page of the blog. - The other top level
*.orgpages correspond to individual undated pages (i.e., not posts). - Each directory within the source directory which contains a file
category.txtcorresponds to a category of posts. Thecategory.txtfiles will be loaded as Org-mode files, although including first-line Org-magic is optional. - Category directories should not contain an index.org file! An index of posts will be generated, and this file will be ignored.
- Otherwise, each ORG file in a category directory corresponds to a blog post.
So if the source directory is /DIR/TO/SRC, then a possible directory layout is:
/DIR/TO/SRC/
|
+-- index.org Top-level page
|
+-- style.css Style sheet for the generated pages
|
+-- contact.org A page of contact information
|
+-- jokes.org A page of favorite jokes
|
+-- kittens A subdirectory corresponding to a category of
| posts.
|
+-- category.txt Properties of the "kittens" category.
|
+-- adopted.org A post about adopting a kitten
|
+-- vet-jul20.org A post about a trip to the vet
in July 2020.
Required parameters:
-
name, a string used to identify this blog. Thisnameis used byorg-publishto publish this particular blog, and it is also used to name generated storage locations so that they do not conflict with the names used for other blogs. -
source-directory, a string giving the absolute pathname of the source directory of Org- and other files for this site. -
blog-title, a string with the human-oriented name for the web site.
Optional parameters:
-
blog-urlgives the URL for the top of this blog. This value is required for most XML artifacts. -
By default,
defblogwill use a temporary directory named by the system for both the intermediate file areas, and for the directory of final files to be published. However it possible to name specific directories for these uses with thepublished-directoryandgenerated-directoryarguments. -
By default,
defblogwill delete thepublished-directoryandgenerated-directoryafter it finishes. These deletions can be suppressed by passing non-null values to theretain-published-directoryandretain-generated-directoryarguments. -
The
css-style-rel-pathargument specifies the local path from thesource-directoryto the default CSS stylesheet for the blog. -
The
frontpage-css-style-rel-path,page-css-style-rel-path,post-css-style-rel-pathandcategory-index-css-style-rel-patharguments specify local paths from thesource-directoryto the CSS stylesheets for those groups of pages. If not given, these arguments take the value ofcss-style-rel-path. For any of these, a NIL value means there should be no CSS style sheet. -
Org-mode can generate section numbering and a table of contents when converting Org files to HTML. The
frontpage-section-numbers,page-section-numbers,post-section-numbers,category-index-section-numbers,frontpage-table-of-contents,page-table-of-contents,post-table-of-contentsandcategory-index-table-of-contentsarguments control these options for the various classes of document. Their values are checked for anullor non-nullsetting. -
The
post-copy-functionandfront-copy-functionarguments specify how a file in the temporary directories are made from the various source Org files. The default isdefblog/page-copy-verbatim, which simply copies the source file. Other options, and the protocol for writing a custom function, are discussed in the Processing files section below. -
The
generate-xml-sitemap,generate-rssandgenerate-atomarguments indicate whether the published blog should include these XML artifacts.For the RSS and Atom feeds, the
feed-entry-sunsetargument gives the length of time that a post should be included in any XML feed (RSS or Atom). The value may be:- An Emacs Lisp time value (used as-is: the age of a post
calculated via
time-subtract, and compared to this upper bound). - A Lisp list (passed as arguments to
make-decoded-time, whose result is used as a sunset bound as above). - A string (passed to
parse-time-string, and used as an absolute limit of the earliest date included.
For the Atom feed, the
default-author-nameargument gives a value for the default article attribution; this can be overridden on a post-by-post basis with the file properties (below).For the XML sitemap, the
sitemap-default-change-freqandsitemap-default-prioritygive default values for pages which do not set a change frequency or priority in their file properties. By default their values aremonthlyand0.5. Priority values should be between 0.0 and 1.0 (inclusively), 1.0 being the most important. Other valid values for the change frequency arealways,hourly,daily,weekly,yearlyandnever.The RSS and Atom feeds are validated via validator.w3.org/feed. The XML sitemap is validated via xml-sitemaps.com/validate-xml-sitemap.html.
- An Emacs Lisp time value (used as-is: the age of a post
calculated via
-
The
uploadargument specifies whetherdefblogshould upload the website files it produces to a remote server. Its two current valid values arenil, indicating that no upload should occur.:rsync, indicating an upload via thersyncprotocol.
There are four additional options for
rsync:-
The
rsync-rshargument specifies the protocol provided for the--rshoption torsync. If:rsyncis selected, this value is required. -
The
rsync-destargument specifies the remote machine and directory for the file transfer. This value is provided as the final argument to thersynccall. If:rsyncis selected, this value is required. -
The
rsync-delete-excludedargument, if non-null, requests the--delete-excludedswitch forrsync. This argument is optional, and is set totby default. -
The
rsync-optionsargument should be a list of strings passed as additional options torsync. This argument is optional, and is set to("-rLptgoD")by default.
This section presents the Org file properties of pages, posts, and
category specifications that defblog reads and uses.
These properties are meaningful in both page/post files, and in
category.txt files.
TITLEThe title of the page/post, or the name of the category. Note that org-publish will place this title as the headline of the HTML it generates.DESCRIPTIONA short blurb of the contents.CHANGE_FREQA hint about how often a page/post changes, to be included in the XML sitemap. Valid values are discussed at [[https://www.sitemaps.org/protocol.html#changefreqdef]].SITEMAP_PRIORITYA relative assessment of the importance of crawling a page/post, compared to other pages/posts on this site. Should be a floating-point value between 0.0 and 1.0, with 1.0 having the highest priority.
The properties in this section are not meaningful in category.txt
files. Date information about categories is synthesized from the
posts in that category)
DATEThe publication date of the page/post.UPDATEDThe last change of the page/post.AUTHOR_NAMEThe name of the author of the given post/page. When an Atom feed is generated, either this property must be given for every post/page, or a non-null value for the DEFAULT-AUTHOR-NAME parameter must be provided to DEFBLOG.
There are additional page/post file properties applicable only to the
defblog/page-copy-with-substitutions processing function, which are
described below.
defblog transfers Org source files into temporary directories, from
which org-publish converts them into HTML and other files. By
default the files are simply copied, but it is also possible to
transform the file contents based on pragmas in the source.
In addition to the defblog/page-copy-verbatim function for a simple
verbatim copy, the defblog/page-copy-with-substitutions function can
be passed for either or both of the post-copy-function and
front-copy-function keyword arguments to defblog. This processor
also copies most text verbatim, but rewrites certain expressions and
pragmas. Currently there are two substitutions:
-
If a line starts
# RECENT-POST-LINKS
then this line will be replaced with information from recent posts. The substitution is controlled by the following file properties which can vary from file to file:
-
PAGE_SUBST_POSTS_MAXgives the maximum number of posts which will be included. By default this value isnil, signifying no maximum. -
PAGE_SUBST_POSTS_MAX_AGE_DAYS,PAGE_SUBST_POSTS_MAX_AGE_MONTHS, andPAGE_SUBST_POSTS_MAX_AGE_YEARSgive the maximum age of post which should be included. At most one of these properties will be consulted: ifDAYSis given, then it is used; otherwiseMONTHS; and thenYEARS. -
PAGE_SUBST_POSTS_EARLIESTThis property is checked only when thePAGE_SUBST_POSTS_MAX_AGE_*properties are not given, and gives the date of the earliest last-modified post which can appear. The string given for this property is converted to a date withparse-time-string. -
PAGE_SUBST_POSTS_INDENTdescribes the indentation associated with each post reference.-
If this property is a number
n, thennspaces will precede the information printed for each reference. -
If this property is
nil, then no prefix is printed. -
Otherwise, the string given for this property is used.
-
-
PAGE_SUBST_POSTS_NEWLINESIf this property is non-null, then a newline is started after the information printed for each reference. -
PAGE_SUBST_POSTS_FINAL_NEWLINEIf this property is non-null butPAGE_SUBST_POSTS_NEWLINESis null, then a newline will be inserted after the last reference. -
PAGE_SUBST_POSTS_FORMAT_STRINGThis format string describes what should be printed for each reference. In the usual manner for format strings, most characters are echoed verbatim,%%translates to%, and%Lis replaced with the opening of a link to the post.%Zis replaced with the closing of a link to the post.%tis replaced with the title of the post.%Tis replaced with the title of the post, capitalizing the first letter if it is not already capitalized.%dis replaced with the description of the post.%Mis replaced with the full name of the month of the last update to the post.%Dis replaced with the number of the day of month (space-padded) of the last update to the post.%Yis replaced with the year (including century) of the last update to the post.
The default is
"%L%T%Z (%M %D, %Y)". -
PAGE_SUBST_POSTS_NUMBEREDIf this property is non-null, then the references are inserted as a numbered list; otherwise they are inserted as a non-numbered list.
-
-
If a line starts
# CATEGORY-LINKS
then this line will be replaced with several lines of links to category index pages. Right now the substitution produces a non-numbered list; future work will allow controlling the list with file properties, as for the recent posts pragma.
Any function can be provided for the post-copy-function and
front-copy-function keyword arguments so long as they expect four
arguments:
- A string giving the absolute path to the source Org file.
- A string giving the absolute path to the temporary Org file to be generated.
- The property list of the overall site.
- The property list of the post being generated.
More information about the property lists are presently below.
defblog builds several property
lists
describing pages, posts, categories, and the overall site to be
generated.
Each page and post is associated with a property list with these values:
:bareis the name of the Org file for this page/post, without any enclosing directory paths.:pathis the full absolute pathname for this file.:depthis the number of directories enclosing this file relative to the top-level source directory.:titleis theTITLEproperty from the Org source file.:descis theDESCdescription property from the Org source file.:catis the tag for the category of a post, ornilfor a top-level page.:author-nameis theAUTHOR_NAMEproperty of a page/post, or the site default passed todefblog.:dateis theDATEcreation time property of a page/post, ornilif none is given.:updatedis theUPDATEDproperty for the last update time of a page/post, ornilif none is given.:modis the later of the creation time and last update time, ornilif neither are given.:sitemap-priorityis the relative priority of the page for the XML sitefeed.:change-freqis the change frequency of the page for the XML sitefeed.
The file property list hash table maps the symbol whose name is the absolute path for a source file, to the property list for that page/post.
:titleis the human-oriented name for the category.:descriptionis a short text description of the category.:tagis the short tag name, which is also the directory holding the category's files.:src-diris the absolute path of the subdirectory of the source directory for that category.:sitemap-priorityand:change-freqare the XML sitemap properties for the category index page.:post-filesis a list of the bare (without surrounding directories) source file names of the post files in the category.
The category property list hash table maps the symbol whose name is the category tag, to the property list for that category.
:titleis the name of the web site.:descis a short text description of the site.:urlis the URL of the top level of the site.:file-plists-hashis the file property list hash table. Usehash-table-valuesfor just the plists.:cat-plists-hashis the category property list hash table.:sorted-file-plistsis a list of file property lists sorted in descending order of last-modified date.