Smart UI: Beginners Guide
I have to admit, I have been avoiding this for a while. Every time I get myself psyched to look at building a Smart UI module I get frustrated by the gaps in the documentation, the workflow that seems at times to be janky. Compared to other similar addon mechanisms (like Microsoft SPfx ) this has some similarities, but the lack of a total end-to-end getting started tutorials means it can be a steep climb for newcomers.
So let's create a Smart UI module and then and deploy this to a server.
Smart UI Project Setup
You are going to need some things for this, and below is a shopping list of sorts:
- Node JS — Use a Node Version switcher….cannot emphasize this enough. Smart UI is running on some old dependencies and these will break in the future. I am using NVS, but there are others like NVM
- The Smart UI Zip files from the knowledge center (you will need to search for them as they are not in a logical place).
- a JavaScript editor- I am using VS Code 😍
- Content Server, with Eclipse IDE and the Content Server SDK Eclipse plugin installed. Yes the Smart UI SDK creates the Javascript, and the Oscript files — there is no way to just simply build the oll files required to deploy your module 😣
For we are just keeping this to a hello world type tutorial. At the end of this, we will end up with a widget and will be able to be deployed to a Content Server.
Simple Primer
So that we can keep terminology consistent we will have two projects:
- a Smart UI module that will contain widgets (and behaviors, commands, controllers, controls, modules, perspectives)
- an Eclipse OScript Project that will contain a module. We then combine the output of this with the Smart UI module to create our output.
Setup Project
Setup Node
The first this you will want to do is set up Node. Using NVS select version 10/11.
Next, you will need to install the following (these two build tools are key):
npm install grunt-cli yo -g
Unzip the Generator
The next thing we will need to do is unzip the CSUI generator
From the command line, browse to the location of the generator and run
npm link
This will create a symlink that will allow other node projects to use this code (in this case it will be the yo generator)
Build Smart UI Module
We should have enough to get started. Let's create a new project folder.
mkdir simplemodule
With the folder created, browse to that folder and start the yo generator
cd simplemodule
yo csui-extension
You will need to provide the following information:
- CS module name — for now I am just calling it simple, but if you are adding Smart UI capability to an existing module then you could use the same name
- The module description
- And RequireJS module prefix. Now I have just accepted the defaults here, but keep in mind that there might be a chance of this clashing with other modules in the Smart UI ecosystem so it might be worth choosing something unique.
This will take a while to build, once done you will be left with a shell of a project. Once it has completed, you will notice that if you run npm start you won't be able to see anything. That is because we have not added any content to this project. So let's do that.
Add Widget to Project
To add a widget to the project you can use the same generator (in the same folder as your Smart UI project).
yo csui-extension:widget
The yo generate will also prompt us to update the following files:
- /src/simpl-extentions.json
- /src/bundles/simpl-all.js
Now to see our hello world run
npm start
Next, browse to http://localhost:7777/src/widgets/hello/test/ and you will see our very basic hello world.
You can now start developing this widget.
Some Improvements to the project
If you use React, Angular, SPfx, you will be used to seeing a live-reload experience. By that, I mean an HTTP server that monitors changes to your JS and HTML that will automatically reload your browser when changes are made. It is a simple thing that focuses you more on the code and less on making sure you click refresh on your browser.
However, this is missing from this experience 😪
But we can fix this — so let's fix it.
First, let's install some additional modules to this project:
npm install grunt-contrib-watch grunt-browser-sync --save-dev
Next, we will need to need to add a new file to the root of the project. At the root of the project create a launch.html. We will use it as the root of our project that will make it quicker to get to the test pages (the browserSync server will be using port 3000 so be sure to link the widget appropriately).
Next, we need to update two grunt files. The first is located /test/Gruntfile.js. In this file load the karma section — after the debug entry add a unit entry
karma: {
debug: {
configFile: 'karma.debug.js'
},
unit: {
configFile: 'karma.debug.js',
preprocessors: [],
reporters: ['progress']
},
release: {
configFile: 'karma.release.js'
}
}
Save that change, and then open the Gruntfile.js at the root of the project. In this file, we will make two changes.
First, after the subgrunt section in the grunt.initConfig add the following:
browserSync: {
bsFiles: {
src: 'src/**/*'
},
options: {
browser: 'Chrome',
//open: false,
server: {
baseDir: './',
directory: true,
routes: {
'/img': 'lib/src'
},
},
startPath: 'launch.html',
watchTask: true
}
},
watch: {
files: 'src/**/*',
tasks: ['check', 'subgrunt:karma:unit']
}
So it should look like this:
Next, after the grunt.loadNpmTasks(‘grunt-notify’); line, add the following:
// watch for changes, run tasks and reload server
grunt.loadNpmTasks('grunt-browser-sync');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('dev', ['browserSync', 'watch']);
Finally, we update the package.json to add the dev script.
Now running npm run dev will now enable live reload
And now you can get the Live Reload love 🤩🤩🤩
Build out Project
We are not getting too much into the weeds. So once you are at a happy point — let's build out this project by running:
npm run build
This will generate four new folders in your project:
- out-debug
- out-languagepack_en
- out-module
- out-release
The one we need will be out-module, as it will have the oscript files and structure that will need to build our final module.
Eclipse and Content Server module setup
So in the documentation, it does describe importing the out-module folder into the CS Oclipse IDE. What is doesnt tell you is how. And given that I am not an Oscript developer this kind of gap is not really helpful.
Note: All this will need to be done on a server with Content Server installed. There is no way around this as yet.
Setup Eclipse
Eclipse download and installed, and the the CS Eclipse plugin extracted.
Open Eclipse, and set up a location for your workspaces
To add the plugin, within Eclipse go to Help > Install New Software
Then click on Add, and select the location of the CS plugin
Click Add, then select the software and install (a restart of Eclipse will be required).
Create Project
After the restart, hit Ctrl + N to start a new OScript project
For this OScript project, you will need to provide it a Project Name, and the location of your Content Server
It will then prompt you to take over the Content Server service, so select Shutdown (this will turn Content Server into a single threaded instance).
Once started up, in OScript Explorer right click on srcmodules and select New > Module.
Provide a module name (make sure it is the same as the Smart UI module name).
Generating this module will generate the generic files. Note that they are similar to the ones generated by the Smart UI Project.
Next — locate the Smart UI project files and then copy to the location of the Eclipse files
After you have completed, you can now see that the module is built by using the Module Explorer
And if you check the OTHOME\staging folder you will find the compliled oll.
We can now combine the resulting support resources with this
We can now test the module. To do this stop Eclipse, and start Content Server and the module should now be available in the install module section of the Admin pages
Go ahead and install it and then you can test this new module in a perspective manager
Wrapping up
So this seems like one of the longest hello worlds. But there are definately some ways to improve this workflow:
- Adding a live reload to the yeoman generator would be great
- enabling a way to compile the os files into an oll file without the need for an server and Eclipse IDE — this will assist the final build enabling development in containerized environments, and some additional CI/CD to be introduced
- It would be nice to have TypeScript in the mix — but I understand that might be asking too much for current builds of Backbone / Marionette / RequestJS / jQuery. Chris Meyer has some great articles covering the introduction of Vue here which can bring some modern JS libraries into the mix
- Better documentation — something that will get someone new off the ground as well as assist the experienced developer