Moka is a damn simple framework designed to build static websites like portfolios, showcases, minisites, HTML mockups, etc. Moka setup takes a single command, and it provides you with a hierarchical template system and some super-convenient helper methods so you never have to write more code than necessary. The result of your work is compiled to plain HTML, CSS and Javascript: you just need to upload it to your server to deploy it. Add as a bonus the Lipsum helpers, with which you can generate dummy text with a single line of code during development or in HTML mockups.
Moka values:
-
Don’t Repeat Yourself
-
Convention Over Configuration
-
Learn it in 10 minutes, set it up with a single command, start your creative work immediately
-
Compile everything into plain HTML and CSS code, working on virtually any possible webserver
Install the gem:
sudo gem install moka
Moka is really simple and straightforward, but it is intended for developers and people who already know how to code in HTML and CSS. Since Moka uses Ruby language, some knowledge of it is probably needed before getting started. For Ruby on Rails developers, using Moka should be extremely simple, since Moka uses erb (or haml) and many helper methods that work nearly the same way as in Rails.
You can create a new Moka project with just one command. Simply open the command line, navigate to your development directory and type:
moka new site your_site_name
You need to replace ‘your_site_name’ with the actual name of your project.
By the time this command executes, you’ll see that a new directory named ‘your_site_name’ (or whatever you choose as the name of your project) was created. Into this directory you will see a file named manifest.yml, which describes the structure of your new site and gets updated automatically as you create new pages and groups. Apart from this file, you will find three directories:
-
compiled - here is where your project will be compiled to a pure HTML website, and where static assets like images, javascripts and stylesheets should be placed.
-
project - your development directory, where you will create all the pieces that Moka will put together to compile your project into a working website: partials, variables, groups and pages (keep reading and this will get much clearer)
-
script - this directory contains files needed by Moka in order to work properly. Usually you won’t need to edit them.
Adding pages to your project is really simple, but first you need to understand the way Moka is organized. In Moka we have the concepts of site, groups and pages. Basically, every page belongs to a group, and every group belongs to the site. It’s like a tree: the site is the trunk, groups are branches and pages are leaves (for this reason we call this structure the sitetree).
This structure helps you avoid duplication and write less code: if some pages share some common elements, such as layout or pieces of code, they should belong to the same group. This way, you will need to code the common elements just once, at the group level, and all the pages in that group will use them. In the same way, if some elements are common to all the pages in your website, you should code them at the site level, so they will be available to every page in every group.
Groups also determine the location in which pages will be compiled. In particular, a page named ‘hello’ belonging to a group named ‘greetings’ will be compiled by default in /greetings/hello.html into the compiled directory. This rule is always valid, apart from the default group, which is named ‘root’ and gets compiled in the root directory. In other words, if you create a new page named ‘welcome’ without specifying the group it belongs to, it will belong by default to the group ‘root’, and will be compiled in /welcome.html (and NOT in /root/welcome.html).
So, let’s get more practical and create the first page in our project. In the command line, navigate to your new project directory and type:
moka new page index
Bazinga! You just created a new page named ‘index’ and belonging to the group ‘root’. Want to see it? You can have a look at it in your browser, but since this page is not yet compiled, you first need to start the development server. Again, type in your command line:
moka server
Now, as soon as the WEBrick server starts, you can open your browser, go to localhost:3333/index.html and see the page you just created. The development server is a very useful tool, since it shows you a preview of your work without having to re-compile the whole site after each change. Still, keep in mind that it is quite slow and only intended for development: before publishing your website you will have to compile it into HTML and CSS code.
In the previous example, we didn’t specify a group, so Moka created the page named ‘index’ in the default group, a.k.a. ‘root’. In order to create a new page named my_page in a group named my_group you would have instead to type in the command line:
moka new page my_group:my_page
Now that you created your first page, you probably want to edit its layout and content to suit your needs. It is then time to open the text editor of your choice and start coding.
But what files do you need to create/edit? When you create a page using the new page command, Moka creates into the project/site directory a new directory named as the group your page belongs to (‘root’ if you didn’t specify it), and into that it creates another directory named as the page. Also, it updates the manifest.yml file with the info about the new group and page. Note that the directories are structured as a tree (the sitetree, again): the site directory contains the group directories, and each of these group directories contains the directories of pages belonging to that group.
Moka is all about placing pieces of code in the right directory, as where you place your file determines how these files are used to compose your pages.
Think of pages in a Moka project as jigsaw puzzles: every page is composed of various pieces, and Moka uses its conventions in order to select the right pieces when assembling the puzzle. When Moka compiles a page, first of all it looks for a file named layout.erb (or .haml) which defines the basic HTML layout and structure of the page. Moka looks for this file first in the page directory (project/site/root/index in the case of our first page). If it can’t find it there, it looks into the group directory (project/site/root), and then, if there is no layout file in the group directory, it looks for it in the site directory (project/site).
Apart from defining the basic HTML structure of a page, the layout file may request one or more partials (through the Ruby method partial(:partial_name) ). Partials are erb (or haml) files too, and define parts of the HTML code of a page. In our analogy, they are the pieces of the puzzle. As it does with the layout file, Moka looks for each partial first in the page directory, than in the group directory, and finally, if all else failed, in the site directory.
In your layout or partials, you can also use some variables, that you define in a file named variables.yml. Again, Moka decides the value of each variable looking for its definition in a variables.yml file first in the page directory, then in the group directory and finally in the site directory until it finds it.
Now the advantage you get from this hierarchical structure provided by Moka should be clear: you place all the page-specific elements in the appropriate page directory, the elements that are used by multiple pages in the same group in the group directory, and all the elements that are used all over the site in the site directory. Basically, the directory where you put an element determines its scope: Moka always assembles your pages choosing the most specific version of an element (being it a layout, partial or variable). This means that you never have to write duplicated code.
As mentioned before, in your layout and partials you have access to some instance variables. These are @site, @current_group and @current_page. As the names suggest, these variables point to the current page, group and site in the sitetree. The same layout or partial may be used by many different pages, but when you compile your project, the @current_page (@current_group) variable will always be referencing the right page (group) being compiled.
You can navigate through the sitetree:
@site.groups # Returns an Array of all groups @current_group.pages # Returns an Array of all pages in the current group @current_page.group # Returns an object referencing the group to which @current_page belongs. Same as @current_group @site.mygroup.mypage # Returns an object referencing the page 'mypage' in group 'mygroup' @site.find_group('mygroup').find_page('mypage') # Same as above, but the strings passed as arguments to the find_* methods may be variables # declared somewhere else in your code
You can cycle through nodes:
<% @current_group.pages.each do |page| %> # do something with each page <% end %>
Nodes in the sitetree (site, groups and pages) let you access the variables defined in the variables.yml files. Thus, you can do something like:
@current_page.name # The name of the current page. 'index' in the case of our first example. @current_page.my_variable # Returns the most specific value of variable my_variable defined in a variables.yml file in the current page directory, # or in its group directory, or in the site directory.
Sitetree nodes provide you with a way to use page-specific or group-specific variables in your code. Making good use of sitetree variables lets you write less code and makes your design more robust. An example is when you code navigation menus:
<ul> <% @current_group.pages.each do |page| %> <li><%= link_to(page.name.titleize, page) %></li> <% end %> </ul>
Creating the menu in this way is not only incredibly fast, but also robust to changes: should you add new pages to the group or delete some existing pages, you don’t need to rewrite the navigation menu, as it adapts to your changes.
Moka provides you with a bunch of super useful helper methods that you can use in your layouts and partials. Some of these helpers are link_to, path_to, image_tag, include_javascript_tag, stylesheet_link_tag and many others (Rails developers, do some of these methods sound familiar?). Read the docs and find out how these methods can help you making your code extremely efficient.
You have also among your weapons the convenient Lipsum class, with which you can generate dummy text at the speed of light:
Lipsum.paragraphs 4 # Generate four paragraphs of dummy text, enclosed by <p> tags Lipsum.sentences 3 # Generate three sentences of dummy text Lipsum.words 10 # Generate 10 words of dummy text
All these Lipsum methods can also be passed a block:
<ul> <% Lipsum.sentences(7) do |sentence| %> <li><%= sentence %></li> <% end %> </ul>
Need even more kung fu? Then you can code your own helper methods. Just code your methods into project/lib/helpers.rb and you will be able to use them in your layout and partials.
You are probably wondering now “OK, but what about CSS?”. Well, you can code your CSS inline, or place CSS files into the compiled/stylesheets directory and import them in your HTML. Alternatively, if you are a fan of the awesome SASS syntax, you can write SASS or SCSS files into the project/styles directory, and they will be magically compiled into CSS stylesheets into compile/stylesheets.
When you are done coding your pages (which, thanks to Moka awesomeness, will look clean and simple like haiku poetry) you are ready to release your website. It is as simple as typing:
moka compile
Moka will compile all your project code into pure HTML and CSS into the compiled directory. In order to publish your new website you just have to upload the content of the compiled directory on your server. It’s so simple, and it just work!
Try typing in the command line something like:
moka new site --template=another/project/path # Create a new moka project using another one as a template moka new group [--template=another_group] # Create a new group [using an existing one as a template] moka new page my_group:my_page -v title:"My Page Title" other_variable:"Moka Rocks!" # Create a page named my_page in group my_group and define its variables title (with value "My Page Title") # and other_variable (with value "Moka Rocks!") writing into the project/site/my_group/my_page/variables.yml file moka inspect site # Show groups and variables defined at the site level moka inspect group my_group # Show pages and variables defined at the level of group my_group moka inspect page my_group:my_page # Show variables defined at the level of page my_page in group my_group