UNPKG

create-modulo

Version:

Starter projects for Modulo.html - Ready for all uses - Markdown-SSG / SSR / API-backed SPA

276 lines (201 loc) 9.3 kB
<!DOCTYPE html><meta charset=utf8><script src=../static/Modulo.html></script><script type=md>--- title: Processors description: Overview of definition processors. --- # Processors **Definition processors** are a feature of Modulo that allows for component parts and other definitions to support special attributes that trigger certain behavior. They are commonly used for configuring, loading, or tranforming definitions. Definition processors are conventionally prefixed with a dash (that is, `-`). This distinguishes them from regular attributes. Some processors can only be used with a certain type of component parts or definitions. For example, examine the `-store=` processor for _State_: ``` <State -store="userdata" username="crash0veride" ></State> ``` Others are supported by all component parts. For example, examine the `-src=` processor for loading content from external files. ```modulo <Template -src="my-template.html"></Template> <Style -src="fancy-look.css"></Style> ``` ## Behavior Definition processors have three important rules of behavior: 1. As the name implies, definition processors are run while Modulo first loads definitions, meaning all the _Processors_ will all complete before your web components register their tag names. Definition processors are applied _before_ any other behavior. That is to say, _every_ processor finishes its tasks before _any_ components are mounted on the screen. 2. Processors can be asyncronous, load data, process data, and can even do "slow" operations compared to other aspects of Modulo. CParts can load asyncronously, or even block loading if they choose to do so. This is what allows Modulo to self-configure and users to "invent" their own CParts: `<Configuration -src="...">` will block loading any future `-src=` attributes until it's finished with all it's Processors; however, `<Template -src="...">` is written to assumed to not need any particular ordering, and will be loaded asynchrously. 3. Definition processors are _not_ run in built or packed scripts. That is, the definitions stored in the compiled JS file are "pre-processed", and thus the processor only will run during development or when building. If accumulating many files and definition processors is slowing down your growing site, the good news is that after building, no one will notice, since _Processors_ are (typically) only run during development. # Built-in Processors > **Why no dash for `<Component name="...">`?** Note that for _Component_, you > use `name=` (without the `-`), and use a valid JavaScript identifier as the > Web Component name. However, that behavior is specific to the _Component_ > definition, and is not available on Component Parts or other definitions. > Definition types (e.g. [core definitions](/docs/core/) like _Library_ or a > [component parts](/docs/cparts/) like _State_) can each specify their own, > unique behavior for processors. ## -name * Supported by: **All Definitions** The `-name` directive allows you to override the default name that Modulo will generate with something else. This allows you to have multiple Component Parts of the same type without conflict. For a simple example, see below: ```modulo <Template -name="footer_template"> ``` ### Example: `-name` for multiple Component Parts Note that _Template_ has special behavior around `-name`. If you specify a name, it will _not_ by default still render, since it will assume you are going to include it somewhere else. ```modulo_demo <Template> {# This becomes the "primary template" (named "template") #} <h3>Welcome to my blog</h3> <p>Things I like: {{ likes_data }}</p> <p>Things I dislike: {{ dislikes_data }}</p> {% include footer_template %} </Template> <Template -name="footer_template"> {# This becomes a non-primary template (named "footer_template") #} <p>(C) 2095 Tux the Penguin</p> </Template> <StaticData -name="likes_data"> [ "Fish", "radishes", "hackable software" ] </StaticData> <StaticData -name="dislikes_data"> [ "Wet towels" ] </StaticData> ``` ## -src * Supported by: **All Definitions** ```modulo <Template -src="./MyComponent/MyComponent.html" ></Template> <Script -src="./MyComponent/MyComponent.js"> function anotherFunction() { // Etc... } <-Script> <Style -src="./MyComponent/MyComponent.css" ></Style> ``` ### -src for JavaScript extension Note that the -src= combines the retrieved content with whatever is embedded between the opening and closing tag. It _does not_ replace the embedded content, but instead places the retrieved content before content _BEFORE_ the embedded content. This ordering is important, since it allows the internal content to "extend" the content that is being brought in. In this case, due to the order of function declaration behavior, the `anotherFunction` declaration will take precendence (since it's declared last) over whatever `anotherFunction` might have been declared in `MyComponent.js`. ### -src for _Component_ extension The `-src` attribute is designed to allow for many types of "inheritence" or a sort of primitive extension, depending on the CPart. For example, _Components_ can "inherit" CParts of base components (e.g., the _Template_ and _Script_ could be the same across two _Components_, but they only differ in _Style_), or _Style_ can "inherit" another style file, but get to append some modifications to the end. (e.g., loading from a third party, then override certain properties). Similarly, _Library_ or _Modulo_ can load entire Modulo libraries, and then apply _Configuration_ scripts at the end to modify configuration settings within that other libraries' execution context. ## -filter-content * Supported by: **Template**, **StaticData**, **Style** Allows you to apply [template filters](/templating/filters.html) at load time. ##### Example 1: Trim excess code You can use `trim` to remove excess characters from a remotely loaded file. For example, here we load content from an external document file, and then use `|trim` to clean up the doctype information, text we don't want in the _Template_: ```modulo <Template -src="https://some-site.com/some-old-document.xhtml" -filter-content="trim:'<xml version=1.0><html>,</html>'" ></Template> ``` In this case, the `trim` filter will remove the XML doctype and an HTML opening tag, along withe the HTML closing tag, if they are found at the beginning and end of the document retrieved from: `https://some-site.com/some-old-document.xhtml`. Processors all happen during initial loading of components and definitions, meaning the trimmed text will be ignored and omitted from the JS builds. ##### Example 2: Style template with trim By defining a `style Template`, we can template style for inclusion. By using `trim` we can use a placeholder of `x { .. }` to make editing this CSS easier to read. Note that this is, in fact, a _Template_ CPart, however, we will use a `style` initial tag to make it easier to read and syntax highlight. See below for a concrete example of how to use this technique for making a quick button designer component: ```modulo_demo edit: demo=modulo <Template> <label><input state.bind name="bg" type="color" /> Color</label> <label><input state.bind name="size" type="range" min="5" max="20" /> Size</label> <button style="{% include button_style %}">Sample Button</button> <pre>button { {% include button_style %} }</pre> </Template> <style Template -filter-content="trim:'x {,}'" -name="button_style"> x { background-color: {{ state.bg }}; font-size: {{ state.size }}px; } </style> <State bg="#a0caa0" size:=10 ></State> ``` ##### Example 3: Tagswap for `<table>` Modulo uses HTML syntax for most everything. This, unfortunately, means that `<table>` tags can behave differently when it comes to how content is processed and loaded, causing content to "escape" when you are still just assembling the initial Template's DOM. Similarly, the closing `script` tag can have special meanings as well. To get around limitations like this, we can use the `|tagswap` to convert innocuous placeholder tags into other ones: ```modulo_demo edit: demo=modulo <Template -filter-content="tagswap:'t=table r=tr d=td'"> <t> <r> <d>Col 1</d> <d>Col 2</d> <d>Col 3</d> </r> <r> <d>A</d> <d>B</d> <d>C</d> </r> <r> <d>1</d> <d>2</d> <d>3</d> </r> <r> <d>X</d> <d>Y</d> <d>Z</d> </r> </t> </Template> <Style> table { border: 2px solid Tomato; } td { border: 1px dotted Tomato; padding: 2px; } </Style> ``` > **Gotcha: Applied at loading time** Remember that it is applied "pre-baked" > to the content itself during initial content load, and NOT at _Template_ run > time, meaning it will affect (and potentially disrupt) the tempting language > itself as well (e.g. using `-filter-content="upper"` will cause `{{ > state.stuff }}` to become `{{ STATE.STUFF }}`, which _will not_ work since > capitalization matters in this case). This will be applied at load time, so there are ultimately no performance penalties, as the final JavaScript file will have the tag transpositions "baked in" (and with no trace of the original template, either).