A super high level workflow/application mark-up language

About a month or two ago, I was gabbling about a mark-up language for web apps with the under-achiever goal of covering the bottom 75%-ile in terms of complexity of CMS & workflow web app functionality. This mark-up language would describe the functionality and workflow of an application without seriously considering (for now) any presentation issues. So, it’s a functional but ugly web application mark-up language (FBUWAML). There could be many uses, but the most immediate one that comes to mind for me is super fast prototyping.

The goals of this project are

  1. To be able to generate web apps in an XML/HTML-like language that truly stays at the application level / requirements gathering level, and
  2. To target web designers rather than programmers—kinda like the way HTML does.

An implementation of this XML standard (ie. a program or script) would do the database configuration & schema generation/destruction/ modification automatically, so that users wouldn’t have to mess with MySQL, PhpMyAdmin or anything like that at all.

Below is an example of what I’m talking about. For this example, I’m just trying to make a blog with one admin user. (The concept of a “users” is assumed at this level.) Here is a high level natural language description of the sample web app:

Goal: To describe a blog website for 2 levels of access.

  1. Owner
  2. Reader

Usage scenario outline:

Admin pages:
  • Owner creates a blog entry.
  • Owner edits a blog entry.
  • Owner deletes a blog entry from a list with confirmation.
Public pages:
  • Reader sees most recent 10 pages on the homepage.
  • Reader clicks on an individual title.
  • Reader reads a blog entry.
  • Reader can browses by month, year on the homepage.
< fbuwaml>
< model>
< entity name="blog">
< attribute name="title" type="string" />
< attribute name="body" type="text" />
< attribute name="created_on" type="datetime" />
< /entity>
< /model>
< pages>
< publicpages>
< homepage title="Hello Blog World">
Welcome to David Beckwith's blog.  I hope you enjoy your stay.
< br />
Recent entries: < br />
< list from="blog" order="created_on descending" 
position="left-half" limit="10">
< link content="title" to="blog-detail-page">
< /list>
Browse by date: < br />
< list from="blog" order="date descending" position="right-half" limit="40">
< link content="date" to="blog-detail-page">
< /list>
< /homepage>
< page name="blog-detail-page" from="blog">
< text content="title" />
< text content="body" />
< link label="Home" to="homepage">
< /page>
< /publicpages>
< adminpages password_protected="true" password="abc123">
< page name="admin-home">
< link content="Create a new blog" to="create-blog-page">
< list from="blog" order="created_on descending" per_page="20">
< text content="blog.title">
< button label="Edit" redirect_to="blog-edit-page">
< button label="Delete" action="delete" confirm="Are you sure you want to
delete this blog entry?">
< /list>
< /page>
< page name="create-blog-page">
< input label="Title: " target="blog.title" />
< input label="Body: " target="blog.body" />
< submit label="Save" redirect_to="admin-home" />
< /page>
< page name="blog-edit-page">
< edit label="Title: " target="blog.title" />
< edit label="Body: " target="blog.body" />
< submit label="Save" redirect_to="admin-home" />
< /page>
< /adminpages>
< /pages>
< /fbuwaml>

Essentially, what I’m trying to do is parameterize web apps and assume certain patterns of behavior. I envision the final product to be realized as an open-source XML standard and also possibly a RoR application as a sample proof-of-concept prototype. The standard will specify the behavior for other code-generators (written in any language). This code-generator( or “scaffolding”) program would

  1. configure the database (create database and users if they don’t exist, create the schema, modify the schema without affecting existing data)
  2. generate model, controller, and view files that could be compiled or interpreted in your favorite language, beit RoR, PHP, Java, Python or whatever.

Why focus on the XML-standard as opposed to a particular implementation?

  1. Platform independence. By focusing on the standard, you’re not tied to any particular platform, OS, and ultimately can help more people.
  2. Interfaces matter. HTML was an advance in an interface that acted as the great equalizer of the internet. Creating a more accessible and easy-to-use interface (XML standard) will make whipping up “functional” websites accessible to a much wider audience.
  3. This XML standard can act as a glue layer for GUIs and many other apps that generate web apps.
  4. There could be uses that we cannot yet imagine for this standard. Particular implementations lock you into one usage.
  5. It would be pretty natural mix-in HTML for formatting purposes.

What’s the advantage of using a code generator that uses this standard?

  1. Functional, database-driven web apps will be easy to make for non programmers.
  2. If you are a programmer, it will save you a lot of coding time….hopefully.
  3. Since the output is code, it will always be open ended and you can customize your app to your heart’s content if you’re a programmer or have access to programmers in the target language. People are always going to want to customize their application to the nth degree. Having access to the code will allow you to do this.

What do you envision as an interface for the creator of a website? I would like to see users install the code generator as a web app on their site. Once you upload your WAML file, the code generator updates the server-side code and database. Then just point your browser to the homepage of the site. An improvement on this interface would be a GUI that generates the XML for you. steps. Sample next steps(leaps)/features:

The next step would be to flesh out the above example in baby
  1. It would be interesting to see how to express comments on blog entries. (baby step)
  2. User registration and different access levels would also be interesting. (toddler step)
  3. I’d like to have a nice and simple email notification/integration system for email verification of user sign up. (pretty easy I think)
  4. It would be nice to have a place to collect business rules…. like a way to describe bank work days…. it’s hard to imagine for me how it would be implemented in an automatic way though. Maybe some of you more experienced guys have insight into this. (ambitious)

    Anyway, I’d love to hear your guys’ feedback. If you think it’s

    useless, misdirected or naive, that’s great—please educate me! My ego is not attached to this whatsoever. If it’s been done before, I’d like to know too. Feel free to say whatever you like, I’d love to hear comments either way. If you want to work on it go ahead. It’s open source.

DPP: > dogscape.com… > about 1,000 lines of Java code and 1,500 lines of XML code. It took me > about 2 weeks to build it and the most complex code is the image caching

To me that says a lot about potential productivity gains and is very inspiring. Why not make SmartMode open source? Or abstract an XML standard out of it?

because the target audience of your DSL is developers.

Developers are a subset of my target audience. Actually, my intended target audience is anybody capable of using HTML and/or Excel—Ie. anybody capable of left-brain thinking. I think that’s probably a much larger number of people than the number of developers in the world. Ultimately developers will have to go in there and customize real world apps, so for developers this will probably (in my imagination) be used as a productivity enhancement tool, e.g. an interface for scaffolding maybe.

Learning new tags in XML is a serious learning curve.

I think if the tags are aesthetically pleasing, short-and-sweet, and named well, it probably won’t be too bad. It’s all about the beauty of code… like left-brained poetry.

Dave, what did your 1500 lines of XML look like?

WW:

Very cool idea.

Wow thanks! Okay, suddenly my ego is becoming attached to this idea.

What about when you add or change attributes to your DB schema? Would there be a way to handle moving data from the old to the new version?

The only problem that I see there is in trying to distinguish between wanting to rename a column, deleting a column, and adding a column. Say you wanted to rename a column from contact_number to phone number.

Old version w/ exisiting data in the database:

< model>
< entity name="person">
< attribute name="contact_number" type="text">
< /entity>
< /model>

New version:

< model>
< entity name="person">
< attribute name="phone_number" old_name="contact_number" type="text">
< /entity>
< /model>

But then you wouldn’t need the old_name attribute anymore after the renaming process. So as not to be annoying, maybe, after successfully renaming the column, the web app would automatically know that the old_name attribute wasn’t needed and delete

old_name="contact_number"

when trying to export the model XML. If you wanted to change the type of the data, then you could probably rely on MySQL’s built-in ability to coerce types from one data type to another. Anything fancier than that I would say is beyond the initial scope of this project, and in that case you would probably have to do some massaging of data yourself.

If you don’t put the old_name attribute in there, columns that didn’t exist in the previous version will be created, and columns that existed in the previous version but don’t in the new version would automatically be destroyed with all the data in it. (“Ouch!”—you might be thinking. Well, okay, then program in a versioning system (like migrations in Rails) along with an occasional mysqldump.)

WH: > you need to be able to drill down to do custom stuff, or else you’re > limiting what’s possible

Embedding it in another language is a good solution for programmers, who want to enhance their programming environment. Personally, I think readability would plummet and you would muddy the applicaiton/requirements level with low level stuff that nobody but developers would want to see. That’s one reason why I favor code generation. Code generation would still enable you to customize your app to the N-th degree in your target language (say, Lift ;) while keeping the application-level XML files separate from the detailed developer’s world of plumbing and gadgetry.

Goal: To describe a blog website for 2 levels of access. ENHANCEMENT: adding comments to articles.

  1. Owner
  2. Reader

Usage scenario outline:

Admin pages:
  • Owner creates a blog entry.
  • Owner edits a blog entry.
  • Owner deletes a blog entry from a list with confirmation.
Public pages:
  • Reader sees titles only of the most recent 10 pages on the homepage.
  • Reader clicks on an individual title.
  • Reader reads a blog entry. Blog entry contains a list of comments previously created by readers.
  • Reader can browses by month, year on the homepage.
< fbuwaml>
< model>
< entity name="blog" has_many="comment">
< attribute name="title" type="string" />
< attribute name="body" type="text" />
< attribute name="created_on" type="datetime" />
< /entity>
< entity name="comment">
< attribute name="name" type="string" />
< attribute name="body" type="text" />
< attribute name="created_on" type="datetime" />
< /entity>
< /model>
< pages>
< public_pages>
< home_page title="Hello Blog World">
Welcome to David Beckwith's blog.  I hope you enjoy your stay.
< br />
Recent entries: < br />
< list from="blog" order="created_on descending" position="left-half" 
limit="10">
< link content="title" to="blog-detail-page">
< /list>
Browse by date: 
< list from="blog" order="date descending" position="right-half" limit="40">
< link content="date" to="blog-detail-page">
< /list>
< /home_page>
< page name="blog-detail-page" from="blog">
< text content="title" />
< text content="body" />
< list from="blog.comment" >
< text content="name"> said on :
< text content="blog.comment.body">
< /list>
< link label="Home" to="homepage">
< /page>
< /public_pages>
< admin_pages password_protected="true" password="abc123">
< page name="admin-home">
< link content="Create a new blog" to="create-blog-page">
< list from="blog" order="created_on descending" per_page="20">
< text content="blog.title">
< button label="Edit" redirect_to="blog-edit-page">
< button label="Delete" action="delete" confirm="Are you sure you want to 
delete this blog entry?">
< /list>
< /page>
< page name="create-blog-page">
< input label="Title: " target="blog.title" />
< input label="Body: " target="blog.body" />
< submit label="Save" redirect_to="admin-home" />
< /page>
< page name="blog-edit-page">
< edit label="Title: " target="blog.title" />
< edit label="Body: " target="blog.body" />
< submit label="Save" redirect_to="admin-home" />
< /page>
< /admin_pages>
< /pages>
< /fbuwaml>

Posted by David Beckwith on Saturday, May 19, 2007