A near-empty default.haxproj
was created during project creation. This plain-text file exists to contain any number of (fairly trivial) "directives" — lean-yet-expressive statements that may: define reusable micro-contents, fine-tune the overall processing flow, associate certain content pages with one another, or compose and direct custom rendering logic.
(Note that you can combine multiple *.haxproj files — eg. if they grow too big to grasp at once, or for more advanced purposes such as temporary overriding of some directives or separately co-existing "named setups" in a single project.)
Here's what they look like:
|T|greeting: Hello stranger! |C|_hax_domainname: www.haxtatic.foo
|T|
, |B|
, |X|
, |P|
, or |C|
, and spans all subsequent lines until the one that begins the next directive. Best practice (for readability and avoiding subtle pitfalls) is to indent all subsequent lines "belonging" to each directive, but this isn't strictly required. Everything before the first directive is ignored, everything after necessarily belongs to some directive or other.
Directives of type |B| and |C| allow specifying of local paths. These are typically considered relative to the project's build directory and in any event, nowhere are paths pointing outside the project directory supported. HaXtatic does attempt to sanitize those and then interpret them as relative to the currently supposed context.
|T|AuthBlurb: The author is a serial enthusiast
role-playing <a>on XingedIn</a>.
{T|AuthBlurb|}
Just as |T| directives consist of a name connected via a :
to their value, so each and every |B| directive defines a Blok (a section-of-related-pages, or indeed a simple "poor-man's blog-of-sorts") by connecting via a :
that Blok's name to its properties — eg. here's how this site's current Basics section (also just a "Blok") is (approximately, the original includes haXtags) defined:
|B|basics: title="Basics", atomFile = "-xml/basics.atom", blokIndexPageFile="basics/index.html", inSitemap = True, desc=> <p>This material may appear "unduly exhaustive" at first glance, but this is all blatantly-simple-stuff and mostly just spelled out in (almost) every last minor detail for completeness and future reference.</p> <p>Notably no article on <b>"how to author pages"</b>. That's because there's nothing to it once a quick note is made of <a href="../basics/projdir.html">where to place them</a>, <a href="../basics/tmplsnip.html">which outer-template is applied during processing & how</a>, as well as the diverse range of <a href="../tags/index.html">haXtags</a> that any page (indeed any user-authored/-customized file in a project) may embed and combine in any manner.</p>
Stringent syntactic rules apply here! The properties in detail:
title
and desc
— self-explanatory, and used (for one) in these associated auto-generated
files, if any:atomFile
and blokIndexPageFile
both describe a site-root-relative (aka. build-directory-relative) file path and if empty, these files will not be generated.inSitemap
includes or excludes all pages associated with this Blok in/from the generated sitemap.xml (if any)The values set for the above properties can be output anywhere via B-tags — so in essence each |B| directive automatically defines 5 uniquely distinct B-tags.
Just as each |T| directive practically defines a uniquely distinct T-tag that can be embedded many times anywhere (to effect in-place text substitution), so each and every |X| directive in essence defines a uniquely distinct X-tag that can be embedded many times anywhere (to effect in-place output rendering by some custom logic).
That is to say: with |X|x-renderer-type:mytagname: ..
we declare that {X|mytagname: ..|}
encountered anywhere will during processing invoke the X-renderer x-renderer-type with the defined properties in effect.
So every |X| directive associates with a chosen custom (X-)tag name: both a specified X-renderer type to invoke for output rendering (in-place of every X-tag encountered with that given name), and that X-renderer's properties effective while it produces output.
For example, this site declares (among others) these two |X| directives in order to automatically generate on every page (the shaded box near the top to the right) a listing of "Jump To" shortcuts for every chapter heading on that page:
|X|hax.miniTag:h:h2: attr=[("id","{:content:}")] |X|hax.htmlAnchors:doxpagetoc:h2: considerEmpty = 1, outputIfEmpty = "<style type='text/css'>.hd-toc { display: none; }</style>", xmlEscapeHref = False
No particularly substantial extra effort here for all the individual content pages: these simply contain their chapter headings not as plain <h2>
HTML tags but as {X|h: Chapter Heading Here|}
X-tags instead (2 quick "find&replace-in-folders" commands in any minimally capable text editor if this change is introduced late). Meanwhile just the default.haxtmpl.html employs a single {X|doxpagetoc:li: attr = [] |}
X-tag to dynamically produce these desired, page-content-specific <li><a href="#...
outputs in all generated pages.
what becomes immediately apparent from just this example:
hax.miniTag
and hax.htmlAnchors
) :
and a custom (X-)tag name (here h
and doxpagetoc
) and another :
{X|
tag embedded anywhere begins with the very custom tag name from 2. (again, here h
and doxpagetoc
) pointing to the associated |X| directive, followed by a :
and then possibly some further individually-varying X-renderer-specific per-instance settings notation (aka. tag params), if any.:h2:
and :li:
above) andname=value, ..
named properties, to which these stringent syntactic rules strictly apply.
Create "micro-content records" with |P| directives. All such "posts" are categorized first into "feed names" (or think arbitrary "primary category", really) and a further sub-level of
|P|quotes: dt = "2016-01-23", cat="Programming", title="Brian Beckman", link="http://youtu.be/ZhuHCtR3xq8?t=1003", more=[], content=> As software gets ever more complicated, we need better control over the complexity. [...] <i>The</i> way to control complexity is compositionality. |P|quotes: dt = "2016-03-21", cat="Programming", title="John Carmack", link="http://number-none.com/blow/john_carmack_on_inlined_code.html", more=[ ("customfield1","data value 1"), ("customfield2","dat data value 2"), ("customfieldX","funky dis") ], content=> I have gotten much more bullish about pure functional programming.
Stringent syntactic rules apply here! The property names should be self-explanatory, except more
(normally not needed and then best kept []
empty — when such custom "record data" fields become a serious consideration, check out the default.haxproj for this very site for usage). The above example constitutes:
quotes
Programming
.Such "feeds" can be output as *.atom XML files (just add a |C|_hax_relpath_postatoms directive) but other than that no separate pages or other files will be auto-generated from them. To embed such micro-contents in the project's generated output pages in versatile ways (without coding up a custom X-renderer from scratch), use the "feed"-related iterators of the built-in hax.iterator X-renderer (those, incidentally, treat |P| "feeds" and Bloks as (for their purposes) functionally equivalent types of content sources, allowing for some neat mixing-and-mashing).
All quite unnecessary at first, and only promising some relief for increasingly extensive projects on the verge of becoming unwieldy.
For processing source directories, 2 directives are parsed if present: |C|process:static:
(raw files to be batch-copied unprocessed) and |C|process:pages:
(dynamically processed files to be templated-and-generated). Examples:
|C|process:static: skip=["*_thumb.jpg"], force=[], dirs=["static1","static2","static3"] |C|process:pages: skip=[], force=["*"], dirs=[]
Implicit factory defaults:
|C|process:static: skip=[], force=[], dirs=["static"] |C|process:pages: skip=[], force=[], dirs=["pages"]
For any such |C|process:
directive:
dirs
to specify the list of names (not patterns or paths) of all direct sub-directories (situated inside the project directory) to source contents from. If empty []
, defaults to pages for |C|process:pages:
and to static for |C|process:static:
.skip
to specify a list of "simpleton file name (not path) patterns" designating which files to always-skip during processing, regardless of current file modification timestamps. (A "simpleton" pattern either begins with, or ends with, or both, or is devoid of, or consists entirely of an *
and interprets no other wildcards or wildcard placements.)force
to specify a list of "simpleton file name (not path) patterns" designating which files to always force processing for, regardless of current file modification timestamps.skip = ["*"]
force-skips all except what's forced by force
. If the skip = [ .. ]
list contains a single "*"
among other values, this is interpreted as simply skip = ["*"]
.force = ["*"]
force-processes all except what's excluded by skip
. If the force = [ .. ]
list contains a single "*"
among other values, this is interpreted as simply force = ["*"]
.skip = ["*"]
and force = ["*"]
end up as effectively present in the same directive, both cancel each other and the default combination skip=[], force=[]
is thusly assumed for both.Defines a custom date-time format.
Example:
|C|dtformat:slang: Way back on %Y-%m-%d it was!
Format strings are parsed as documented here.
Choose by example what might be needed from:
|C|_hax_domainname: www.haxtatic.foo |C|_hax_dir_build: généré |C|_hax_dir_deploy: redistribuer |C|_hax_dir_cache: |C|_hax_relpath_postatoms: xml/posts/ |C|_hax_relpath_sitemap: xml/sitemap.xml |C|_hax_htmlequivexts: php,shtml,xhtml |C|_hax_onparseerror: abort |C|process:tags: T,P,C
Implicit factory defaults are:
|C|_hax_domainname: <name-of-project-directory> |C|_hax_dir_build: build |C|_hax_dir_deploy: |C|_hax_dir_cache: _cache_tmp |C|_hax_relpath_postatoms: |C|_hax_relpath_sitemap: sitemap.xml |C|_hax_htmlequivexts: |C|_hax_onparseerror: |C|process:tags: T,P,B,X
To elaborate:
_hax_domainname
is used in sitemap.xml and all generated *.atom XML feed files_hax_relpath_sitemap
— site-root-relative file path to the output sitemap.xml, set to
(no value) to disable generating the sitemap._hax_relpath_postatoms
— generation of *.atom XML files for |P| feeds can be enabled by setting this directive with a site-root-relative (aka build-output-directory-relative) directory path to store them in; by default, such files are not generated_hax_htmlequivexts
— file extensions other than the built-in always-on .html
, .htm
and
(no file extension) can be designated to also be processed via the applicable *.haxtmpl.html template_hax_onparseerror
— if manually set to abort
, all processing will halt upon the first
failure to parse some directive properties or X-tag parameters. By default, parse errors result in the
process continuing but the error details being written out directly in-place into generated output files.process:tags:
— comma-separated list of haXtags to be processed. Removing those that will never be embedded anywhere in the project output may marginally speed up processing (perhaps only noticably-so with many 1000s of processable input files). Also allows enabling the disabled-by-default {C|misc_setting_name|}
C-tag prefix, which simply outputs the
current setting of any (except |C|process:..
& |C|dtformat:..
) named configuration directive. Note:
use of haXtags in this one directive is (other than plain puzzling) probably ill-advised_hax_dir_deploy
sets a secondary build-output directory (name, not path) where by default there is none._hax_dir_build
and _hax_dir_deploy
directory names will each (at runtime) be combined (via -
dash) with the current setup name for the final actual build-output directory name: hence in new projects the implicit-default value for _hax_dir_build
—that is, build
— results in the actual build-output directory name default-build
.