Developing Your First Custom SuiteCommerce Advanced Module: Part 1

This tutorial is the first in a four-part tutorial on the basics of developing in SCA. It is most appropriate for Denali and Mont Blanc versions. If you're running Vinson or Elbrus, the section on service files will still work but is a deprecated coding style. You may wish to follow up with a tutorial on service controllers, eg how to build a contact us form. If you're running Kilimanjaro, Aconcagua or newer, I recommend using the newer tutorial.

Once you have your SuiteCommerce Advanced site and developer tools set up, it's time to get started. This article will guide you through the process of making changes to your site by adding functionality to the My Account section of a site. While the functionality itself will be somewhat arbitrary, it will teach:

  • Using the developer tools, including Gulp.
  • Performing basic tasks in the NetSuite app, to help familiarize you with the web interface. 
  • Understanding the folder structure and where files go.
  • Getting to grips with single-page web architecture, particularly the libraries that we use in SCA: Backbone and Underscore.
  • Interacting with NetSuite's Shopping and Commerce APIs to perform CRUD (create, read, update and delete) operations.
  • Making aesthetic changes to the site's design.

The process for doing this takes several hours and the steps for doing is split up into multiple parts. This part covers the initial work for creating a module, getting "Hello World!" to appear on your site, and the basics of creating a view, router and template.

Module Summary

The module we will be adding captures the name of an artist and the genre of music that they perform. Ultimately this will be able to be entered through a form in a shopper's My Account; thus the shopper will need to log in, navigate to the page, and then create/read/update/delete record data. We will also be making aesthetic changes such as styling using Bootstrap, adding a link to the navigation, using modals, and adding a crumbtrail. 

Creating the Record Type in NetSuite

Before we can develop something to interact with a record we must first create a new record type. Log in to the web interface for your site and navigate to Customization > Lists, Records, & Fields > Record Types > New. Add the type as follows:

  • Name: Artist
  • ID: _artist
  • Show ID: (ticked)
  • Access Type: Use Permission List
  • Permissions Tab
    • Role: Customer Center
    • Level: Full
    • Restrict: Viewing and Editing.

Make sure you click Add in the Permissions tab to add that permission, and then click Save to add the record type. You should leave all other settings to their default values.

Note that we use an underscore as a prefix to the custom record ID, this is because the app will append "customrecord" to the start of the ID when it is created. This convention is not mandatory but it's recommended to help you keep track of all the custom records (and custom fields and custom lists) that you create. 

The permissions tab configuration will ensure that the customers will only be able to view and edit their own records and not the records of any other customer.

When the page reloads, click the New Field button in the Fields subtab. We need to add in a field to the Artist record. Add it as follows:

  • Label: Genre
  • ID: _genre
  • Type: Free-Form Text

It would be better to make the genre field a list, but for the sake of simplicity we're going to use a standard text field. Save the field.

Preparing Your Local File Structure

In the local version of your site's files (that you created as part of your dev tools setup) is a folder called Modules; in this folder are two more folders: one, suitecommerce, that contains the proprietary code that makes up your site, and the second, third_parties, contains the libraries. frameworks and other code that SCA sites depend on. Within the Modules folder create a third and name it something like custom (or, say, your site's name) – this is where your site-specific code will live. 

For our Artist module, we need to replicate the standard module structure. Under your custom folder create the following structure:

  • Artist@dev
    • JavaScript
    • SuiteScript
    • Templates

Note the dev suffix – typically modules use numbers instead, but we're not versioning this module so we're picking an arbitrary value instead. 

Within the Artist@dev folder put a ns.package.json file. This file tells Gulp to look in the specified directories for your module's code. The easiest way to do this is to copy this file from an existing module. When you've done this open the new file and modify it so that it has the following structure:

{
    "gulp": {
        "javascript": [
            "JavaScript/*.js"
        ],
        "ssp-libraries": [
            "SuiteScript/*.js"
        ],
        "services": [
            "SuiteScript/*.Service.ss"
        ],
        "templates": [
            "Templates/*.tpl"
        ]
    }
}

After saving the file return to the top level of your SCA directory and edit distro.json. In the JSON for the modules key add in an entry to the bottom of attribute-value pair list for the Artist module. For example:

{
    "name": "SuiteCommerce Advanced 2.0",
    "version": "2.0",
    "folders": {...},
    "modules": {
        "suitecommerce/Account": "2.0.0",
        "suitecommerce/Address": "2.0.0",
        ...
        "third_parties/underscore.js": "1.7.0",
       "custom/Artist": "dev"
    ...
}

Save the file.

Hello World

At this point you've created an empty module that will be included in the Gulp tasks, such as adding it to the distribution and deploying to your site. Next we're going to add some code to it so that something appears on the frontend – we will add backend code later. First we start with a module file. 

A module file lives in the module's JavaScript folder, taking the form of [module name].js. The SCA single page app uses this file to initialize a router for the module. For testing purposes, however, let's just put a simple console.log() in it so we can see if it's working. Create Artist.js and put the following in it:

//@module Artist
define('Artist', function() {
  'use strict';

  return {
    mountToApp: function(application) {
       console.log('Hello World!');
    }
  }
});

Now that we have a JS component, we need to execute it in one of three applications that make up SCA (Shopping, MyAccount and Checkout). Open distro.json again. What we edited before only declared our new module, we now need to specify where we're going to run it.

Scroll down to tasksConfig and, within that, to the MyAccount task (SC.MyAccount.Starter). In the dependencies array, add an entry for Artist at the bottom.

Save the files and run gulp. This will build your code and deploy it to your site. Once the deploy finishes, go to your site in your browser and log into a customer account (if you don't have a customer account already, register and then go to My Account). When you're in, open the console – you should see your "Hello World!" message.

Create a View, Router and Template

In Backbone, views are JS files that are used to reflect the application's data models and listen to events and react accordingly. The simplest way to think of them is as the code that loads the template to be rendered on the frontend. In JavaScript folder create Artist.List.View.js. For now we are going to keep it simple, so just put the following in it:

define('Artist.List.View', [
'Backbone'
], function(Backbone) {
   return Backbone.View.extend({

   });
});

Note that we have used define; this is part of a library SCA uses called RequireJS, which allows us to manage our module structure effectively and manage the dependencies that each module has. The first argument in a define statement is an array of dependencies. In this statement we are putting Backbone as a dependency and then passed as parameters to the function.

This is going to be used to show a list of artists. To get to the view, you'll need to create a router. Routers are used in Backbone to direct users through the use of hash tags (#) and slashes (/). Thus, in order to show customers a list of artists we will need to create a router to direct them to Artist.List.View.js. Create Artist.Router.js in your JavaScript folder. Its contents looks similar to the view:

define('Artist.Router', [
  'Backbone'
  ], function(Backbone) {
  return Backbone.Router.extend({
    routes: {
      'artists': 'artistList',
      'artists/new': 'newArtist',
      'artists/:id': 'artistDetails'
    }
  });
});

So we've added three routes: one for listing the artist, another for adding a new artist, and a final one for viewing a particular artist's details. The values attached to the attributes we just specified are functions that we need to create. But first, for the artistList function to work, we will need to add Artist.List.View.js as a dependency. Modify the define statement to the following:

define('Artist.Router', [
  'Backbone',
  'Artist.List.View'
  ], function(Backbone, ListView) {

So now our router has all things it needs to direct the user to a particular view (it know it depends on our view file and has the power to call it) so now we just need to define the artistList function that will be called when a user visits #artists in the browser. Below routes add the following:

artistList: function() {
  var view = new ListView();
  view.showContent();
}

This will render the view when the hashtag is used. Remember, though, we don't have anything in our view – we will need a template. Within your Templates create artist_list.tpl and, for now, just put in the following code:

<h1>Hello world!</h1>

Now we need to modify the view so that it knows to show the template. Modify Artist.List.View.js to add the template as a dependency and parameter to the define statement, and then add the template to return statement. Your code should look like the following:

define('Artist.List.View', [
'Backbone',
'artist_list.tpl'
], function(Backbone, artist_list_tpl) {
   return Backbone.View.extend({
      template: artist_list_tpl
   });
});

Then, we need to plug the router into the application – this goes in Artist.js. Modify it so it looks like this:

define('Artist',
  [
  'Artist.Router'
  ],
  function (Router) {
    'use strict';
    return {
      mountToApp: function(application) {
        return new Router(application);
      }
    }
  }
);

Finally, we need to initialize the application in the router. In Artist.Router.js create an initialize function within the return function. This also needs to be added as a parameter to the artistList function.

  return Backbone.Router.extend ({

    initialize: function(application) {
      this.application = application;
    },

    routes: {...},

    artistList: function() {
      var view = new ListView ({application: this.application});
      view.showContent();
    }
  });

Everything is ready for another test, so run gulp local to deploy it to your local server. When that finishes, log back in to your local site's My Account. You can access your local site by appending -local to the name of SSP application in the URL. For example, after you log in change /my_account.ssp to /my_account-local.ssp. After that, append #artists to the end of the URL. You should see your "Hello world!" in the page.

Note that if you see a blank page when accessing your local server, it may be because the scripts are being blocked because you're using a secure protocol with insecure resources. You will need add an exception to allow the scripts to run; in Chrome you can do this by clicking the silver shield in the address bar. See 5 Ways to Troubleshoot SCA in the Browser for more information.

Conclusion

In this article (one of many in the series) we covered the basics of getting started using the SuiteCommerce Advance development tools. After moving through some basic set up in NetSuite and our local environments, we wrote some Hello World! code. In doing so we learnt about views, routers, and templates which are crucial parts of Backbone and SCA.

In the next article of this series, we will introduce further Backbone components to our module, namely models and collections, and also some basic SuiteScripting, which is server-side JavaScript and provides a powerful tool for frontend developers.

You can download a copy of the files as they should be here SCA-First-Custom-Module-Part1.zip.

Part two to this series is available here.

Further Reading