UNPKG

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
<!DOCTYPE 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>&#9658; 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> ```