• Stars
    star
    182
  • Rank 204,110 (Top 5 %)
  • Language Haxe
  • Created over 9 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Haxe externs for Mithril (JS MVC framework)

Mithril for Haxe

Mithril is a small, yet great javascript MVC framework that is faster and more flexible than most others. Here's the Haxe version for Mithril 2, with some useful extra features thanks to macros and the type inference.

Installation

Standard procedure: haxelib install mithril and then -lib mithril in your .hxml file.

How to use

Mithril has a great introduction on its website and plenty of documentation, so I'll only highlight what you need to get started with the Haxe version here.

Implement the Mithril interface

When using Mithril, you will create components that will be used with the Mithril API. The recommended way to create a component is using a class that implements the Mithril interface. Here's an example of a Mithril component:

import mithril.M;

class TodoComponent implements Mithril
{
    var todos : Array<Todo>;

    public function new(todos) {
        this.todos = todos;
    }

    // When implementing Mithril, the last m() expression 
    // or Array of m() is returned automatically.
    public function view()
        m("div", [
            m("h1", "To do"),
            m("table", [for(todo in todos)
                m("tr", [
                    m("td", m("input[type=checkbox]", { 
                        onclick: e -> todo.done = e.target.checked,
                        checked: todo.done
                    })),
                    m("td", todo.description)
                ])
            ])
        ]);
}

/**
 * The model
 */
class Todo
{
    public var done : Bool;
    public var description : String;

    public function new(description, done = false) {
        this.description = description;
        this.done = done;
    }
}

class Main
{
    // Program entry point
    static function main() {
        var todos = [
            new Todo("Learn Haxe"),
            new Todo("??"),
            new Todo("Profit!")
        ];
        
        M.mount(js.Browser.document.body, new TodoComponent(todos));
    }
}

The major API differences

  • Use M, not m! import mithril.M;, then use M instead of m for the whole API. As you see above, the only exception is when using m(), you can use that without prefixing with M.
  • m.redraw.sync() is available through M.redrawSync().

Upgrading from 1.x to 2.x

  • The M.route methods can now be called as in the Mithril syntax, M.route.param etc. To call M.route however, use M.route.route.
  • M.withAttr has been removed. Use an e -> e.target lambda function instead.

When using Node.js

If you're using Node.js, you can install and use Mithril from npm instead of the Haxe port (see below for server side examples). To do that, define -D mithril-native.

Side note: "this" is slightly different in native javascript

Because of the slight mismatch between Haxe classes and the classless Mithril structure, in lifecycle methods, the native javascript this points to vnode.tag instead of vnode.state. Otherwise it would have pointed to another object when inside instance methods.

This is usually nothing you have to worry about if you're using Haxe classes for your components and state. In that context, this works as expected.

Haxe examples

This repo has some examples that can be interesting to test. Clone it, open a prompt in the directory and run:

haxelib install mithril

Then select one of the following:

Some small apps

A collection of two demo apps, available on the Mithril site.

  1. haxe client.hxml
  2. nekotools server -d bin
  3. Open http://localhost:2000/ in a browser.

Webshop

A simple e-commerce site to demonstrate the power of Mithril.

  1. haxe webshop.hxml
  2. nekotools server -d bin/webshop
  3. Open http://localhost:2000/ in a browser.

Live demo here: http://ciscoheat.github.io/webshop

From scratch

If you prefer a bare-bones example (doesn't require cloning), create the following two files and follow the instructions below:

index.html

<!doctype html>
<body>
<script src="https://unpkg.com/mithril/mithril.js"></script>
<script src="example.js"></script>
</body>

Example.hx

import mithril.M;

class User
{
    public var name : String;

    public function new(name) {
        this.name = name;
    }
}

class Example implements Mithril
{
    var user : User;

    public function new() {
        this.user = new User("Thorin Oakenshield");     
    }

    public function view() [
        // Display an input field
        m('input', {
            // Updates the model on input
            oninput: e -> user.name = e.target.value,

            // The redraw triggered by the oninput event will update
            // the input field value from the model automatically
            value: user.name
        }),
        
        // Display a div with class .user and some style
        m('.user', {style: {margin: "15px"}}, user.name)
    ];

    // Program entry point
    static function main() {
        M.mount(js.Browser.document.body, new Example());
    }
}

Compile and run with:

  1. haxe -lib mithril -js example.js -main Example
  2. Open index.html in a browser.

Server side - All targets

The rendering part of Mithril has been ported to Haxe, so you can now enjoy writing Mithril templates and have them rendered to HTML anywhere. Here's a class to get you started:

import mithril.MithrilNodeRender;
import mithril.M.m;

class Main {
    static function main() {
        var view = m("ul", [
            m("li", "item 1"),
            m("li", "item 2"),
        ]);

        // <ul><li>item 1</li><li>item 2</li></ul>
        Sys.println(new MithrilNodeRender().render(view)); 
    }
}

(Note: The above code may not work in interp mode. Test it with neko instead.)

Server side - Node.js & isomorphism

Without too much hassle, it's possible to render a Mithril component/view serverside on Node.js. Run the following in the repo directory:

  1. npm install
  2. haxelib install hxnodejs
  3. haxe server.hxml
  4. cd bin

Example 1: Simple rendering

node server.js outputs a simple HTML rendering example.

Example 2: Isomorphic code

node server.js server

Starts a server on http://localhost:2000 that executes the same code on server and client. The server generates the HTML so the page is perceived to load quickly and search engines can index it, then the client enables the functionality.

Example 3: Cross-platform rendering

As a bonus, a Neko version of Example 1 will also be compiled. Test it with

neko server.n

The MithrilNodeRender is tested with travix and should work on all targets.

Feedback please!

Feedback is always welcome! Open an issue and give me a piece of your mind. :)

More Repositories

1

sveltekit-superforms

Making SvelteKit forms a pleasure to use!
TypeScript
1,793
star
2

sveltekit-flash-message

Send temporary data after redirect, usually from endpoints. Works with both SSR and client.
TypeScript
208
star
3

sveltekit-rate-limiter

A modular rate limiter for SvelteKit. Use in password resets, account registration, etc.
TypeScript
140
star
4

buddy

Your friendly BDD testing library for Haxe!
Haxe
96
star
5

dataclass

Give your Data some class!
Haxe
47
star
6

HaxeContracts

A Design by contract library for Haxe.
Haxe
44
star
7

haxedci

DCI for Haxe!
Haxe
40
star
8

slambda

Short Lambda expressions in a tiny Haxe library
Haxe
40
star
9

haxedci-example

Example code for haxedci (DCI library for Haxe)
Haxe
36
star
10

haxelow

A small, flat JSON database library for Haxe.
Haxe
35
star
11

deepstate

An immutable state container for Haxe 4, similar to Redux.
Haxe
30
star
12

immutable-hx

Makes even local vars immutable in Haxe 4.
Haxe
29
star
13

superforms-web

Website for the SvelteKit library Superforms
Svelte
29
star
14

erazor

A Haxe implementation of the Razor view engine
Haxe
19
star
15

sveltekit-spa

[DEPRECATED] How to configure SvelteKit to become a SPA with client-side routing.
Svelte
18
star
16

unject

A dependency injection library for haXe, inspired by Ninject.
Haxe
16
star
17

umock

A mocking framework for Haxe, inspired by Moq.
Haxe
13
star
18

uniontypes

Union types in Haxe, similar to Typescript
Haxe
12
star
19

ivento-dci

A DCI library for C#, using extension methods
C#
9
star
20

htemplate

A cross-platform template engine for haXe
Haxe
7
star
21

SnakeDCI

A demonstration of DCI in game programming, creating the classic Snake game in Haxe and the Phaser game framework.
Haxe
7
star
22

vite-plugin-haxe

Run Haxe code on Vite.
TypeScript
5
star
23

prisma-to-zod

Generate Zod validation schemas from a Prisma schema.
TypeScript
5
star
24

typesafe-i18n-with-sveltekit

SvelteKit and typesafe-i18n for modern multi-language sites.
TypeScript
4
star
25

simplest-sitegen

The simplest static sitegen there is. Build a modern, fully working website with only HTML.
HTML
4
star
26

nodehost

Quick Node.js hosting on ubuntu/debian with nginx
Haxe
3
star
27

NosceIpsum

A gentle reminder to keep focus on the Now
C#
2
star
28

odm-web

Website created for the ODM Haxe meetup.
Haxe
2
star
29

MakeItPortable

An autohotkey library for creation of Portable Applications
2
star
30

viagrant

Quick 'n dirty node script for building Vagrant files.
Shell
2
star
31

dcisniffer

A DCI Standard for PHP, to be used with PHP_CodeSniffer.
PHP
2
star
32

prismic-hx

Haxe externs for prismic.io
Haxe
1
star
33

dilemma

Prisoner's dilemma in Svelte
Svelte
1
star
34

asynctools

Haxe implementation of the npm async package
Haxe
1
star
35

vite-plugin-svelte-globalcss

Use global css/sass in a sveltekit app.
TypeScript
1
star
36

empty-haxe-project

Empty Haxe project starting point. Node/Neko/Js ready.
Haxe
1
star
37

eslint-plugin-dci-lint

DCI linting for Typescript and ESLint
TypeScript
1
star
38

superforms-examples

Examples for Superforms
Svelte
1
star