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

ojster

v0.2.0

Published

Objective JavaScript Templater

Downloads

3

Readme

Ojster

Ojster is "objective javascript templater" - dead simple template engine which translates .ojst templates into javascript classes capable of template content rendering.

TextMate bundle for Ojster can be found here: https://github.com/4u/Ojster.tmbundle

Key Concepts

  • Templates are JS-based (similar to EJS)
  • Templates need "compilation" (similar to Google Closure Templates)
  • Compiled template is a regular JS class

Templates use full power of JS with minimal additions of non-JS syntax. You don't need to learn lot of new stuff, because you already know the language that is powerful enough to manage your templates. Ojster does not stop you from doing terrible things in templates, just like JS hardly stops you from writing terrible code. You can easily use any dirty tricks, but generally you shouldn't. Be good all the time and be evil only when you really have to. Ojster provides tags and other non-JS constructions only as a syntax sugar and to hide differences between various frameworks' inheritance and module systems.

With compilation templates are faster and have less errors, because they are already parsed and checked when it's time to render. Compilation is as simple and straight as possible. It always clear what final code will look like. And you can manage this code as any other code in your project - check with linter or your other favorite tool, compress with JS-compressor and so on. Template is a regular JS class, so you can inherit it from any other class or inherit some class from it or do whatever you usually do with your classes.

Features

  • Templates can be translated into code compatible with:
    • node.js
    • Google Closure Library
    • other frameworks support can be added easily
  • Same template file (if properly written) can be used to produce code for both node.js and Google Closure Library
  • Template blocks can be overriden (similar to Django templates' blocks, but more rich)
  • Parametrized template blocks are yet not ready, but planned
  • Any JS constructions allowed (for, if, etc.)
  • "Filters" are NOT supported (use JS code instead)

Compilation is very fast because it's dumb simple. All JS fragments of template are transferred to final code literally. Template blocks are translated into regular methods of compiled JS class. These methods capable of appending corresponding content and nothing more. They can be called any number of times at any place of template, overriden in child templates and so on.

Syntax

It's recommended to take a look at examples directory before continue to read. Examples are very simple and intuitive. By examining .ojst files and their corresponding .js files (compilation results) you will understand how template code is translated into JS code clearly enough. Further reading will provide you with details you could missed.

Template syntax is similar to EJS, but it has some extra conceptions. All the special constructions are enclosed within <% %> tags:

  • <%= ... %> - calculate expression and render result escaped. Will be translated into something like this.append(this.escape(...))
  • <%- ... %> - calculate expression and render result unescaped. Will be translated into something like this.append(...)
  • <% @commandName ... %> - one of the commands (described below).
  • <% ... %> - raw JS code fragment. Will be transferred literally. Can contain any JS code including this.append(...) calls.

Commands

  • require - imports required JS modules
  • template - describes template itself (it's name and so on)
  • inherits - describes template's base class
  • init - defines initializing function
  • func - defines function
  • block - breaks a template into reusable parts
  • base - base method call
  • call - calls block
  • insert - inserts other template
  • space - writes space
  • css - inserts getCssName(...) call

...other command descriptions to be added...

block command

  • <% @block blockName { %> - opens block blockName
  • <% @block blockName } %> - closes block blockName (blockName is optional here)

Code related to content between these two commands will be placed to appendBlockBlockName method of resulting template class. Blocks can be nested. If block is nested corresponding method call will be placed in appropriate place of nesting block.

<% @block A { %>
	a
	<% @block B { %>
		b
	<% @block } %>
<% @block } %>

will be translated into something like

TemplateClass.prototype.appendBlockA = function () {
	this.append('a');
	this.appendBlockB();
};

TemplateClass.prototype.appendBlockB = function () {
	this.append('b');
};

Note, that nested blocks haven't access to local variables of nesting block, because blocks are translated into completely separated (not nested) functions. Following example will not work as expected:

<% @block A { %>
	<% for (var i=0; i<10; i++) { %>
		<% @block B { %>
			<%= i %>
		<% @block } %>
	<% } %>
<% @block } %>

This examples will be translated into something like this:

TemplateClass.prototype.appendBlockA = function () {
	for (var i=0; i<10; i++) {
		this.appendBlockB();
	}
};

TemplateClass.prototype.appendBlockB = function () {
	this.append(i);
};

And of course i is undefined within appendBlockB function scope. Use parametrized blocks to transfer local variables into scope of nested block.

<% @block blockName {} %> - opens and closes block blockName. Such an empty block can be defined to be overriden in child templates.

main is a special block name indicating a block that will be appended on template's render() method call. By default, text outside of any block will be supposed to be a raw JS code.

Readme TODO

  • move detailed descriptions to doc/ directory, here should be just quick examples
  • for doc/:
    • more on syntax
    • all the commands
    • locals
    • detailed usage of bin/ojster
    • guide to generated code
  • programmatic usage of ojster
  • provide short usage of bin/ojster
  • describe difference between Node and Closure module systems and how it is handled by Ojster

License

MIT