Themes in the Erdiko Framework (Part 1)

As web applications and sites become more complex it becomes important to organize your view layers with themes. We explain how to leverage the Erdiko theming engine and how to keep your code tidy and consistent. This is the first of a series of posts about Erdiko theming.

Why do we need themes?

Typically when we start a new web project, we are focused on the workflow and technical details about how the applications will work and what solution will provide to the end user. At some point of the planning process, we should start thinking about how our application will look, what data will offer, and then we begin to define our needs:

  • What is dynamic and what is static
  • What will be changed according our business logic
  • What is the menu, header, footer etc

Most of the time the HTML code will deliver rendered data elements, but half the battle of frameworks is deciding how to organize your code.

remember that design patterns are tools that you can use to solve specific problems , In MVC the Controller is responsible for determining which View is displayed in response to any action including when the application loads, if some parts of the view are very similar probably you need themes, don’t reinvent the wheel!

Currently we can find this behavior in any web application or SPA :

  • The header and footer are consistent across pages
  • The content changes according to the link we click in the navbar
  • The navbar (below the header or left aligned) will probably change according  to user level (admin, operator, visitor, etc).

At the end of the day we can realize that we don’t have to repeat over and over the same code, and we want to promote the re-usability of our code.

Thankfully, much of this work has been solved by many modern frameworks (re-inventing this is not an easy task). Let’s examine how we accomplish this with the Erdiko theming engine.

Paths and files

Let’s discuss what is in our Erdiko folder structure:

paths

For the moment just keep focusing on the “themes” folder and their nested folders. There are a lot of files right? Don’t worry let me explain:

  • themes: where each different theme is stored.
  • bootstrap: the default Erdiko’s theme.
  • views: This is where we put our HTML templates, where we render the data from our models.

Within the bootstrap theme:

  •  templates/layouts: we got templates in the most common variety: 1, 2, 3 columns and a menu.
  • templates/page: this part is the easier to understand, footer and header content, a messages file to show flash message alerts, and two special files: ‘google_header’ and ‘google_body’.  These last two allow us to insert Google Tag Manager and Google Analytics information.
  • theme.json: this file is one of the most important in order to use themes feature. Here we can set up all the previous files we talk, using json format.
  • app/config/{context}/default.json: another important config file to set up what theme will be used by the Erdiko application (theme, namespace, how many columns? And the home url). In order to demonstrate the flexibility of Erdiko framework, you can define many different contexts for a web application (default, production, etc).
  •  Default.php: the backbone file for Erdiko’s themes, here we give the main html5 structure to the final app  and also (and most important) we make use of the previous dynamic files (header, footer, example) calling the method:
Theme::getTemplateHtml().

In the same way we can show the dynamic code corresponding to the footer:

$this->getTemplateHtml('footer');

 We finally don’t know how this magic happens, how to mix dynamic data and html code in the exactly and specific parts. Is a dirty job but somebody has to do it… and the candidate is Mustache!

But what is mustache?

Mustache is a logic-less templating language that can be used to take most of the work out of creating re-usable HTML templates.

Let’s see a little example:
1. define the mustache template:

<h1>{{header}}</h1>

Please note the ‘header’ word between curly brackets.

2. define the model to user over that template:

{ "header": "Hello world!"}

3. Apply that model to the template and render it:

<h1>Hello world!</h1>

This pattern is extremely useful. Not just for re-use, but making debugging far easier.

Currently Mustache offers a lot of useful functionality but this is the most basic and important one. What we got here is the idea how it works, but remember that Mustache is One of many template systems, and the framework is not limited to use it.

Themes

The Theme class is the key element here, we need to understand how it works, their methods names are self-exaplanatory, the most important task is to process data and html templates to obtain a final html code. When a controller is created, a theme attribute is built in order to provide structure to the application. All necessary parts before to render are prepared by the _before() hook:

public function prepareTheme()
{
    $this->getResponse()
         ->setTheme(new \erdiko\core\Theme($this->getThemeName()));
}

Each time we call an action on a controller (except the ajax controllers) we automatically are setting a Theme, by inheriting the class \erdiko\core\Controller. When the action is done, tipically we create a new view passing a data array as second parameter:

$this->addView('examples/list', $data);

Or maybe we don’t want to show a view, we can just show a basic content with controller::setContent() method:

// Entering raw text on the page
$this->setContent("
    <div class=\"container\"><p>
    This is the simplest page possible.</p>
    </div>");

Then if the action is finished, the internal Theme will render their html stored. The most important methods of class Theme are:

  • addMeta(): Manages metadata of the application.
  • setPageTitle() and setBodyTitle(): Manages the title.
  • getCss() and getJs(): their setters add units of code, but the getters retrieves an array of that specific nature (array of css, or array of js stored). The result is a well formed <link> tag according to each array cell.
  • getTemplateHtml($aPartialToBeRendered): we can switch the template for a theme to render html with data.
  • toHtml(): finally we got html rendered.

In this first half of our blog post, we offer a big picture view of how theming works in Erdiko framework. At this point, we know that Controllers ‘under the hood’ already has prepared a theme ready to use with our defined content, and these themes are able of make html code. But they are not the only actors in this movie and the render concept needs to be explained a little more in depth. The next post we will continue talking about themes and discovering more actors and abilities. Thanks for reading!

Angular 2 Attribute Directives

Attribute Directives are a powerful way to affect the appearance or behavior of a DOM Element in your Angular 2 Application. We examine how attribute directives work, and how you can build re-usable custom code for your projects.

Introduction

AngularJS really introduced the concept of organizing and extending the DOM for use in real web applications. AngularJS 1.x brought us the idea of a Directive, or a way to indicate that a DOM element was “special” and will have a behaviors or an appearance that will be controlled by your code. AngularJS 2 took this idea and ran with it, but this also means we need to explain some stuff. We now have 3 tools at our disposal for interacting with the DOM: Components, Structural Directives and Attribute Directives.

Components, which you should have at least read about by now, are the most basic of the angular building blocks. Everything is a component and all components have directives; components are created from one or more directives. Directives are the method to identify a component’s behavior or associate a variable to a component.

Structural Directives are used to add or remove elements from the DOM. Common examples are *ngIf or *ngFor. These directives allows you manipulate a component based on a variable value or allow a component to iterate a series of values.

Finally, we have Attribute Directives. Attribute directives allow you to attach a behavior to an element or affect it’s appearance and re-use this throughout your application or package it up as something you use in all your projects.

Using Attribute Directives you can create a stylized DIV tag that formats all text and adds an event listener to change the color when the user mouses over the text. Show off your example code with some syntax highlighting!

I should also note that Attribute Directives can access and manipulate application values, but primarily are focused on affecting the component they have been attached. Think of this as more like CSS Selector Class on steroids. Make sure you do the “real math” of your application in your components.

Anatomy of an Attribute Directive & How to use it

Attribute Directives can be simple or complex. The simplest example of an Attribute Directive could be a simple CSS property attached to a P Tag:

<p [style.background]="'red'">I'm red!</p>

Anything more complex than the above example requires a little more wiring. Let’s look at an commented example from the official docs called “Highlight”:

// Import some stuff from the core library
import { Directive, ElementRef, Input, Renderer } from '@angular/core';

// create a Directive to decorate. To prevent confusion let's call this myHighlight to 
// illustrate the fact this this is a custom appearance
@Directive({ selector: '[myHighlight]' })

export class HighlightDirective {

    /* 
    This is a pretty simple example, we just need a constructor. Pass the element we wish to affect in as "el" and make sure we interact with the DOM renderer with the obvious name of "renderer"
    */
    constructor(el: ElementRef, renderer: Renderer) {

       /* 
       Set the element's Background Color CSS property to Yellow, as though we "highlighted" it with a marker.

       Note we reference the element itself as el.nativeElement so we actually update the rendered DOM model itself.
       */
       renderer.setElementStyle(el.nativeElement, 'backgroundColor', 'yellow');
    }

}

Use and apply your custom directive attribute in your application
<p myHighlight>Highlight me!</p>

Some Attribute Directive Examples

Italic & Underline

A very simple example showing how we can make something italic, and underlined, using a simple attribute directive.

@Directive({ selector: '[alItalic]' })

export class ItalicDirective {
 
  constructor(el: ElementRef, renderer: Renderer) {
    renderer.setElementStyle(el.nativeElement, 'fontStyle', 'italic');
    renderer.setElementStyle(el.nativeElement, 'textDecoration', 'underline');
  }
 
}

Plnkr

Blink

We can also bring back the much missed BLINK tag using an attribute directive. This example illustrates how we can actually encapsulate some logic and manipulate the DOM element’s CSS with this logic by using an attribute directive that can be placed on any block element.

@Directive({ selector: '[alBlink]' })

export class BlinkDirective {
  
    constructor(el: ElementRef, renderer: Renderer) {
      setInterval(() => { 
        let style = "hidden";
        if(el.nativeElement.style.visibility && el.nativeElement.style.visibility == "hidden") {
          style = "visible";
        }
        renderer.setElementStyle(el.nativeElement, 'visibility', style); 
      }, 750);
    }
    
}

Plnkr

Detected User Event – Click

Finally, here’s an example where we can listen for a user event (click) on an element by simply using an attribute directive.

import { Directive, ElementRef, Input, Renderer, HostListener } from '@angular/core';

@Directive({ selector: '[alClick]' })

export class ClickDirective {
  
  private _el: ElementRef;
  
  constructor(el: ElementRef, renderer: Renderer) { 
    this._el = el;
  }

  @HostListener('click') onClick() {
    let str = this._el.nativeElement.innerHTML;
    alert("innerHTML from the element you clicked: " + str);
  }
    
}

Plnkr

Conclusion

We really only scratched the surface of what you can do with Attribute Directives. AngularJS has always been a framework that allowed you to organize and extend your DOM based applications, but AngularJS 2 has taken this to a whole new level.

Hope you enjoyed this post!