AkashaRender includes a "built-in" plugin with custom tags useful for any target use. The AkashaCMS toolchain supports rendering both websites and EPUB's, and could support rendering for other target uses of HTML. The EPUB format includes constraints where, while EPUB3 uses HTML5, a sizeable list of HTML5 features are not allowed. Both the built-in plugin and the akashacms-base
plugin both aspire to provide features useful to everyone, the latter includes those features useful only for websites, whereas the built-in plugin features are useful for everyone.
Installation and Configuration
There's nothing to do, the built-in plugin is, well, built-in to AkashaRender.
Simplification for figure/img
tags
This construct is recommended in the HTML5 world for its microformat goodness
<figure>
<img src="an-image.jpg"/>
<figcaption>Image caption</figcaption>
</figure>
While you can surely write these tags yourself, the <fig-img>
tag offers a simplification.
<fig-img href="an-image.jpg"
class="class-name"
id="id-name"
style="...CSS..."
width="...width..."
template="template-partial.html.ejs">
Optional caption text
</fig-img>
Using the default template (ak_figimg.html.ejs
) the tag converts into the structure shown above. The attributes are interpreted as so:
class
is added as aclass
attribute to the<figure>
id
is added as aid
attribute to the<figure>
style
is added as astyle
attribute to the<figure>
width
is added as awidth
attribute to the<figure>
template
overrides the default template
Create figure/img constructs from images
We have a tag <fig-img>
to aid constructing the combination of a <figure>
containing an <img>
. But after some time of using that tag it seems better to use the <img>
tag, and add attributes to control the construction of the figure/img construct.
To trigger this behavior include the figure
property on the image.
<img id="change1" figure src="img/Human-Skeleton.jpg">
With the figure
property, we replace the <img>
with a <figure>
containing an <img>
.
The recognized attributes are:
id
becomes theid
of the<figure>
class
becomes theclass
of the<figure>
width
becomes thewidth
of the<figure>
style
becomes thestyle
of the<figure>
dest
becomes an<a>
tag surrounding the<img>
within the<figure>
caption
becomes a<figcaption>
tag within the<figure>
This is processed through the ak_figimg.html.ejs
template just as for <fig-img>
.
Resizing images
Sometimes you want to store a full-size image in the documents
directory, but the deployed website will use a reasonable size image for web browsers. For example a marketing department might provide highly detailed product images accompanying a press release, but of course it is useful to keep images to 100-300kb for delivery on a public website.
For this purpose a filter exists to resize images. This feature may be extended in the future to include general image manipulation.
It is triggered by adding a resize-width
property to an <img>
. The value of this property declares the width of the resulting image in pixels. The image height is automatically calculated to maintain the same width/height scale (e.g. a 600x400 image resized to 300 width would be 200 pixels high).
The usage is as follows:
<img id="resizeto150"
src="img/Human-Skeleton.jpg"
resize-width="150"
resize-to="img/Human-Skeleton-150.jpg">
The recognized properties are:
src
The file within the documents or assets directories that is copied into the render outputresize-to
The file name used within the render output directoryresize-width
The resulting image width as discussed above.
In the rendered HTML, if resize-to
is given, the src
attribute of the <img>
will be rewritten to the value of the resize-to
attribute.
The rendered version of this tag will be:
<img id="resizeto150" src="img/Human-Skeleton-150.jpg">
The resize-width
and resize-to
attributes are removed in the final output.
<img id="png2jpg" src="rss_button.png" resize-width="50" resize-to="rss_button.jpg">
In this case the image type in src
differs from resize-to
. In this case an image format conversion is performed.
Stylesheets
The <ak-stylesheets>
tag generates links to CSS stylesheets, as declared in config.js
or in the document metadata.
In config.js
add something like this:
config
.addStylesheet({ href: "/vendor/bootstrap/css/bootstrap.min.css" })
.addStylesheet({ href: "/vendor/bootstrap/css/bootstrap-theme.min.css" })
.addStylesheet({ href: "/vendor/bootswatch-readable/bootstrap.min.css" })
.addStylesheet({ href: "/style.css" });
The options include the href
option shown here, and media
to declare the media type. These correspond to these attributes
<link rel="stylesheet" type="text/css" href="${style.href}" media="${style.media}"/>
In document metadata include this for per-page stylesheets:
---
...
headerStylesheetsAdd:
- href: "/vendor/bootstrap/css/bootstrap.min.css"
- href: "/style-for-this-page.css"
...
---
JavaScript
JavaScript tags can be added either at the top of the page, in the <head>
section, or at the bottom of the page, depending on your preferences. AkashaRender supports declaring the JavaScript files to be put in which section.
Place the <ak-headerJavaScript>
tag where you want header JavaScript to appear, and the <ak-footerJavaScript>
tag where you want the footer JavaScript to appear.
In config.js
add something like this:
config
.addFooterJavaScript({ href: "/vendor/jquery/jquery.min.js" })
.addFooterJavaScript({ href: "/vendor/bootstrap/js/bootstrap.min.js" })
Substitute Header
for Footer
and the JavaScript will appear in the <head>
section.
The object can contain these fields:
lang
(optional) specifies the language of the script, corresponding to thetype=
attributehref
corresponds to thesrc=
attributescript
becomes an in-line JavaScript placed within the<script>..</script>
tag
It is not allowed to have both href
and script
fields.
To specify these on a per-document basis in the metadata:
---
...
headerJavaScriptAddTop:
- href: "/vendor/jquery/jquery.min.js"
- href: "/vendor/bootstrap/js/bootstrap.min.js"
...
---
This specifies JavaScript at the top of the page, use headerJavaScriptAddBottom
for JavaScript at the bottom of the page.
Teaser content
Some writers swear by creating a teaser for every document. The idea is a small bit of text teasing the reader to go ahead and read the whole document.
The <ak-teaser>
tag supports inserting the content of a teaser
metadata object. It uses the ak_teaser.html.ejs
partial to do so.
Embedding code snippets from files in the document directory
Sometimes we want to embed code snippets. While Markdown makes this easy, we could also have code in files and then embed the files. To do that:
<code-embed file-name='path/to/file.ext' lang='lang-code'></code-embed>
The file-name
argument must be either a relative path, or absolute path, within a documents directory. Relative path's are computed relative to the file this is within.
The lang
argument is refers to what language code is to be used with this file. For example css
for a CSS file.
Not shown is the id
argument that creates an id
in the output code.
This element is integrates with the
Highlight.js library and therefore the lang
codes must be from their list of supported programming languages.
The contents of the file must be textual for this to work. That's because the file contents will be inserted into the output wrapped within this structure:
<pre id='id'>
<code class='lang'>
... CONTENTS OF FILE
</code>
</pre>
Clearly for this to work correctly the file must have textual content.
Select N elements from a group
Sometimes you want to randomly select one or more elements from a group of items. Consider:
<select-elements id='advert-group'>
<div><div id='advert1'>... HTML for advert 1</div></div>
<div><div id='advert2'>... HTML for advert 2</div></div>
<div><div id='advert3'>... HTML for advert 3</div></div>
<div><div id='advert4'>... HTML for advert 4</div></div>
</select-elements>
The idea is to support displaying only one of them, selecting at random the child to display.
It selects among the direct children which element or elements to display. The outer element for the child is discarded, and only its contents are displayed in the output HTML. For example the result of the above example might be:
<div id='advert-group'><div id='advert3'>... HTML for advert 3</div></div>
The attributes accepted by select-elements
are:
id
- The ID value to use on the outputted HTML elementclass
- The class value to use on the outputted HTML elementcount
- The number of child elements to display - defaults to 1
Anchor tag cleanups
This feature automagically fixes <a>
tags, referencing a local document, and which lack text or an image. Normally an empty tag would show up as nothing in the web browser. AkashaRender makes it into something useful.
It reads the metadata of the referenced document, and inserts that documents title as the anchor text.
For example the code <a href="/hello-world.html"></a>
might be rewritten to: <a href="/hello-world.html">Hello, world!</a>
. If you're using Markdown the equivalent works: [](/hello-world.html)
because Markdown converts that to a normal <a>
tag.
The URL passed in the href
attribute should of course be the URL of the rendered file. You might have created a file hello-world.html.md
which is then rendered to hello-world.html
. The link of course needs to reference the rendered file even though the metadata is in the source file. AkashaRender figures out which is which under the covers.
Relative local URL's versus absolute local URL's
It is encouraged to write your content using absolute local URL's like:
<a href="/index.html"></a>
<img src="/images/logo.jpg">
<link rel="stylesheet" type="text/css" href="/vendor/bootstrap/css/bootstrap.min.css">
<script src="/vendor/jquery/jquery.min.js">
But for deployment this has a couple issues:
- If the content is to be rendered as an EPUB all URL's must be relative, and therefore we must rewrite the URL's
- If the content is deployed to a subdirectory .. that is, if
config.root_url
is something likehttp://example.com/path/to/subdir/
.. the URL's must be rewritten either to include the subdirectory, or to be relative
For the purpose of deployment to a subdirectory, rewriting the URL's to include the subdirectory made it difficult to preview the site using a local web server. That is, if the above is rewritten to:
<a href="/path/to/subdir/index.html"></a>
<img src="/path/to/subdir/images/logo.jpg">
<link rel="stylesheet" type="text/css" href="/path/to/subdir/vendor/bootstrap/css/bootstrap.min.css">
<script src="/path/to/subdir/vendor/jquery/jquery.min.js">
And then we run a local webserver to preview the rendered site, none of these links will work. The biggest problem is CSS and JavaScript for theming will not load.
Therefore, for most cases, it is desired to use relative links rather than absolute.
<a href="./index.html"></a>
<img src="./images/logo.jpg">
<link rel="stylesheet" type="text/css" href="../vendor/bootstrap/css/bootstrap.min.css">
<script src="../vendor/jquery/jquery.min.js">
For that purpose, by default, the built-in plugin automatically computes a relative path from the source page to the destination local URL.
But this is not desired in all cases. In some cases it is desired to use absolute paths for local URLs. To enable this behavior, use the following in the configuration:
config.prepare();
config.plugin('akashacms-builtin').relativizeHeadLinks = false;
config.plugin('akashacms-builtin').relativizeScriptLinks = false;
config.plugin('akashacms-builtin').relativizeBodyLinks = false;
Because the akashacms-builtin
plugin is installed in config.prepare
, you cannot reference the plugin until after that function is executed. These three options control whether to relativize those types of local URLs.