Ext JS to React: Simple Templating

   JavaScript

This is part of the Ext JS to React blog series. You can review the code from this article on the Ext JS to React Git repo.

One of the lesser talked about classes within Ext JS is its templating class. Ext JS’s Template and XTemplate classes take a string (or an array of strings) and compile it down to a JavaScript function. When it’s told to render, the JavaScript will execute with data passed to it and outputs HTML. It’s one of the few aspects of Ext JS where you will deal with HTML directly.

In React, instead of defining a template and passing data to output HTML, you’ll use JSX and native HTML/CSS/JavaScript. This sounds a bit scary and may even come across as a step backward after having worked with the templating system in Ext JS. But in reality, it’s just skipping the runtime compilation step Ext JS had to go through (using Babel will transpile JSX into JavaScript at build time). JSX allows you to take full benefit of the conventions ushered in with ES6 such as string template literals. Additionally, Javascript expressions can be included with ease including conditional processing. But, perhaps we’re getting ahead of ourselves. Let’s take this one step at a time!

Ext JS templating example

Most Ext JS components can accept a tpl config and when passed data, will render the HTML for you. Templates can be a mix of primitive values (strings, numbers, booleans) or can handle more complex values (arrays, objects). An example of using these values would look like:

vvar data = {
    name    : 'Smith Corp',
    address : {
        street : '1 Smith Blvd',
        city   : 'Smithville',
        state  : 'Smith',
        zip    : 12345
    },
    people  : [{
        name   : 'Bob Smith',
        email  : 'bob@smith.com',
        skills : ['cooking', 'building']
    }, {
        name   : 'Jane Smith',
        email  : 'jane@smith.com',
        skills : ['managing', 'presenting']
    }]
};

Ext.define('MyComponent', {
    extend: 'Ext.Component',
    xtype: 'mycomponent',
    
    tpl: '<h1>{name}</h1>' +
    '<div>' +
        '<h2>Address:</h2>' +
        '<div>{address.street}</div>' +
        '<div>{address.city}, {address.state} {address.zip}</div>' +
    '</div>' +
    '<tpl if="people.length &gt; 0">' +
        '<div>' +
            '<h2>People ({people.length}):</h2>' +
            '<ul>' +
                '<tpl for="people">' +
                    '<li>' +
                        '<div>{name}</div>' +
                        '<div>{email}</div>' +
                        '<div>Skills:</div>' +
                        '<ul>' +
                            '<tpl for="skills">' +
                                '<li>{.}</li>' +
                            '</tpl>' +
                        '</ul>' +
                    '</li>' +
                '</tpl>' +
            '</ul>' +
        '</div>' +
    '<tpl else>' +
        '<div>No people found</div>' +
    '</tpl>'
}); 


Ext JS templating rundown

This component will show a company’s name and address after looping through an array of people belonging to the component. There are a couple of distinctions to note:

  1. The values wrapped in curly braces are mapped to the current object/array. So {name} is mapped to data.name and {address.street} is mapped to data.address.street.
  2. Most of the tags are normal HTML tags. The only special tag is the <tpl> tag. It is not a HTML tag but is handled specially by Ext JS. This tag can handle special things like if conditionals (<tpl if=”people.length &gt; 1”> and <tpl else> where if is checking for data.people in this case), loop through an array (<tpl for=”people”> which will loop through the data.people array) among other things.
  3. Notice within the <tpl if=”people.length &gt; 1”> ,the > had to be encoded.
  4. When looping through an array, the values within the curly braces are for the current item in it. This is why {name} within the people loop will belong to the object within the people array and not the top level name of the company. Likewise, if the item within the array is a primitive value you would use a period within the curly braces. This will use the current item similar to the skills loop.

The template string above is compiled to JavaScript the first time it’s executed. It will replace the curly braces with the associated data, and use an if conditional for the <tpl if=””> without needing to encode the greater-than. Then, it will run a for loop for the <tpl for=””>. With React, the component will handle all of the JavaScript code instead of relying on a compile step being abstracted away.

React templating example

Now, we will show how a React component would output the same HTML as above in the Ext JS example:

import React, { Component } from 'react';

class Company extends Component {
  render () {
    const { data } = this.props;

    return (
      <div>
        <h1>{data.name}</h1>
        <div>
          <h2>Address:</h2>
          <div>{data.address.street}</div>
          <div>{data.address.city}, {data.address.state} {data.address.zip}</div>
        </div>
        <div>
          {
            data.people.length > 0 ?
              <div>
                <h2>People ({data.people.length}):</h2>
                <ul>
                  {
                    data.people.map(person => (
                      <li>
                        <div>{person.name}</div>
                        <div>{person.email}</div>
                        <div>Skills</div>
                        <ul>
                          {
                            person.skills.map(skill => <li>{skill}</li>)
                          }
                        </ul>
                      </li>
                    ))
                  }
                </ul>
              </div> :
              <div>No people found</div>
          }
        </div>
      </div>
    );
  }
}

export default Company; 

To use the Company class (with the same data we set up for the Ext JS example above):

import React, { Component } from 'react';
import Company from './Company'
import './App.css';

// the data object from the Ext JS example above

class App extends Component {
  render() {
    return (
      <Company data={data}/>
    );
  }
}

export default App; 


Ext JS to React: Simple Templating, Example



With the exception of the native JavaScript ternary and array maps, the React version is very close to what you would do in Ext JS. JSX uses curly braces to allow you to return a value from the data object but also allows you to execute a JavaScript statement within it. Not having a templating system isn’t a scary thing as JSX is really close to a templating system itself. Your IDE may even decorate your code with syntax highlighting including the JavaScript within the curly braces as well as report errors by line number. Your editor’s auto indenting and code formatting tools, such as eslint, will unindent your nice XTemplate! For example, the IDE is not going to know to indent <tpl for="">. In this way, the dev experience is much improved with JSX.

Conclusion

Ext JS templating has proven to be a very flexible and powerful system, but JSX is just as powerful, more flexible, and well supported by the various tooling for JavaScript. With React, you are likely already familiar with the mechanics of JSX. This means no bespoke templating system is needed AND you don’t lose any functionality! Reliance on facilities of XTemplate like xindex and xcount to monitor iterations is no longer needed. It can all be done with plain, familiar JavaScript. Another big plus with React templating is that compositing JSX output from one React class into another is very straight forward. Stay tuned for our next blog post where we take a deeper dive into what’s possible with JSX and React!


This website uses cookies

These cookies are used to collect information about how you interact with our website and allow us to remember you. We use this information in order to improve and customize your browsing experience, and for analytics and metrics about our visitors both on this website and other media. To find out more about the cookies we use, see our Privacy Policy.

Please consent to the use of cookies before continuing to browse our site.

Like What You See?

Got any questions?


>