create-modulo
Version:
Starter projects for Modulo.html - Ready for all uses - Markdown-SSG / SSR / API-backed SPA
245 lines (194 loc) • 7.56 kB
HTML
<meta charset=utf8><script src=../static/Modulo.html></script><script type=md>---
title: Overview
description:
Learn more about Modulo Definitions through a tour of features with
interactive component examples.
---
Learn more about Modulo definitions through a tour of definition-related
features with interactive component examples.
# Component Parts
**More info: [Definition Types / Component Parts](definitions.html#componentparts)**
Once you have included Modulo and activated it, you can fill it up with
Component *definitions*, which are special tags in HTML format. These work like
keywords or configuration settings in order to set-up the component and define
it's apearance and behavior. Component _definitions_ start with a "Component"
opening tag in the format of `<Component name="HelloWorld">`.
What goes inside of Component Definitions? Why, _Component Parts_, of course!
By using a _Template_ and _Style_ in a Component we can make a very simple
starting component definition:
##### Example 1: SimpleStyle
```modulo
edit: demo=modulo
<!-- The simplest component: Template & Style only -->
<Template>
Components can use any number of <strong>Parts</strong>.
Here we use only <em>Style</em> and <em>Template</em>.
</Template>
<Style>
em { color: darkgreen; }
* { text-decoration: underline; }
</Style>
<!-- HINT: 1. Make a change and click RUN to see result
2. Hover over RUN button for more options -->
```
> **MVC** - The Model-View-Controller paradigm somewhat matches here: The _State_ is
> the _Model_, the _Template_ is the _View_, and the _Script_ is the
> _Controller_.
##### Example 2: To-Do MVC
Template and Style are just the beginning. Here's the classic **To Do MVC
App** written using Template, State, and Script, and taking advantage of these
Modulo features: _Template Variables_ (`{{ item }}`), Template Tags
(`{% for %} ... {% endfor %}`), and DOM directives (`state.bind`, `on.click`).
```modulo
edit: demo=modulo
<Template>
<ol>
{% for item in state.list %}
<li>{{ item }}</li>
{% endfor %}
<li><input state.bind name="text">
<button on.click=script.add>Add</button></li>
</ol>
</Template>
<State
list:='["Milk", "Bread", "Candy"]'
text="Coffee"
></State>
<Script>
function add() {
state.list.push(state.text); // add to list
state.text = ""; // clear input
}
<-Script>
```
# Core Definitions
> **Markdown and HTML... at once!?** Modulo uses a little "magic trick" that's
> visible if you do "View Page Source": This documentation is written in
> Markdown files that "disguise themselves" as HTML. This gets the best of all
> worlds: Directly viewable in a browser, directly editable in an editor, and
> directly loadable by Modulo. Try viewing source!
**More info: [Definition Types / Core Definitions](definitions.html#coredefinitions)**
Modulo can do more than just define web components. It ships with dependency
and configuration management tools (see "Include" and "Configuration"),
a management command system with a powerful SSG / SSR build system (see
"Artifact" and built-in management commands), a content management system (see
"ContentList" and it's built-in content types), and finally file inclusion and
namespacing tols (see "Library" and `-src=` pre-processor).
##### Example #1: Loading and Displaying Content
Combining the "Component Part" described above with the _ContentList_ described
here, we can create a simple Markdown file-based content management system:
```modulo
edit: demo=modulo_embed
<ContentList -load="md">
static/exampledata/article1.md.htm
static/exampledata/article2.md.htm
static/exampledata/article3.md.htm
static/exampledata/wood-chair
static/exampledata/plush-chair
</ContentList>
<Component name=App>
<Template>
{% for file in global.definitions.contentlist.files %}
<article>
<h3>{{ file.title }}</h3>
{% if file.description %}
<p><strong>{{ file.date }}</strong> - {{ file.description }}</p>
{% endif %}
</article>
{% endfor %}
</Template>
<Style>
* { margin: 0; padding: 0 }
article {
font-size: 90%;
background: pink;
border: 8px outset tomato;
padding: 3px;
font-size: 0.9rem;
color: #115;
display: block;
}
h3 {
background: tomato;
border: 8px outset pink;
display: inline-block;
color: white;
text-decoration: none;
margin-bottom: 10px;
}
</Style>
</Component>
```
> **What's "building" or "bundling"?** Building" is a feature of Modulo where
> it packs up all the components, JavaScript, and CSS you have loaded on
> a particular page into single `.js` and `.css` files, respectively. Each
> single file, called a _build_, contains all the code from all your components
> and various includes, optimized for fast loading. You can run this and all
> Modulo commands from the Modulo menu, available in your browser's console.
Note that as with custom Component Parts, users can create or customize new,
custom Core Definitions types as well, as well as registering custom management
commands, or content types or formats.
##### Example #2: Custom Bundle
Using the _Core Definition_ of `<Artifact>`, we can create custom build bundles
("artifacts") that only target certain operations, or modify code in a certain
way. Since Artifacts use Modulo's templating language, we can use
`<script Configuration>` to create a custom `minify` templateFilter, and output
a file called: `custom_bundle.(hash).js`:
```modulo
edit: demo=modulo_embed
<Artifact -bundle="script,modscript" name=js build=custom_bundle>
{% for id in def.ids %}
{{ def.data|get:id|minify|safe }}
{% endfor %}
{% for name in config.modulo.build.mainmodules %}
modulo.registry.modules.{{ name }}.call(window, modulo);
{% endfor %}
</Artifact>
<script Configuration>
modulo.templateFilter.minify = function (s) {
// Collapses whitespace and removes comments
return s.replace(/\/\*[^\*\!][\s\S]*?\*\/|\/\/.*$/gm, '')
.replace(/[\n \t]+/gm, ' ')
}
<-script>
<Component name=App>
<Template>
<button on.click=script.doCmd>► run "custom_bundle"</button>
</Template>
<Script>
function doCmd () {
modulo.argv = [ 'custom_bundle' ] // (bundle file gets this name)
modulo.command.custom_bundle(modulo)
}
<-Script>
</Component>
```
# Custom Types
**More info: [Custom Types](custom.html)**
It's easy to make re-usable Component Parts using JavaScript (or variants).
See below for how easy it is to make your own version of a component part, to
integrate custom JavaScript code or third party libraries:
```modulo
edit: demo=modulo_embed
<script Configuration>
modulo.part.autorefresh = class AutoRefresh {
initializedCallback() { // (once)
this.data = { count: 0 }
return this.data; // expose data to template
}
updateCallback() { // (after every render)
this.data.count++
const { delay } = this.attrs
setTimeout(() => this.element.rerender(), delay);
}
}
<-script>
<Component name=App>
<Template>
<h1>Refresh Count: {{ autorefresh.count }}</h1>
</Template>
<AutoRefresh
delay:=1000
></AutoRefresh>
</Component>
```