To illustrate how you can build a custom theme by extending a standard blog starter kit, we created the Events Minimal Theme and introduced a couple of new custom properties. Since we wanted to keep our new theme compatible with the other themes, we wanted to change only the HTML template files. Nothing needs to be done on the back end: you are free to add custom properties whenever you need them, directly in the HTML. I am a designer, and wanted to make the whole process as much designer-friendly as possible. Therefore, you will not have to deal with the complex javascript code and AngularJS controllers and services. Baasic will do all the heavy lifting for you.

Extending article admin

Since this theme is all about events, we had to introduce custom properties like start date, end date, performer, event type and extend the standard blog post JSON scheme. The image below shows some of these properties as displayed in the blog post edit view.

Extending article admin

Adding properties to the edit form

To add a property to the edit form, we’ve simply added HTML fields in the blog-post-edit-form.html, and used AngularJS ng-model directive to bind data to them. Here are some examples:

date field:

<input type="time" name="endtime" id="fieldEndTime" ng-model="blog.endtime" date-converter/>

select field:

<select name="type" id="fieldType" ng-model="blog.type">
    <option value="">---Please select---</option>
    <option value="Concerte">Concerte</option>
    <option value="Play">Play</option>
    <option value="Conference">Conference</option>
    <option value="Party">Party</option>
    <option value="Fair">Fair</option>
    <option value="Other">Other</option>
</select>

To add dynamically repeatable input fields with add/remove item functionality, we have used the standard ng-repeat directive:

<div ng-repeat="performer in blog.performers"></div>

Note that input ID’s for performer name and description fields are written with + {{$index}} to give them unique IDs for each field.

<label for="fieldPerformer + {{$index}}">Performer</label>
<input type="text" name="title" id="fieldPerformer + {{$index}}" ng-model="performer.name" />
<label for="fieldPerformerDesc + {{$index}}">First Performer Description</label>
<input type="text" placeholder="Short description..." name="title" id="fieldPerformerDesc + {{$index}}" ng-model="performer.desc" />

A button for removing particular performer uses the ng-click directive.

<button type="button" ng-click="blog.performers.splice($index, 1)">x</button>

Here is how he handle adding of a new performer:

<button type="button" ng-click="blog.performers = blog.performers || [];blog.performers.push({name:'', desc:''});">Add Performer</button>

When you combine all of this you get:

<div ng-repeat="performer in blog.performers">
    <label for="fieldPerformer + {{$index}}">Performer</label>
    <input type="text" name="title" id="fieldPerformer + {{$index}}" ng-model="performer.name" />
    <label for="fieldPerformerDesc + {{$index}}">First Performer Description</label>
    <input type="text" placeholder="Short description..." name="title" id="fieldPerformerDesc + {{$index}}" ng-model="performer.desc" />
    <button type="button" ng-click="blog.performers.splice($index, 1)">x</button>
</div>
<button type="button" ng-click="blog.performers = blog.performers || [];blog.performers.push({name:'', desc:''});">Add Performer</button>

Displaying custom properties

Custom properties have to be shown on blog-list.html and blog-post.html views. Here are the examples:

blog-list.html:

<article ng-if="hasBlogs" ng-repeat="blog in blogList.item" ng-class=" { 'article--lrg': $first , 'article--sml': !$first } ">
    <div style="background-image: url('{{ blog.featured }}')">
        <span>{{ blog.startdate | date:'MMM' }}</span>
        <span>{{ blog.startdate | date:'dd' }}</span>
        <span>{{ blog.startdate | date:'yyyy' }}</span>
        <span>{{ blog.type }}</span>
        <h1><a ui-sref="master.blog-detail({ slug: blog.slug })">{{ blog.title }}</a></h1>
        <span>{{ blog.location }}</span>
        <div ng-if="$first">
            <div ng-repeat="performer in blog.performers | limitTo: 3">
                <h2>{{ performer.name}}</h2>
                <small>{{ performer.desc }}</small>
            </div>
            <a ui-sref="master.blog-detail({ slug: blog.slug })">More Info</a>
        </div>
    </div>
</article>

blog-post.html (example of the performer field):

<div ng-repeat="performer in blog.performers">
    <h2>{{ performer.name }}</h2>
    <small>{{ performer.desc }}</small>
</div>

This way we managed to extend and customize the standard Baasic article module with just a few changes in HTML files.

Conclusion

Extending Baasic AngularJS starter kit using this approach will give you an easy way to add your own functionality without changing starter kit core functionality. If you are building a whole new blog or a Web site and you wish to extend it even more, you can take an alternative approach and fork the Blog Starter-Kit. This approach will allow you to modify all application files such as services, controllers and even change the whole build and deployment process - but it will require more in-depth knowledge of javascript.

Feel free to leave a comment

comments powered by Disqus