npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

pug-mithrilier

v2.1.0

Published

pug-mithrilier

Downloads

15

Readme

PUG-MITHRILIER - A design-focused abstraction layer over Mithril and PUG.

NPM

========

Join the chat at https://gitter.im/imrefazekas/pug-mithrilier

pug-mithrilier is a small utility library allowing you define your views in PUG templating engine.

The aim is to have a toolset facilitating a design-focused orchestration leveling a very simple way to manage the MVC part of a webapp. You can define your

  • views using PUG as template engine
  • models and validation rules with plain JS object

and pug-mithrilier will generate the necessary Mithril components you can mount to your app. To support the "multi-island scenario", you can associate multiple views to the same model or mount the same templates to different DOM parent as your needs encourage you to orchestrate.

Applications are not created in a vacuum, teams are working on it and design and code are evolving continuously urging the development team to handle representation freely. In other words, you should be encouraged to choose the template engine and the orchestration structure of yours, fitting the best your project. This solution wants to show a proven way.

Concept of PUG

Some environment involving multiple teams urges the need of an independent view layer, where the functional and the presentation layer can be distinguished. The view layer must be freed from unnecessary technical decoration within the reach of everyone during the whole lifecycle of the app. Styles, layouts, UI components could be refined over the time not inducing any process on service-level.

PUG is a very simple, yet power templating engine to be used.

Concept of plain JS models

To have a real JS-based full-stack solution, the need of shared data models and validation comes naturally. You execute the same validation rules on the UI and in the REST services; you use the same models in the MVC mapping code and DB services.

We should resist the temptation of rogue paths. No philosophical essays can be considered as apology for breaking the most important design pattern of JS: developers must respect the standards (and the code culture of the company). You can have one (versioned) model repository used by all tiers of your app.

The first step on this road is common coding style and module format.

The simplest way is to use plain and pure JS object as a CommonJS module requirable by any code you write. Require function is provided on the client-side by webpack or browserify.

Straight in to an example

The following PUG file (Content.pug) defines a view of a Person:

.section
	text.h6 Sign up
	br
	input.c_ds_blue.hN.text-center(type="text", id="join_name", placeholder="Your name", data-bind="name")
	br
	input.c_ds_blue.hN.text-center(type="text", id="join_email", placeholder="Your email address", data-bind="email")

Let's reference it from an index.html file:

<html>
<body>
	<div>
		<div id="Content" data-mount="Content" data-model="Person"></div>
	</div>
	<script src="main.js"></script>
</body>
</html>

A 'div' tag has been defined embedding the Person view defined earlier. The main.js serves as the functional entry point.

Let's compile the PUG onto Mithril using gulp:

var mithrilier = require('pug-mithrilier');

gulp.task('mithril', function( cb ){
	var folder = './m/';

	var pugContent = fs.readFileSync( 'Content.jade', { encoding: 'utf8' });
	var mithrilView = mithrilier.generateMithrilJS( pugContent );
	fs.writeFileSync( 'Content.js', mithrilView.trim() + '\n', { encoding: 'utf8' } );

	cb();
});

Let's have a Person model:

module.exports = {
	dataModel: {
		name: 'John Doe',
		email: '[email protected]'
	},
	validation: {
		name: { minlength: 6, element: ["John Doe"] },
		email: { type: 'email' }
	}
};

This CommonJS code defines the 'name' and 'email' attributes with validation rules attached.

Let's connect it with the main.js:

var m = require('mithril');
var model = require( './models/Person' );
var element = document.getElementById('Content');
var viewName = element.getAttribute('data-mount');
var modelName = element.getAttribute('data-model');
modelLoader.mount( model, self, viewName, modelName, element );

And you are done. Of course, you can orchestrate your project as you desire. You can

  • have tons of models and views
  • use same models for different views
  • use same view at multiple points in the page

For a complete demo about features and services, see the folder demo-project. It uses

  • Webpack to have CommonJS and require function on the client-side
  • gulp delivering task execution

Note: That demo uses automation to make ready all views you define and all referred models. You might find this overdramatisation, but it is actually closer to a live project.

Note: Please keep in mind, that it is JS and PUG(HTML) bridge we are dealing with, so try to define your embedded JS expressions escaped properly as the example below shows:

text(data-value="terms() ? \"Haloho\" : \"Hehehehe\"!")

Binding markup

pug-mithrilier handles the following binding markup:

At mounting points:

  • data-bind: identifies the mithril template / view to bind with
  • data-model: when you share templates and models across DOM elements, this attributes helps to match the participants
  • data-opts: when the binding is depending on specific unique context. Some part of the view can be seen only on the 'control' page but cannot be seen on the 'view' page. So one view reused on different places and behaving accordingly. This environment can be reached by using the '$opts' variable in an expression of the tags listed below.

In template PUG:

  • data-bind: 2-way binding for a given attribute of the model.
  • data-value: 1-way binding for a given attribute of the model. Good to present value from model.
  • data-each: maps array-typed attribute from the model
  • data-prop: properties of a given DOM element are set dynamically by the expression defined by 'data-prop'
  • data-attr: attributes of a given DOM element are set dynamically by the expression defined by 'data-attr'
  • data-class-enable: the given class names are added or removed to/from the DOM element
  • data-attr-enable: the given attributes are added or removed to/from the DOM element
  • data-visible: visibility of a given DOM element is determined dynamically by the expression defined by 'data-visible'
  • data-enable: the attached expression will determine if 'enabled' or 'disabled' class will be added to the DOM element
  • data-select: the attached expression will determine if 'selected' class will be added or removed to/from the DOM element
  • data-display: the boolean value of the expression attached determines if the given DOM element can be displayed (set in CSS rules) or not
  • data-style: style properties of a given DOM element are determined dynamically by the expression defined by 'data-style'
  • data-html: the content of a given DOM element is determined dynamically by the expression defined by 'data-html'
  • data-tap: tap handler. The element will catch tap events (via HammerJS) and generate 'tapped' events through the context

License

(The MIT License)

Copyright (c) 2016 Imre Fazekas

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Bugs

See https://github.com/imrefazekas/pug-mithrilier/issues.