TIBET Logo

TIBET Quickstart

Quicker

Thank you for giving TIBET a try!

Over the next few minutes we'll create a simple Hello World! application using no code.

When you're done you'll not only have written Hello World! entirely in markup, you'll have a reusable hello:world tag other developers can consume without writing code themselves.

Shifting the "component consumption model" from code to markup is the critical difference TIBET brings to web development, a markup-first approach that's fully-tooled and fully-supported.


tl;dr

Hello World! in TIBET requires no code, just markup, which seems appropriate.

TIBET doesn't make simple things harder. You don't need to learn a new language to do things you can do in markup already, TIBET keeps simple things simple.

# Install TIBET
$ npm install -g tibet

# Create a new project, initialize it, and start the development server.
$ cd /tmp   # or a suitable temporary directory
$ tibet clone hello
$ cd hello
$ tibet init
$ tibet start

# Write Hello World!
#   Edit public/src/tags/APP.hello.app/APP.hello.app.xhtml to contain
<h1 tibet:tag="hello:app">Hello World!</h1>

# Style Hello World!
#   Edit public/src/tags/APP.hello.app/APP.hello.app.css to style your <h1> tag
h1 { color: green }

That's it. Hello World! with no code, just markup and CSS. As it should be.

So why use TIBET? So you can quickly turn Hello World! or any other component into a reusable component other projects can consume with little or no code.

To see how TIBET makes that possible read on....


First Steps

Prerequisites

To complete this tutorial you'll need to be running on a Mac or Linux environment (Windows support is upcoming). You'll also need Node.js version 6.0 or higher and npm version 3.0 or higher.

Installation

$ npm install -g tibet

If you have any issues installing TIBET see the full installation instructions.

tibet quickstart

Once TIBET is installed the tibet command gives us access to a wide range of tools to streamline development. We'll start with the quickstart command.

Enter tibet quickstart to display quickstart info:

$ tibet quickstart

Welcome to TIBET! This quickstart content is intended to get you up and running
with a minimum of overhead so we'll be working with a limited set of commands
and using their default options. Once you're done, check out the documentation
at https://www.technicalpursuit.com/docs/platform.html to dive deeper into TIBET.

CREATE A NEW PROJECT

The 'tibet clone' command is your first step in creating a TIBET project.

Before using clone navigate to a directory to hold your new project content
and select a name for your new project. The name will be used as a directory
name so it should be a valid directory name on your platform.

Type 'tibet clone {appname}', replacing {appname} with your project name:

    $ tibet clone hello
    ...
    Application DNA 'default' cloned to ./hello as 'hello'.
    ...

INITIALIZE THE PROJECT

With your new project in place you need to initialize it to install any code
dependencies specific to the template you cloned (we used the default here).
Navigate to your project and then type 'tibet init' to initialize it:

    $ cd hello
    $ tibet init
    ...
    project initialized successfully.
    ...

START THE SERVER

The 'default' template used by clone includes a Node.js-based HTTP server
we call the TIBET Data Server or TDS. By default the TDS will use port 1407
so assuming that port isn't busy on your system you can start the server
using 'tibet start' without any parameters:

    $ tibet start
    ...
    1498043782937 [7] TDS hello 0.1.0 @ http://127.0.0.1:1407#?boot.profile=development (dev)

Congratulations! Your new TIBET project is running. Open the web address
for your project in a supported HTML5 browser and you'll see text directing
you on how to take the next step in your TIBET journey.

For more info visit https://www.technicalpursuit.com/docs/platform.html.

We're going to follow quickstart's steps to get our first project started.


Project Framing

Project Framing


tibet clone

The tibet clone command creates a new TIBET project by cloning a template directory, what we call 'dna', into a target directory. The simple form is tibet clone <appname>. For this tutorial our <appname> will be hello.

Move to a suitable temporary or development directory:

$ cd ~/tmp

Create the hello project using tibet clone hello:

$ tibet clone hello
...
Application DNA 'default' cloned to ./hello as 'hello'.
...

tibet init

The next step is to initialize our new project. The tibet init command ensures that all dependencies in the project's package.json file are loaded and ready.

Because it depends on the specific DNA you choose, the public npm repository, and your download speed, this step can take from a few seconds to a few minutes. Be patient :).

Initialize the new project via tibet init

$ cd hello
$ tibet init
...
project initialized successfully.
Use `tibet lint` to check for coding standard violations
Use `tibet test` to test your application's core features
Use `tibet build` to build production packages for deployment
Use `tibet start` to run your application.

Once the project has initialized we've got a runnable TIBET application.

tibet start

The default dna template includes support for the TIBET Data Server or TDS. The TDS is an optional Node.js server that makes it easy to create full-stack TIBET applications.

NOTE: TIBET is 100% server-agnostic and does not require the TDS in production. You can use TIBET with any HTTP-accessible server or on the desktop via Electron.

Start the TDS by typing tibet start:

$ tibet start

                                  ,`
                            __,~//`
   ,///,_            .~////////'`
  '///////,       //////''`
         '//,   ///'`
            '/_/'
              `
    ////////////////////     ///////////////////  ////
    `//'````````````///      `//'```````````````  '''
     /`              //       /'
    /                //      '/
   ,/____             /'    ,/_____
  /////////;;,,_      //   ,//////////;,_
              `'/,_   '/              `'///,_
                 `'/,_ /                   '//,
                    '/,/,                    '/_
                      `/,                     `/,
                        '                      `/
                                               '/
                                                /

1504056886785 [7] TDS TIBET Data Server v5.0.0-pre.11 (development)
...
...
...
1504056888242 [7] TDS hello 0.1.0 @ http://127.0.0.1:1407 (production build) (build)
1504056888242 [7] TDS hello 0.1.0 @ http://127.0.0.1:1407#?boot.profile=development (dev)

The TDS outputs the TIBET logo, various pieces of information about the library, application, and middleware stack, and ultimately a URL you can use to launch the application from the client. Once you see the launch URL your server is ready to handle requests.


Project Launch

Supported Browsers


TIBET is unique in that it loads into your browser once at startup, parsing your code once and staying resident regardless of how many times you redraw your UI.

The TIBET Loader is responsible for loading the TIBET library and your application code, which it does in two phases. First the TIBET library loads, then your application code.

If you activate TIBET's login page feature the library code loads in the background while the user is logging in and application code loads upon success, dramatically reducing user-perceived startup times. For our hello demo the login sequence is off by default.

Booting 'hello'

Let's boot our new hello application and see the loader in action.

Load http://127.0.0.1:1407#?boot.profile=development in Chrome, Safari, or Firefox:

Project Startup

TIBET Launch


By default TIBET shows you a boot screen including a progress bar. There are other configurable options and, of course, you can alter this UI to fit your needs.

Boot Complete

Once the application has booted successfully you should see the application's default home page content rendered in the window:

Project Home Page

Default Home Page


Congratulations! You're running your first TIBET application!

Let's take a moment and review our steps so far:

$ tibet clone hello
$ cd hello
$ tibet init
$ tibet start

Three simple tibet commands and we've got a running application, one with a simple Node.js server and TIBET's client-side framework loaded and ready for development.

Our project also has built-in lint, test, and build command support without having to install any other components or modules. TIBET provides the entire toolchain.

TIBET provides a true "sum of the parts" solution that covers everything a modern web application requires in a fully-supported single-vendor stack.


Test Ready

Now is a good time to mention testing.

All TIBET projects start out with a handful of pre-built tests which provide a starting point for you to work in a test-driven, or at least test-backed, fashion.

The TIBET CLI includes a test command. Let's run it and see what happens...

Open a new terminal window, navigate to your project and enter tibet test:

$ tibet test
# Loading TIBET via PhantomJS 2.1.1 at July 15, 2017 at 15:43:30 MDT
# TIBET loaded in 4986 ms. Starting execution.
# TIBET starting test run
# 2 suite(s) found.
1..3
#
# tibet test APP --suite='APP suite'
ok - Has a namespace.
ok - Has an application type.
# pass: 2 total, 2 pass, 0 fail, 0 error, 0 skip, 0 todo, 0 only.
#
# tibet test APP.hello.app.Type --suite='APP.hello:app suite'
ok - Is a templated tag.
# pass: 1 total, 1 pass, 0 fail, 0 error, 0 skip, 0 todo, 0 only.
#
# PASS: 3 total, 3 pass, 0 fail, 0 error, 0 skip, 0 todo, 0 only.

# Finished in 5194 ms w/TSH exec time of 208 ms.

Here we can see that TIBET has already generated some baseline tests for our application and its initial tag, helping ensure we start our work from a green test state.

On with the tour...


Turtles Tags All The Way Down

<turtle>
    <turtle>
        <turtle>...</turtle>
    </turtle>
</turtle>


We often say TIBET is 'tags all the way down'. We're not kidding. From the moment our application starts we're running a system whose focus is processing tags.

Tags and their associated types provide a consistent, reusable, structured way to assemble applications and to reuse their components across projects without more coding.

Pages vs Tags

The 'home page' for a default TIBET application differs from typical web applications in that it normally contains a single tag in the <body>, what we refer to as the 'app tag':

...
<body>
<hello:app xmlns:hello="urn:app:hello"/>
</body>
...
home.xhtml


One implication of TIBET organizing applications around an app tag is that all TIBET applications are composable. We can take our <hello:app/> tag and use it anywhere, not just as a standalone application but as a reusable component.

The other implication is that we don't alter TIBET applications by editing 'pages', we alter them by editing tags, starting with the application tag and working down through any nested component tags that ultimately define the application's interface and behavior.

Where The Tags Are

When we cloned the default dna creating our project TIBET processed our dna template files and created a hello:app application tag. That tag's files are found in our application's tag directory, public/src/tags, in a tag-specific subdirectory which keeps all of the tag's resources in a sharable "bundle":

A listing of our project's public/src/tags directory shows the following:

$ ls -C1 public/src/tags
...
APP.hello.app
...
public/src/tags


Let's look at the tag bundle itself:

$ ls -C1 public/src/tags/APP.hello.app
...
APP.hello.app.css
APP.hello.app.js
APP.hello.app.xhtml
APP.hello.app.xml
APP.hello.app_test.js
...
public/src/tags/APP.hello.app


There's our application tag type and unit test file along with an associated style sheet, xhtml template, and bundle package. If we were to open that template file in an editor we'd see the content that's currently displayed in our application home page.

Our first foray into TIBET development will be to alter that content.

Virtual Paths

Before we move on, a quick word about TIBET "virtual paths".

TIBET was designed and built to run with or without a web server meaning app resources might load from a wide variety of URI schemes. To avoid issues with path resolution TIBET uses "virtual paths", configuration values which let you refer to resources indirectly, avoiding hard-coded paths.

For the remainder of this document we'll use one of the more common ones, ~app_tags to refer to the root public/src/tags we've used to this point.

Note the leading ~ (tilde) on that reference. All TIBET virtual paths are identified with a leading tilde to indicate they require resolution to their absolute path equivalent.

Back to the tour...


Tag Authoring

Tag Authoring


The 'App Tag'

When our application starts, TIBET processes the content of our home page and transforms our hello:app tag to produce what we see as home page content.

By default TIBET tags are template-driven so for our hello:app tag we see the content of APP.hello.app.xhtml, our tag's template file. Using external template files lets us run well-formed and validation checks on our application's markup, helping ensure quality.

Edit ~app_tags/APP.hello.app/APP.hello.app.xhtml to contain:

<h1 tibet:tag="hello:app">Hello World!</h1>
APP.hello.app.xhtml


There's our single line of markup to create Hello World!

Save your changes and TIBET will automatically re-render the tag.

Hello World!

Hello World!


Hello World! is complete and we wrote no code and didn't reload. Simple.

Live Patching

F5 reload


One of the central features of TIBET is the focus on eliminating reload cycles.

With TIBET you can edit source code, template files, and style sheet content and TIBET will instantly integrate your changes without reloading the page.

TIBET's 'live patching' is a powerful improvement on live reload in that TIBET never truly reloads the page, potentially flushing valuable context, data, etc. Instead TIBET patches your source code, templates, and style changes in-situ.

How did TIBET know to load and render APP.hello.app.xhtml? The answer lies in the key TIBET enhancement behind every tag...the tag's type.

The 'App Tag', Part Deux

Tag-based development isn't unique to TIBET. Where TIBET differs from other tag-based systems is that in TIBET all tags, even built-in tags, have types associated with them.

When TIBET renders the content of home.xhtml it detects the existence of our <hello:app/> tag and looks for an associated type to determine how to proceed.

As a convention-driven system TIBET uses strict naming conventions to map tags to types. For <hello:app/> convention dictates a type name of APP.hello.app.

Application-specific resources use a root JavaScript namespace of `APP` in TIBET. Library-based resources are rooted on the `TP` namespace.

By default all tags are found in the ~app_tags directory under their respective type name bundle. In the case of our <hello:app/> tag the type's source code is therefore in ~app_tags/APP.hello.app/APP.hello.app.js:

/**
 * @type {APP.hello.app}
 * @synopsis The root application tag for the application. This type's template
 *     is responsible for the content you see while its methods are responsible
 *     for handling events which reach the application tag (this type).
 */

TP.core.TemplatedTag.defineSubtype('APP.hello:app');
APP.hello.app.js


The single line of executable code here makes use of TIBET's defineSubtype method, creating our tag as a subtype of TP.core.TemplatedTag. As you may guess, the TemplatedTag in that name is why hello:app renders via a template.

Additional naming conventions in TIBET dictate that unless we map our tag's template file to another location the content should be in ~app_tags/APP.hello.app/APP.hello.app.xhtml so editing that file automatically results in new content being rendered.

Recap

With three commands and one line of markup we've created a full-stack application and updated it to display Hello World!, appropriate effort for something this simple.

We could stop here, but instead we'll move on to refactoring our Hello World! content into a reusable component. After all, TIBET was built not only to build applications, but to help you build reusable component libraries you can share across enterprise projects.


Tag Refactoring

Refactoring


Now that we've seen both a tag template and a tag type let's refactor our Hello World! <h1/> into a reusable component, one we can add to our corporate tag library.

hello:world

We're going to create a new custom tag, a <hello:world/> tag, which will render 'Hello World!' anywhere we use it, then leverage that from our app tag.

Create a templated tag with the tibet type --dna templatedtag command:

$ tibet type hello:world --dna templatedtag

Running this command within our project will create a new tag type, a template, and a test file. Note that due to live patching our new hello:world tag type and its attendant template and test stub will immediately be live patched into our running application.

To get our new tag to render the desired content we want to edit its newly-created template file ~app_tags/APP.hello.world/APP.hello.world.xhtml to contain our target text.

Edit the tag's template ~app_tags/APP.hello.world/APP.hello.world.xhtml to contain:

<h1 tibet:tag="hello:world">Hello World!</h1>
APP.hello.world.xhtml


Note this is almost identical to our earlier edits for the hello:app tag but we've set the tibet:tag attribute to point to our hello:world type as the backing type for this tag.

Hey...let's test!

Change to your terminal where you're running TIBET tests and enter tibet test at the command line:

$ tibet test
# Loading TIBET via PhantomJS 2.1.1 at July 15, 2017 at 16:05:16 MDT
# TIBET loaded in 4165 ms. Starting execution.
# TIBET starting test run
# 3 suite(s) found.
1..4
#
# tibet test APP --suite='APP suite'
ok - Has a namespace.
ok - Has an application type.
# pass: 2 total, 2 pass, 0 fail, 0 error, 0 skip, 0 todo, 0 only.
#
# tibet test APP.hello.app.Type --suite='APP.hello:app suite'
ok - Is a templated tag.
# pass: 1 total, 1 pass, 0 fail, 0 error, 0 skip, 0 todo, 0 only.
#
# tibet test APP.hello.world.Type --suite='APP.hello:world suite'
ok - Is a TP.core.TemplatedTag tag.
# pass: 1 total, 1 pass, 0 fail, 0 error, 0 skip, 0 todo, 0 only.
#
# PASS: 4 total, 4 pass, 0 fail, 0 error, 0 skip, 0 todo, 0 only.

# Finished in 4357 ms w/TSH exec time of 192 ms.

As we can see, there's a 4th test suite now, the APP.hello:world suite, thanks to the tibet type command. So far so good.

hello:app

Once we have our <hello:world/> tag ready we can change our <hello:app/> template ~app_tags/APP.hello.app/APP.hello.app.xhtml and tell it to render our new custom tag instead of hard-coded content.

In the example below we use more than one, just for fun :).

Edit the app tag template APP.hello.app.xhtml to use our new tag:

<div tibet:tag="hello:app">
    <hello:world/>
    <hello:world/>
    <hello:world/>
    <hello:world/>
    <hello:world/>
</div>
APP.hello.app.xhtml


Save your changes and you should again see Hello World!...a lot :).

hello:world tags

Hello World!!!!!


With that simple change we can already start to see the real power of TIBET's implementation of tag-based programming...

A small team of coders producing reusable tags for your enterprise can support a much larger team building applications using those tags and far less JavaScript code.

In fact, we have yet to write a single line of JavaScript code....

Recap

Using the tibet type command (with a --dna templatedtag option) we created a new custom tag. We then updated that reusable component to produce Hello World!, then used our new reusable tag within our application's main tag template to display Hello World! multiple times.

Imagine doing the same sequence with a common application header, a common footer, navigation, menus, etc. and you start to glimpse the real power of TIBET's tag system in modularizing the development process.


Tag Styling

Tag Styling


With our new hello:world tag up and running the next question is how do we style that tag?

Tag CSS

For larger applications keeping all the rules in one file isn't considered best practice.

A better approach would be to keep common rules in app.css but factor tag-specific styling into separate files for easy maintenance, rolling them all up for production.

As it turns out, when you use the tibet tag command TIBET automatically creates a style sheet to go with each tag, meaning our hello:world tag has a style sheet we can use.

Default CSS

Let's take a look at the default style sheet created for our hello:world tag:

Open ~app_tags/APP.hello.world/APP.hello.world.css in your favorite editor:

/**
 * @overview 'APP.hello.world' styles.
 */

@namespace tibet url(http://www.technicalpursuit.com/1999/tibet);
@namespace hello url(urn:tibet:hello);

/**
 * If your template/compile process transforms <hello:app/> tags
 * from namespaced XML into XHTML with a tibet:tag attribute so they render in
 * the page similar to <div tibet:tag="hello:app"/> place your
 * style in rules with the following root form:
 */
*[tibet|tag="hello:world"] {
    /* style here for xhtml converted tags */
}

/**
 * If you don't transform from XML form (tags in the page remain in their
 * <hello:app/> form) comment out the prior block and use rules
 * with the following root form:
 */
hello|world {
}
APP.hello.world.css


If you haven't used CSS with XML this may look a little foreign. Don't panic, it's mostly comments :).

Lines 1-2
@namespace tibet url(http://www.technicalpursuit.com/1999/tibet);
@namespace hello url(urn:tibet:hello);

The first two lines of code declare the tibet and hello namespaces that are referenced in the rules that apply to our tag, one in the tag name and one in an attribute.

Lines 3-4
*[tibet|tag="hello:world"] {
}

If your tag replaces XML (hello:app) with a native XHTML element (h1) you can use this form, which relies on the tibet:tag attribute. Note however, any : in an attribute name must be replaced with a vertical bar | when styling XML in CSS hence the tibet|tag value in the selector.

Lines 5-6
hello|world {
}

If your custom tag doesn't convert from its original XML form but instead is going to be styled as XML you'll rely on rules of this form. Again, because : is special in CSS when you deal with XML namespaces you have to replace the : with a vertical bar |.

Simplified CSS

Since our hello:world tag becomes an XHTML h1 we can simplify quite a bit.

Edit ~app_tags/APP.hello.world/APP.hello.world.css file to contain:

/**
 * @overview 'APP.hello.world' styles.
 */

@namespace tibet url(http://www.technicalpursuit.com/1999/tibet);

*[tibet|tag="hello:world"] {
    color: green;
}
APP.hello.world.css


Save this set of changes and our UI should now appear as:

hello:world style sheet

Congratulations! You've completed Hello World! TIBET-style.


Summary

Summary


This quickstart guide has focused on a central aspect of TIBET development, namely creating, refining, and combining custom tags to create reusable components with a minimum of code.

First we created a project using tibet clone and tibet init. Then we started the optional TIBET Data Server (TDS) using tibet start to support development.

With our project in place we altered our application tag template, first to output 'Hello World!', then to make use of a custom hello:world tag for that purpose. We then styled our tag and watched it update without reloads.

There's a lot more to TIBET but we've already touched on some of the primary ways TIBET development differs from working with a typical JavaScript framework:

  • a heavy emphasis on developing reusable components in markup,
  • leverage of core web standards for all aspects of authoring,
  • a strong focus on testing everything from units to UI,
  • a dramatic reduction in boilerplate code, and
  • elimination of compiler and reload delays.

If you'd like to continue your exploration of TIBET check out the TIBET Essentials Guide, which expands on our hello project.


The Pup

Contact us for more information or to discuss how we can assist you.