Erstwhile is an SPA web development framework

It’s a little different than other frameworks:

  • It has a templating language caller ErML, which essentially lets you define your own HTML tags with all kinds of advanced behaviors.
  • It’s an MVC framework. The code is organized in a similar manner to other MVC frameworks like Ruby on Rails. But in the browser.
  • It has an optional backend module for your ExpressJS apps that lets the model layer essentially write itself semi-dynamically.

If you want to learn more about Erstwhile’s differences, checkout out our list.

Attention Theme Designers!

Erstwhile Framework is looking for open source theme designers to assist us in building out our standard bundled themes, as well as the standard tags and attributes. If you’re interested in getting involved, please click here for more details.

Get Started

It’s really easy to create a new project with Erstwhile.

If you want to dig in deeper, check out our extensive documentation.

# create a new directory for your project
mkdir myproject

# enter it
cd myproject

# initialize npm
npm init

# add the erstwhile framework
npm install --save erstwhile

# run the erstwhile init script to create a new project
npx erstwhile init MyProject

Erstwhile Highlights

ErML Templating System

ErML, our templating engine, lets you define custom tags and mix them with regular HTML in your view layer. This lets you easily encapsulate complicated functionality with your components and use it throughout your projects just as easily as HTML.

You can bundle sets of your custom components into Themes and use them across different projects, and override them at the application level if you need something just a little bit different.

<div class="row">
  <div class="col-lg-6 col-md-8 offset-3">
    <Card>
      <div class="row">
        <h2 class="pb-2">Sign Up</h2>
        <hr />
        <div id="initial-signup-form">
          <Alert id="signup-alert" color="danger" light="true" dismissible="true" hidden="true" message="@.page.errorMessage"></Alert>
          <Form id="signup-form" >
            <TextInput name="username" label="Username" required="true" />
            <PasswordInput name="password" label="Password" required="true" />
            <TextInput name="first_name" label="First Name" required="true" />
            <TextInput name="last_name" label="Last Name" required="true" />
            <EmailInput name="email" label="Email" required="true" />
            <Button color="primary" onclick="@.page.submitForm">Signup</Button> 
            <p class="mt-3">
              Already have an account? Click <a href="/login">here</a> sign in.
            </p>
          </Form>
        </div>
      </div>
    </Card>
  </div>
</div>

ErML Templating System

ErML, our templating engine, lets you define custom tags and mix them with regular HTML in your view layer. This lets you easily encapsulate complicated functionality with your components and use it throughout your projects just as easily as HTML.

You can bundle sets of your custom components into Themes and use them across different projects, and override them at the application level if you need something just a little bit different.

MVC Goodness

Erstwhile is a true Model-View-Controller framework. This means that your code will always be organized and easy to figure out, for both you 5 years from now or for the fella who takes over after you.

We make extensive use of ES6 Classes to implement a structure that looks very similar to other MVC frameworks like Ruby on Rails. It’s easier for newcomers to get up to speed without sacrificing any of the power.

const { ErstwhileController } = require("erstwhile");

class IndexController extends ErstwhileController {
  indexAction(args) {
    $App.scopes.page.title = "TestApp";
    $App.scopes.page.meta = {
      "og:description": "This is the default index page in Ersthile. Hopefully this text will change."
    }

    $App.scopes.page.message = "Hello, World!";

    $App.scopes.page.updateMessage = function() {
      let messages = [
        "Hello, World!",
        "You clicked the button",
        "One more time please",
        "This is fun!",
        "Erstwhile Framework Rulez"
      ]
      $App.scopes.page.message =  messages[Math.floor(Math.random()*messages.length)];
    }
  }
}

module.exports = IndexController;

Scoped Variables FTW

Erstwhile makes use of a concept called Scoped Variables to enable data and function sharing between the Controller and View layers.

This allows you to set variables in a Controller and change them through event handlers, timers, polling functions, or whatever else, and your View components are constantly made aware of any changes. Due to our flexible component classes, the components can handle these changes however they want to provide the best user/developer experience.

/controllers/IndexController.js
$App.scopes.page.submitForm = function() {
  $App.getComponent("signup-alert").hide();
  let formValues = $App.getComponent("signup-form").getValues();
  let model = $App.getModel('Authentication');
  if(formValues.password && formValues.password == formValues.password_2 ) {
    model.signup(formValues).then(function(response) {
      if(response.data.success) {
        jquery('#initial-signup-form').addClass("d-none");
        jquery('#signup-success').removeClass("d-none");
      } else {
        $App.scopes.page.errorMessage = "There were errors in your form";
        $App.getComponent('signup-form').showErrors(response.data);
        $App.getComponent("signup-alert").show();
      }
    }).catch(function(e) {
      console.log("error", e)
    });
  } else {
    $App.scopes.page.errorMessage = "The passwords need to match.";
    $App.getComponent("signup-alert").show();
  }
  return false;
}

 

/views/index/login.ejs
<Button color="primary" onclick="@.page.submitForm">Signup</Button>

Scoped Variables FTW

Erstwhile makes use of a concept called Scoped Variables to enable data and function sharing between the Controller and View layers.

This allows you to set variables in a Controller and change them through event handlers, timers, polling functions, or whatever else, and your View components are constantly made aware of any changes. Due to our flexible component classes, the components can handle these changes however they want to provide the best user/developer experience.

Pain-Free Models

When working with compatible backends, Erstwhile can automate generating your model layer for you. A simple shell command will connect to your backend dev server, ask it what endpoints it supports, and write the model classes needed to access those endpoints just where they should be.

Additionally, compatible backends use this same feature to become self-documenting, generating attractive pages like the one seen here.

Don’t worry, if you don’t have a compatible backend you can still use Erstwhile, you’ll just need to make your own models.