-
Notifications
You must be signed in to change notification settings - Fork 2
API Documentation
This page contains detailed API reference documentation.
A Spectate project can be configured through the spectate
field in its package.json
. Currently, there are 3 configuration settings for the page UI:
-
USE_NEWS_NAV
: Show a News navbar (a navbar with just the CDS logo) -
USE_EYE_NAV
: Show an Eye navbar (a navbar with the Eye logo and standard links) -
USE_COVER_HED
: Sort of a legacy Spectate feature. Puts the headline on a cover (example.)
Two other configuration keys, IS_EMBED
and DOC_URL
, are explained in the spectate create
and spectate init
sections, respectively.
Arc stories are server-side rendered into an <article>
node that is pushed deep into various Bootstrap grid elements and Arc styling containers. The uppermost structure looks like this:
div#pb-root
section#top
section#main
..
article
..
section#bottom
At runtime, the uppermost container section#main
is replaced with the <article>
node. The structure becomes:
div#pb-root
section#top
article
section#bottom
This almost completely reduces style and layout conflicts that used to result from Spectate projects being stored in deeply nested containers. The hoisting function, hoistArticle()
, is run only when section#main
exists, which is detected using requestAnimationFrame()
.
$ spectate create [template-option]
There is one template option, embed
. All it does is set IS_EMBED
to true in the Spectate config, which prevents article hoisting. Embeds are projects that are not standalone pages, projects that should just be left as embedded HTML in the Arc story (example). When publishing embeds, just copy the HTML build into an HTML block an Arc. The contents of <head>
will get server-side-rendered into a heightless <p>
, and, for some reason, the non-text-element-having <p>
will have ineffectual margins.
Asks for a slug. Verifies it TK.
Asks for a Google Docs link. If the link is valid, sets it to DOC_URL
in the Spectate config.
$ spectate download
Runs /process/download-doc.js
, which lives in your project, with keys stored in the Spectate directory. The script downloads the Google Doc and processes its contents with ArchieML.
The ArchieML output is prettified and written to /data/doc.json
. Sometimes you may want to import variables stored in the Google Doc to the script, but this may be a bad idea if your doc is large because it would be put into the JavaScript build. I basically just have this file to debug formatting errors from the doc download.
The ArchieML output is also stored in the PostHTML config (.posthtmlrc
) as the locals
object for the Expressions plugin. (When changing locals for posthtml-expressions, live reload seems to only invalidate the cache of .posthtmlrc
and not JavaScript configs.)
The PostHTML Expressions plugin isn't meant to be very smart. Consider this code block, which should only render multiple paragraphs if the local text
exists (which is determined by whether the text
variable exists in the Google Doc).
<if condition="typeof text !== 'undefined'">
<each loop="item in text.split('\n')">
<p>{{ item }}</p>
</each>
</if>
The expressions
plugin will throw TypeError: Cannot read property 'split' of undefined
. The if
block only considers whether some HTML should be included, not whether it should be processed, so expressions
will still try to split the undefined value.
To conditionally include a variable based on its existence in the Google Doc, you have to manually add a default value for the download-doc.js
script (see Docs Configuration).
Note that setting the default value of text
to null
in the previous example will still lead to the error TypeError: Cannot read property 'split' of null
for the same reason as above. The default value of a local should be set considering the operations that it must go through (e.g. empty string if splitting, empty array if looping).
<!-- text default was set to '' -->
<if condition="text.length > 0">
<each loop="item in text.split('\n')">
<p>{{ item }}</p>
</each>
</if>
You could also account for the operation in an expression, but you might risk repeating code.
<!-- text was left undefined -->
<each loop="item in (typeof text === 'undefined' ? [] : text).split('\n')">
<p>{{ item }}</p>
</each>
<!-- text was left undefined -->
<!-- but we want a container to always exist, so we must repeat some logic -->
<if condition="typeof text !== 'undefined'">
<div class="paragraphs">
<each loop="item in (typeof text === 'undefined' ? [] : text).split('\n')">
<p>{{ item }}</p>
</each>
</div>
</if>
Keep in mind that this only works for surface-level locals, not nested ones, because I am shallow cloning default locals with the ArchieML output and the config.
Part of publishing is uploading static assets (like stylesheets, scripts, and sometimes images) to Amazon Web Services' Simle Storage Service (S3). For that to work, write a new file at ~/.aws/credentials
with the contents below:
[spectate] aws_access_key_id = YOUR_ACCESS_KEY_ID aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
See this doc for your access key.
Run cat ~/.aws/credentials
. If the output is the contents of the file you just made, you should now be able to run any publish command.
It is possible to configure defaults for the locals object, as well as the formatter for doc-to-archieml
. This can be done though a docs.config.js
file.
module.exports = {
defaultLocals: { ... }, // top: [] and body: [] are always defaults
formatter: function(textRun) { ... return content; },
};