Star Script

Simplify Web Application Development

Managing HTML with Star Script

When you are creating a web site with multiple HTML pages, very often, those pages will share common sections such as header, footer, or some snippets. When you make a change to a common section, you will need to sync up multiple pages. You can do it manually. But it is boring and error prone. When the syncing requires small adjustments such as changing the page title or adjusting CSS includes, it quickly becomes annoying.

This post will introduce you a free, command line tool called Star Script. It allows you to split large HTML files into smaller and more manageable pieces like that of many other templating systems. What makes Star Script stand out, is its ability to define structured fragment. For example, if you define a HTML fragment for the ‘page’ structure, in Star Script, it can include both the openning <html> tag and the closing </html> tag. This approach is more robust and less error prone, compared with the approach of spliting the openning <html> tag and the closing </html> tag into two seperate templates. Further more, Star Script allows you to associate the structured HTML fragment with a custom tag. So you don’t need to learn a new syntax just to use a template. You use the same markup syntax as any other HTML element in your document. It makes your document looking cleaner and a lot more consistant.

Star Script is a flexible command line tool. It is very easy to integrate it into your existing work flow. You can render a single script at a time; or you can render all scripts under the same directory with a single command. Star Script can also run as a server, which allows you to modify the source and see the changes with a browser refresh.

In this post, I will first show you how it looks like when a HTML site is converted into Star Script. Then, I will go through the definitions of some of the tags. At the end of the post, you will find download links for all the sample Star Script source code and many other useful resources.

Example: Barista Site Template

The example I will use is a beautiful theme for cafes, bars and restaurants called Barista. Below is the screen shot of the theme:

The Barista template comes with 6 HTML files. There are large chunks of HTML code duplicated across the 6 files. You can get the existing HTML source by using the ‘View Source’ function of your browser.

Now, I have extracted the fragments and defined custom tags with Star Script. The pages are much cleaner. For example, the index.html page in Star Script becomes:

use share as s
<s.page ishome=true>
 <s.global_header/>
 <s.global_nav/>
 <s.home_banner/>
 <s.home_content/>
 <s.home_partner/>
 <s.global_prefooter/>
 <s.global_footer/>
</s.page>

As you can see each section of the page can be cleanly wrapped into corresponding tags as show in the below image:

Once you wrap up the sections, it is very easy for you to make page level adjustment. For example, if you want to disable the global_prefooter section, or home_partner section. It is a simple one line change. Adjusting orders of those sections is also very easy.

Star Script facilitates HTML code reuse. Custom tags can be used in more than one page. For example, the ‘page’ tag and ‘global_header’ tag are used for every page of the site. Now, if you make a change to the global_header, you just need to change one place and Star Script will pick up the change whenever it renders the global_header tag.

Now, let’s look at another page. The about.html page. Below is the Star Script version of the about.html page:

use share as s

<s.page>
 <s.global_header/>
 <s.global_nav/>

 <s.inner_content>
  <s.side_bar>
   <s.submenu>
    <entry href="#" label="Our History"/>
    <entry href="#" label="Our Shops"/>
    <entry href="#" label="Our Team"/>
   </s.submenu>
   <s.side_specials/>
   <s.side_cards/>
   <s.side_awards/>
  </s.side_bar>
  <s.about_article/>
  <s.about_people/>
 </s.inner_content>

 <s.global_prefooter/>
 <s.global_footer/>
</s.page>

The tag hierarchy maps nicely to the component hierarchy of the page.
On this page, not only the global header/footer are reusable. the side bar is also reusable. You can use the side bar component in other pages such as the ‘offer’ page or ‘gallery’ page.

The <page> Tag

Now, let’s see how the tags are defined. Let’s start with the ‘page’ tag. The ‘page’ tag is defined as:

func page(ishome as bool)
 <!DOCTYPE HTML>
 <html>
 <head>
  <meta charset="UTF-8">
  <title>Barista - Great People & Atmosphere</title>
  <link rel="stylesheet" href="http://coffeecream.eu/templates/barista/css/style.css">
  <link rel="stylesheet" href="http://coffeecream.eu/templates/barista/css/nivo-slider.css">
  <link rel="stylesheet" href="http://coffeecream.eu/templates/barista/css/prettyPhoto.css">
	
  <!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
  <script src="http://coffeecream.eu/templates/barista/js/jquery-1.7.1.min.js"></script>
  <script src="http://coffeecream.eu/templates/barista/js/jquery.nivo.slider.pack.js"></script>
  <script src="http://coffeecream.eu/templates/barista/js/jcarousellite_1.0.1.pack.js"></script>
  <script src="http://coffeecream.eu/templates/barista/js/jquery.prettyPhoto.js"></script>
  <script src="http://coffeecream.eu/templates/barista/js/cufon-yui.js"></script>
  <script src="http://coffeecream.eu/templates/barista/js/Bebas_400.font.js"></script>
  if ishome then
   <script src="http://coffeecream.eu/templates/barista/js/settings-home.js"></script>	
  else
   <script src="http://coffeecream.eu/templates/barista/js/settings-inner.js"></script>
  end
 </head>

 <body>
  <div id="wrapper">
   system.getContent()
  </div>
 </body>
 </html>
end

As you can see, majority of the ‘page’ tag definition is plain HTML code, except for a few red lines. It looks fairly clean. Star Script supports function, just like other programming languages. What’s new in Star Script is, function name can be used as tag name. When you make a call to a function using the ‘tag’ syntax, Star Script will pass the tag attributes to function as parameters. So the below code will call the ‘page’ function with ‘ishome’ parameter set to true.

  ...
  <g.page ishome=true>
    ...
  </g.page>
  ...

For ease of reference, let’s call the tag defined by a function as a ‘function based tag’. A function based tag can have attributes; it can also have children. The children of a function based tag won’t go directly to the output. Instead, it will be fed to the function based tag as an input. To access the children inside the ‘page’ function body, you will need to call a system function ‘system.getContent()’. This function will return a list of child nodes. The child nodes are not the original nodes such as the <global_header/> tag. Instead, it is fully rendered and expanded global_header HTML fragment. Star Script renders the child element before renders its parent.

Now, let’s try to give the ‘page’ tag a more verbal description. The ‘page’ tag will generate the basic page structure such as DOCTYPE, html, head, and body element. The ‘page’ tag will take a boolean attribute called ‘ishome’. Based on this attribute, it will generate slightly different script loading rule. The ‘page’ tag will also insert its children under the ‘wrapper’ div.

Below is a simple example showing how the ‘page’ tag works:

use share as s

<s.page ishome=true>
   Hello World!
</s.page>

will generate output

 <!DOCTYPE HTML>
 <html>
 <head>
  <meta charset="UTF-8">
  <title>Barista - Great People & Atmosphere</title>
  <link rel="stylesheet" href="http://coffeecream.eu/templates/barista/css/style.css">
  <link rel="stylesheet" href="http://coffeecream.eu/templates/barista/css/nivo-slider.css">
  <link rel="stylesheet" href="http://coffeecream.eu/templates/barista/css/prettyPhoto.css">
	
  <!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
  <script src="http://coffeecream.eu/templates/barista/js/jquery-1.7.1.min.js"></script>
  <script src="http://coffeecream.eu/templates/barista/js/jquery.nivo.slider.pack.js"></script>
  <script src="http://coffeecream.eu/templates/barista/js/jcarousellite_1.0.1.pack.js"></script>
  <script src="http://coffeecream.eu/templates/barista/js/jquery.prettyPhoto.js"></script>
  <script src="http://coffeecream.eu/templates/barista/js/cufon-yui.js"></script>
  <script src="http://coffeecream.eu/templates/barista/js/Bebas_400.font.js"></script>
  <script src="http://coffeecream.eu/templates/barista/js/settings-home.js"></script>
 </head>

 <body>
  <div id="wrapper">

   Hello World!

  </div>
 </body>
 </html>

To fully understand the ‘hello world’ example, let me explain a little bit about the first line ‘use share as s’. This line means, we want to use the script ‘share.ws’ and call it ‘s’ in the ‘hello world’ script. Inside the ‘share.ws’ script, there is a definition for the ‘page’ tag. The reference ‘s.page’ refers to the ‘page’ tag defined in the ‘share.ws’ script. If you define the ‘page’ tag in the same script as the ‘hello world’ script, you will not need the ‘use’ statement and the prefix ‘s.’. You can directly refer to it as ‘page’.

Using the page tag has some benefits. First, if you want to make a global change to the page title, for example, you just need to make change in one place, as oppose to 6 places. Second, you can control the output of the page element easily using tag attributes. For example, if you want to have different title for different page, you just need to add a new ‘page_title’ parameter to the page function and use it both in the function body and as a tag attribute on the page.

The <global_header> Tag

The global header tag is really simple:

func global_header()
 <header>
  <section id="logo">
   <a href="index.html"><img src="http://coffeecream.eu/templates/barista/images/logo.png" alt="" /></a>
  </section><!-- end logo -->
  <section id="social">
   <ul>
    <li class="facebook"><a href="http://www.facebook.com/pages/Coffeecream/144436855653915">Facebook</a></li>
    <li class="twitter"><a href="https://twitter.com/#!/coffeecreameu">Twitter</a></li>
    <li class="youtube"><a href="http://www.youtube.com/">Youtube</a></li>
    <li class="rss"><a href="#">RSS</a></li>
   </ul>
  </section><!-- end social -->		
 </header>
end

As you can see, it simply wraps up a piece of HTML. Nothing fancy here. I will skip most of the tag definitions in the ‘share.ws’ script, because they are very straightforward. Star Script follows one of the ‘Perl’ design philosophy – simple things should be simple; while complex things should be possible.

The <submenu> tag

In the “about.html’ page example, you may noticed a special tag called “submenu”. Below is the code snippet:

...
   <s.submenu>
    <entry href="#" label="Our History"/>
    <entry href="#" label="Our Shops"/>
    <entry href="#" label="Our Team"/>
   </s.submenu>
...

The source code for the submenu tag is:

class menu_entry
 var href as string
 var label as string 
end

class submenu extends component
 var entry as menu_entry[]

 func process()
   if entry == null then return end

   <section id="submenu">
    <ul>
     for i = 1 to entry.length
      <li><a href=entry[i].href>entry[i].label</a></li>
     next
    </ul>
   </section>    
 end
end

You may have noticed the keyword “class”. Yes, Star Script is a full-fledged object-oriented programming language. It supports class and inheritance. Further more, Star Script allows class to be used in tag format. In Star Script, any class can be used in tag format. The attributes of the tag will be used to construct an object instance. The child elements of a tag will also be processed. If the child element name matches a variable name or a method name, the corresponding variable will be assigned and the corresponding method will be called.

Regular class does not directly generate output. There is a special type of class which extends from the component class. For component class, you need to define a special ‘process’ method. The process method is the rendering method, much like the ‘page’ function body.

In the submenu example, the submenu class is a component class. It will generate HTML output such as <ul> and <li>. The menu_entry class is a regular class. It does not generate any direct output. Instead, it holds href and label value. When the user uses an <entry> element under the submenu element. The tag name ‘entry’ is matched against the variable name ‘entry’ defined on the submenu class. The type of the variable ‘entry’ – which is an array of menu_entry is looked up. The “href” and “label” attributes of the entry tag are assigned to the menu_entry object. The menu_entry object are then added to the entry array.

The above process is how Star Script binds a tag hierarchy to object instance. It sounds a little complicated. The concept is actually pretty simple. The submenu tag hierarchy are very close to the object hierarchy you would normally see in the variable inspector view of eclipse. Let’s look at a similar example in Java:

class submenu {
	menu_entry[] entry;
}

class menu_entry{
	String href;
	String label;	
}

If you create a submenu object, let’s call it ‘sub’. In the variable view of eclipse, you can see something like the below

As you can see, the tag hierarchy is very close to the object hierarchy.

The construction of the submenu object happens before the rendering method “process” is invoked. Therefore, inside the “process” method, you have the entire “entry” array ready for use. You can loop through the menu entries and generate proper HTML output.

Our submenu example will be rendered as the below HTML: (* formatting may be different)

  <section id="submenu">
    <ul>
      <li><a href="#">Our History</a></li>
      <li><a href="#">Our Shops</a></li>
      <li><a href="#">Our Team</a></li>
    </ul>
  </section>

Trying it Out

Ok, we have talked too much. It’s time for some actions. Below are some of the resources for interested readers:

  • Example Code : This zip file contains all the example Star Script source code used in this post. Please read the included README.txt file for instructions on how to run the example.
  • Star Script Compiler : Free command line compiler. Require Java 1.6 or above.
  • Star Script Site : contains tutorial and other materials
  • MyEzApp.com : entire site written in Star Script. You can try Star Script online without any download.
  • Barista Site Template : The Barista theme is a beautiful theme listed on the themeforest.net. Unfortunately, wordpress.com does not allow me to directly link to it. They will detect the themeforest.net URL and replace it with some warning messages. If you are interested in the theme, please search it on the themeforest web site using the keyword ‘Barista’.

Additional Notes

Before you try out the Star Script, there are a few notes that will make your experience much smoother.

First, when you are using inline JavaScript on your page, you may want to wrap the Java Script source code inside a comment block such as

<script>
 <!--
    // some inline JavaScript
 -->
</script>

This is because Star Script syntax such as function call or variable declaration are similar with JavaScript. If you don’t enclose the JavaScript source inside comment block, they may be mis-treated as Star Script logic.

Second, Star Script allows you to mix programming structure with text content. Extensive usage showing that, this approach is easier for beginner and makes the source code look cleaner. When you are writing an article, it is not very often for you to run into syntax conflict. In case there is conflict, you can put your text into double quoted string. The only exception is, when you want to display double quotes itself, you will need to use backslash(\) to escape it, such as \”

Final Words

This post shows a simple starting use case. Star Script is a lot more powerful than that. In future posts, I will discuss how to define JS/CSS dependencies for your component and how to automatically generate optimal JS/CSS load rules on the page. So, when you add a component to a page, all the required JS/CSS rules are automatically added. When you remove a component from a page, the redundent rules will be automatically removed. Stay tuned.

Thanks for your time!

* Special thanks to Mr. Marcin Banaszek for allowing me to use his Barista theme in the post. If you are already a Barista user and want to get the complete Star Script source code for the theme, please drop me a note at I will send you the complete Star Script source to simply your customization.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: