Setting up a widget file is easy, but there are few gotchas that can perplex beginners.
The first step is to create a new widget in the Widget Admin console. Click on the New Widget button and enter a name for your widget. Widget names should be short and snake-case (lowercase, with underscores). This will create the resources for your widget on the server. In this example, I will create a widget called "money_stuff".
Now create a folder for your new widget in the code directory on your local machine.
// Go to my widget code directory, create a new folder admins-mbp:Desktop burfoot$ cd /opt/userdata/lifecode/widgets/dburfoot/ admins-mbp:dburfoot burfoot$ mkdir money_stuff
Just for the sake of example, I will upload a file called "hello_world.txt" to the server. This won't do anything special, but it confirms that everything is setup correctly.
admins-mbp:dburfoot burfoot$ cd money_stuff/ admins-mbp:money_stuff burfoot$ echo "Hello, world" >> hello_world.txt admins-mbp:money_stuff burfoot$ ls hello_world.txt
admins-mbp:script burfoot$ CodeUploader.py widgetname=money_stuff Wrote upload file to path /opt/rawdata/servlet/dburfoot__money_stuff.widgetzip Deleted old file /opt/userdata/widgetserve/dburfoot/money_stuff/widget.jsp Extracted file /opt/userdata/widgetserve/dburfoot/money_stuff/hello_world.txt, size is 13
The file is now available on the WWIO server. Important: Notice that you do not have to log in to access this file! It is public for everyone to see. The WebWidgets framework only authenticates requests that attempt to access Widget data (ie, the info in the SQLite files).
admins-mbp:money_stuff burfoot$ curl https://webwidgets.io/u/dburfoot/money_stuff/hello_world.txt Hello, world
Now we create a skeleton SQLite DB and send it to the server. Go to your Widget data directory and run sqlite3. Notice the name of the sqlite3 DB I created. To name the file correctly, upper-case the widget name, and add the extension "_DB.sqlite". After that, I create a simple table with 3 fields, including an "id" primary key.
admins-mbp:~ burfoot$ cd /opt/userdata/db4widget/dburfoot admins-mbp:dburfoot burfoot$ sqlite3 MONEY_STUFF_DB.sqlite SQLite version 3.28.0 2019-04-15 14:49:49 Enter ".help" for usage hints. sqlite> create table big_money (id int, amount int, desc varchar(20), primary key(id)); sqlite> .schema CREATE TABLE big_money (id int, amount int, desc varchar(20), primary key(id));
Now I upload the file with the DataPush.py script. The server tells you a bit about how it is handling the upload, in particular, it tells you how it has auto-generated a JS file from the SQLite definition.
admins-mbp:script burfoot$ DataPush.py widgetname=money_stuff Wrote upload file to path /opt/rawdata/servlet/dburfoot__money_stuff.sqlite Saving DB file for widget dburfoot::money_stuff Deleted old DB file /opt/userdata/db4widget/dburfoot/MONEY_STUFF_DB.sqlite Copied upload file to location /opt/userdata/db4widget/dburfoot/MONEY_STUFF_DB.sqlite, size is 12288 Created directory /opt/userdata/widgetserve/dburfoot/autogenjs/money_stuff Wrote autogen code to path /opt/userdata/widgetserve/dburfoot/autogenjs/money_stuff/BigMoney__001.js
If you're interested, you can look at the JS autogen file. The file is pretty large, I'm just showing the first 20 lines:
admins-mbp:money_stuff burfoot$ curl https://webwidgets.io/u/dburfoot/autogenjs/money_stuff/BigMoney__001.js | head -n 20 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 3966 100 3966 0 0 80938 0 --:--:-- --:--:-- --:--:-- 80938 // Auto-Generated JavaScript code for big_money // Definition of main collection name BigMoneyTable = { // Table properties widgetOwner : "dburfoot", widgetName : "money_stuff", tableName : "big_money", _dataMap : new Object(), register : function(tableitem) { // Item inherits same DB as collection tableitem._dbName = this._dbName; // Assign the K/Value pair. this._dataMap[tableitem.getPkeyStr()] = tableitem; ....
Don't worry: you don't actually need to understand all of that code! It is just backend plumbing for the system.
Now I'm going to create a bare-bones widget.jsp file. You can use this page as a skeleton for developing your widgets.
<html> <head> <title>Money Stuff</title> <wisp/> <script> function redisplay() { const itemlist = W.getItemList("big_money"); populateSpanData({"num_records" : itemlist.length }); } </script> </head> <body onLoad="javascript:redisplay()"> <center> <h3>Money Stuff</h3> Number of records: <span id="num_records"></span> </center> </body> </html>
As you can see, there's only one difference between this file and a normal, pure HTML/JS file (ie, a file you could look at with your browser's Open File command). The difference is the DataServer tag that comes right after the <title> tag. This tag instructs the WebWidgets framework to pull in the data associated with the page. The framework authenticates the user using the request object (this is a Java HttpServletRequest). It also uses the request object to determine the widget name from the URL, and pulls in all of the code and data associated with the widget. The basicInclude command pulls in the entire widget database; it is possible to be more selective about what data is requested, and also to pull in data from other widgets.
Older widget code used two additional tags called AuthInclude and AssetInclude. AuthInclude was placed at the top of every .jsp file, and instructed the system to authenticate the user before serving data. This tag is still used, but you don't need to explicitly include it: the framework adds it to every .jsp file when it is uploaded. The AssetInclude tag was used to pull in the JS library code needed by the system; this is now done by the DataServer tag.
If all goes well, you should see a page that looks like this:
It's showing 0 records because we don't have any data in the SQLite DB. Let's go back to the DB and enter some data:
admins-mbp:dburfoot burfoot$ sqlite3 MONEY_STUFF_DB.sqlite SQLite version 3.28.0 2019-04-15 14:49:49 Enter ".help" for usage hints. sqlite> .schema CREATE TABLE big_money (id int, amount int, desc varchar(20), primary key(id)); sqlite> insert into big_money values (5, 15, 'cheeseburger');
And use the uploader script to send the data to the server:
admins-mbp:script burfoot$ DataPush.py username=dburfoot widgetname=money_stuff Wrote upload file to path /opt/rawdata/servlet/dburfoot__money_stuff.sqlite Saving DB file for widget dburfoot::money_stuff Deleted old DB file /opt/userdata/db4widget/dburfoot/MONEY_STUFF_DB.sqlite Copied upload file to location /opt/userdata/db4widget/dburfoot/MONEY_STUFF_DB.sqlite, size is 12288 New version of AutoGen code identical to previous for DB big_money
Now we reload the page in the browser and we see our new record:
You can also see the record content by going into the browser JavaScript console and calling W.getItemList(..):
Okay! Your widget is setup correctly. From here, you can add more tables to the SQLite database, or start to build out the user interface for your widget. For more ways to manipulate the data, check out the JavaScript API.