Valaa Tutorial: Hello, World!

Simple tab-based mobile app template with 12 lines of code.

Ville Topias Ilkkala
valaa.log
5 min readJan 23, 2018

--

One of the most productive features of Valaa is the way it allows data structures to be drafted with a graphical user interface and then rendered using very little code. This significantly reduces the likelihood of bugs and gives a visual overview of the application structure.

In this tutorial we will be building a very simple tab-based mobile app template using just 12 lines of code.

The outcome of the tutorial with some placeholder content.

The Building Blocks

In order for this tutorial to make any sense, we need to briefly address the building blocks of Valaa applications.

For this tutorial we need to know about four different Valaa primitives: Entities, Relations, Properties and Medias. Entities and Relations are capable of containing other Entities and Relations, as well as Medias. Properties are custom-created fields holding user-defined values that can be added to other primitives.

Entities

Entity is a thing. It behaves like a class, object and a file folder. It can have multiple user interfaces (or Lenses, see below) for different use cases. It can also be instanced, a topic we will cover in a future tutorial.

Properties

Properties always have a name. They can hold either a literal value (e.g “John”, 42 or true) or point to some other Valaa resource, such as an Entity or a script file. When a property shares the same name as the resource it points to, we call it an accessor property.

Relations

Relations share all the same qualities as Entities, but in addition a Relation can have a target to describe a relationship between two things. Valaa Relation can contain a lot of data and functionality to describe and modify the relationship it defines. In this tutorial we use Relations to list the different tabs of our app and store the desired order that they appear in the menu as a property in each Relation.

Medias

Medias are essentially files, most used ones being ValaaScript files (.vs) and VSX files (.vsx). Also external JavaScript libraries, images, sounds and stylesheets are Medias.

Lenses

Lenses are a way of defining user interfaces in Valaa. A Lens is described in a VSX file (JSX for Valaa) and is accessed through a property pointing to it. The Lens property can be named anything, but Valaa can access those named LENS with capital letters by default. A Lens pointer can also point to an Entity or Relation, in which case the default Lens of the target is rendered instead.

ValaaScript

ValaaScript is a extension of JavaScript designed for manipulating the Valaa data structures. It currently supports ECMAScript 5 standard with ECMAScript 6 support coming soon. In our tutorial we only use ValaaScript inline within our VSX files, but larger code blocks can be placed to their own medias named with .vs file extension.

Application Structure

Now that we have covered the basic building blocks of Valaa, we can start assembling our application structure visually using the Valaa IDE.

Each page in our application — accessed via the tabs in the menu at the bottom of the screen — is going to be its own Entity. Inside each of these we will have a LENS property pointing to a simple VSX file with our page contents. Each page is targeted with a Relation called page from our project root. These Relations will hold a property called order for ordering the menu tabs.

In our project root we will have two files: app.vsx for the layout and styles.css for styling. The LENS property is created to our project root as well and set to point to the app.vsx file. Styles.css will have an accessor property.

I manually create three pages: Blog, About and Contact and for them the three Relations — all named page — and set on each Relation an order property, numbering them from 0 to 2.

Finally we need to add a property called currentPage to our project root. We will set this to point to the currently active page later.

Finished data structure for our application. Gray is for Entities, blue for Properties, yellow for Relations and pink for Medias.

The 12 lines of code

We have now assembled our project structure without writing a single line of code. The whole application logic will be contained in the app.vsx file. And this is all we really need to write there:

Please note, that the file extension in Gist is incorrectly .jsx to get automated syntax highlighting. For VSX files the correct file extension is .vsx.

Let’s look at this line by line:

<div className={VSS(focus.styles, "app")}>

Here we wrap our user interface into a <div> element and apply styling through the accessor property of our styles.css file. We fetch the class app from the stylesheet. You can access the whole stylesheet here, as we are not addressing application styling in detail in this tutorial.

{focus.currentPage}

We then render the default Lens from the target of our currentPage pointer. You can also manually set the pointer to any of the three created Entities for our pages to see results even before we add functionality to our user interface.

<ul className="menu">

Our menu is built from a standard HTML list. We wrap it to <ul> element.

<ForEach context={{origin: focus}}
focus={focus[Relatable.getRelations]("page")
.sort( (a, b) => a.order - b.order)}>

Here is where it gets interesting: we have created our own implementation of JSX-Control-Statements to work together with Valaa content, one being the <ForEach>. It will loop through a list of Valaa elements — in this case Relations with the name “page” — and renders a block of HTML with new content on each iteration. <ForEach> can be given a context (data that will remain the same during all iterations) and a focus — the source of the list that is being iterated. We use focus[Relatable.getRelations](“page”) to fetch a list of Relations by the name “page” from the current Entity (our project root) and sort them according to their order-property.

<li className={
origin.currentPage === focus[Relation.target] ? "current" : null
}

Here we use a ternary operator to check if the property currentPage (in origin, as it is the same on each iteration) points to the target of our relation. If it does, we add a class “current” to the list element for styling purposes.

onClick={() => origin.currentPage = focus[Relation.target]}

Here we add an onClick function to each list element that sets the currentPage to the target of the Relation.

{focus[Relation.target][Valaa.name]}

Finally, we render the name of the Entity our Relation is targeting.

And that’s (almost) it.

Each of the VSX files inside our page-Entities should contain something. You can see the name of the page by simply writing the following to the each page:

<div className="content">
<h1>{focus[Valaa.name]}</h1>
</div>

Here we simply fetch the name of the Entity of each page.

Currently our application has one downside (or upside — depending on what you want to achieve) to it: the state of our user interface is global and shared with everyone. One user changing the page will change it for everyone else, too. In the next tutorial we will cover local instancing, one of the easiest methods for achieving independent UI state for different users.

--

--

Ville Topias Ilkkala
valaa.log

I work with companies, universities, research groups, nonprofits and foundations towards a digitally transformed society. I’m the co-founder and CTO of Valaa.