GUIDES


First steps

Installation

In order for you to have Wizardo CLI available in your computer, you need to have node installed in your system in a version equal or greater than v6.0.0. To install node here is the link.
You can install Wizardo through npm as following:

$ npm install -g wizardo

This will install Wizardo CLI globally in your system.
You can see Wizardo's options by executing $ wizardo --help

$ wizardo --help
   Usage: wizardo [options] [command]

   Options:
     -v, --version       output the version number
     -h, --help          output usage information

   Commands:
     init                create the initial boilerplate for wizardo generator
     create <generator>  create a new generator into .wizardo/<generator>.config.json
     run <generator>     run generator given .wizardo/<generator>.config.json
     list|ls             list all available generators
     *                   not a command

Wizardo init

Wizardo is intended to be used for particular projects. So you might want configure it in different ways according to your needs.
For that reason, Wizardo offers a command that adds a folder called .wizardo in the root of your project in which you can dump all the configuration needed.
To execute the command you need to run:

$ wizardo init 

As a result of this command, the root of your project will have a .wizardo folder with a templates folder inside of it.

A project with generators would look like the following:

 app/
  ├ .wizardo/
  │ ├─ sample_generator.config.json
  │ └─ templates/
  │    └─ sample_template.js
  └ other_files/ 

The content of a .wizardo folder is made out of two parts: generators config files and templates. Later in this guide, we will go in depth on each of the previous topics. But as a highlevel explanation, <generators>.config.json files, describe the steps your generators will execute and templates folder contain all the templates used by the config files.

Should I commit this folder in git?

Yes.
Specially if you want your generators to be available to other developers in your project.
Actually Wizardo works tighly coupled with git and you cannot run a generator without have it commited in your repo.

I can't find .wizardo folder in my file explorer

Most of file explorers hide folders and files starting with . and that is the reason why we create wizardo's configuration folder starting with dot. The root of your project shouldn't be contaminated with configuration files. Anyways, you might want to use the folder.
Most of file explorers offer the option to Show Hidden Files when you rightClick in the root of your project and you can do it the same way with your text editor.
In the terminal, you might run $ ls -a to show all, even hidden files, available in the current path.

Generators

In this section we are going to go through different aspects of a generator using a simple example. We will create a plain html based website using Wizardo.

1. Setup

To start with this example, create a folder website/ to hold our project. cd into our folder and execute $ wizardo init

 ~$ mkdir website
 ~$ cd website
 ~/website$ wizardo init
 ~/website$ ls -a
 .  ..  .wizardo 

Next, we will insert an index page in the root of our website

 ~/website$ touch index.html

Copy the following html template inside index.html using your favorite text editor:

 <!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="UTF-8">
     <title>index</title>
   </head>
   <body>
     My website
   </body>
 </html> 

2. Create command

Now we will execute the create command that will add into our .wizardo folder a config file for our new generator.

Lets say that we want a generator to create new pages into our website. So lets run the command by:

 ~/website$ wizardo create page_generator

This command will add page_generator.config.json into our .wizardo/ folder with the following json:

{
  "generator": "page_generator",
  "templates": [
    {
      "source_template": "<%=example.js=%>",
      "destination": "path/to/<%=destination=%>"
    }
  ],
  "modifiers": [
    {
      "path_to_file": "path/to/existing/existing_file.js",
      "regex": "Hello World ___view___\n",
      "text_to_insert": "Just matched with `___view___`\n"
    }
  ]
}

The config file contain 3 main sections, that are generator with the name of our generator, templates and modifiers that we are going to discuss in the following sections templates and modifiers.

3. List command

The existance of page_generator.config.json file, tells Wizardo that we have a generator under the name page_generator.

To verify so, we can run the list command to list all the available generators in our project.

 ~/website$ wizardo ls
    - page_generator 

Templates

Templates in Wizardo are the way of creating new files in your project, based on existing ones. In this section, we will go on with our tutorial by creating a template and reviewing the related parts

1. Templates folder

.wizardo/ folder has a folder called templates/ in which we need to place our templates.
This is the place where Wizardo looks for templates. So lets go and copy our index.html into that location by:

 ~/website$ cp index.html .wizardo/templates/
 ~/website$ ls .wizardo/templates/
   index.html 

2. Templates structure in config file

Great, now that we have a template in .wizardo/templates/ we need to let know our generator (page_generator.config.json) that whenever it runs, we are going to create a new file based on our template

The content of templates key of the configuration file for a generator is really simple. It contains an array of sources and destinations. The source_template key indicates the name of our template inside the templates/ folder, and the destination key, is the path in which is going to reside the file that wizardo will generate.

Lets say that in our website we will have folder pages/ to hold all of our pages. So lets go and modify page_generator.config.json to indicate our intention:

{
  "generator": "page_generator",
  "templates": [
    {
      "source_template": "index.html",
      "destination": "pages"
    }
  ],
  "modifiers": []
}

Note that we removed the content of modifiers key. Later on this guide we will go on to this part, but for now, just the array empty so we can see wizardo in action.

3. Run generator to test templates

To run the page_generator execute:

 ~/website$ wizardo run page_generator
 Wizardo: run page_generator
   - Wizardo is tightly coupled with git.
     It seems that you dont have a git repo initialized in this directory.
   + Create a git repo and commit all your changes before running a generator

As the error messages says, wizardo rely on git to execute the rollbacks. So first we need to create a git repo and commit our changes

 ~/website$ git init
 ~/website$ git add .
 ~/website$ git commit -m "Initialize wizardo"

Once we have that down, we can proceed to try running the page_generator again.

 ~/website$ wizardo run page_generator
 Wizardo: run page_generator
   create: pages
 Wizardo: run page_generator - DONE!
   create: pages/index.html

Note that wizardo created the pages/ folder for us and it also created a copy of the index.html from our templates.

 website/
  ├ .wizardo/
  │ ├─ page_generator.config.json
  │ └─ templates/
  │    └─ index.html
  ├ pages/
  │ └─ index.html
  └ index.html 

Cool! Now that we learned how to generate files given a template, in the following section we will learn how to add some dynamism to our templates so we can generate files with names other than index.html 👍

Variables

Variables are words that follow a special pattern that will be replaced with a given input at run time.

1. Variables types

Wizardo has three types of identifiers for variables:
___var_name___, which is the most common used. It is given by three underscores followed by the variable name in snake_case and ending with other three underscores.
___VarName___, which is used similar to the previous one but uses PascalCase. This allow to use the same variables but print them in the generated files using PascalCase.
<%=var_name=%>, composed with <%= followed by the variable name in snake_case and ending with =%>. This option is available to be used in the same line as one of the previous types.
We will see an example each of the previous variable types in the following steps of this section

2. Variables in config file

Wizardo takes variables found in the config file and prompt for their values, so at run time they are replaced with their corresponding values.

It makes sense in our example that generate pages with other names, such as about, products or FAQ.

So lets modify the page_generator.config.json file to allow dynamic page names

{
  "generator": "page_generator",
  "templates": [
    {
      "source_template": "___page_name___.html",
      "destination": "pages"
    }
  ],
  "modifiers": []
}

This will cause the generator to fail if we run wizardo, because ___page_name___.html does not exist in the templates.
To fix this, lets change index.html name from the templates/ folder to ___page_name___.html

 ~/website$ mv .wizardo/templates/index.html .wizardo/templates/___page_name___.html

3. Run the generator

Let see how wizardo prompts for page_name variables. Remember that in order to run a Wizardo generator, you need to have all the changes commited first.

 ~/website$ git add .
 ~/website$ git commit -m "Modify source_template to take a variable"
                       -m "and created another index page in pages"

 ~/website$ wizardo run page_generator
 Wizardo: run page_generator
   Enter the value for the following variables in your config file
    page_name: products <-------- Insert the new page name here!

Insert products when asked for and hit Enter. You will receive the following message:

 Wizardo: run page_generator - DONE!
  create: pages/products.html 

And you can check the file creation in your file system. It should look something like the following:

 website/
   ├ .wizardo/
   │ ├─ page_generator.config.json
   │ └─ templates/
   │    └─ ___page_name___.html
   ├ pages/
   │ ├─ products.html
   │ └─ index.html
   └ index.html 

4. Variables in templates

You can also add variables inside templates, so everytime you generate a new view based on a template, it is not just a copy, but a customized new file.

To demonstrate this, go to ___page_name___.html and modify the content with the following:

 <!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="UTF-8">
     <title>___page_name___</title>
   </head>
   <body>
     ___PageName___
   </body>
 </html> 

Note that we are inserting the variable ___page_name___ two time. One in snake_case notation and another one in PascalCase notation.

An important point with variables in wizardo is that you should declare its content in snake_case only, and it will transform them into PascalCase if needed.

Lets run the generator again, this time use about_us as value the of ___page_name___ so we can see the PascalCase transformation in action. (Remember to commit the changes before running a generator).

 ~/website$ wizardo run page_generator
 Wizardo: run page_generator

 Enter the value for the following variables in your config file
   page_name: about_us
 Wizardo: run page_generator - DONE!
   create: pages/about_us.html 

Great. Now lets take a look to pages/about_us.html file

 <!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="UTF-8">
     <title>about_us</title>
   </head>
   <body>
     AboutUs
   </body>
 </html> 

5. Limitations and workaround

At the moment wizardo look for variables only in the config file, if the variable to be replaced exists in a template but not in the generator's config file, wizardo won't prompt for that variable and you will probably end up with an un-replaced variable in the final file.
This is a limitation that the team has in mind and we are planning to improve it in future releases.

A workaround to this, is add an extra key variables with an array of variables to the generator's config file. As the following:

{
  "generator": "page_generator",
  "templates": [
    {
      "source_template": "___page_name___.html",
      "destination": "pages"
    }
  ],
  "modifiers": [],
  "variables": [
    "___these_variables___",
    "___exist_only_in___",
    "___template_files___"
  ]
}

This workaround tells wizardo to ask for these variables and to use the values given at runtime.

Modifiers

Modifiers are the way of looking for a pattern in existing files and adding new content to them.
They work with Regular Expressions so if you are unfamiliar with those, we recommend you to go take a look at them in regexone.com or the resource of your choice.

1. Modifiers structure

The content of modifiers key in the configuration file is made of an array of path_to_file, regex and text_to_insert.

- path_to_file indicates the path from the root of the project to the file that the modifier is going to work on.
- regex is the regular expression that will be found in the the given file and will be used to insert after it. A way of validation the patterns created is to use regex101.com in javascript mode.
- text_to_insert is what is going to be inserted after the match in the regex.

Note that at the moment, modifiers don't respect identation, so text_to_insert needs take that into consideration.

2. Use modifiers

Following with the tutorial, lets create a navbar into the index.html of root, so whenever we add a new page with the page_generator, the modifier adds the corresponding route to the navbar.

First, modify index.html to match the following code. We are basically adding a navbar with routes to each of the files we have created so far.


<!DOCTYPE html>
<html lang="en">
 <head>
   <meta charset="UTF-8">
   <title>index</title>
   <style>
     body { padding: 0; margin: 0; }
     nav { background: #efefef; padding: 15px 50px; }
     nav a { color: black; padding: 10px 15px; }
   </style>
 </head>
 <body>
   <nav>
      <a href="pages/about_us.html"> AboutUs </a>
      <a href="pages/index.html">    Index   </a>
      <a href="pages/products.html"> Products</a>
    </nav>
  My website
  </body>
  </html>

Our modifier is going to insert an anchor for the new page right after the <nav> tag.
Modify the page_generator.config.json file to include the following modifier:

{
  "generator": "page_generator",
  "templates": [
    {
      "source_template": "___page_name___.html",
      "destination": "pages"
    }
  ],
  "modifiers": [
     {
       "path_to_file": "index.html",
       "regex": "<nav>\n",
       "text_to_insert": "     <a href=\"pages/<%=page_name=%>.html\">___PageName___</a>\n"
     }
  ]
}

We are going to work in the "index.html" file of root using path_to_file

We are matching "<nav>\n" using regex.

And we are inserting the new anchor right after the match using text_to_insert.

Note that we are using variables in text_to_insert key. You can also use variables inside the regex and path_to_file keys.

3. Execute the modifier

To test the modifier we just need to run our page_generator.

 ~/website$ wizardo run page_generator
Wizardo: run page_generator

  Enter the value for the following variables in your config file
    page_name: faqs
Wizardo: run page_generator - DONE!
  create: pages/faqs.html
  modify: index.html 

As the last line of the response states, index.html was modified and now it contains an anchor to the recently created faqs.html page.

The index now looks like:


<!DOCTYPE html>
<html lang="en">
 <head>
   <meta charset="UTF-8">
   <title>index</title>
   <style>
     body { padding: 0; margin: 0; }
     nav { background: #efefef; padding: 15px 50px; }
     nav a { color: black; padding: 10px 15px; }
   </style>
 </head>
 <body>
   <nav>
      <a href="pages/faqs.html">Faqs</a>
      <a href="pages/about_us.html"> AboutUs </a>
      <a href="pages/index.html">    Index   </a>
      <a href="pages/products.html"> Products</a>
    </nav>
  My website
  </body>
  </html>

4. Don't modify files that you just created

Wizardo is currently built with the async file system api of node. So if you try writing to the same file in the modifiers and the templates, you could come across a couple WTFs.

If you need to do something like that, you can always create a new generator that leaves the templates empty, "templates": [], and run it manually after the one that create files with templates.