Managing XML Files With Sublime Text 2
The challenge this week: to get started with creating the simplest CMS for recipes. This week’s challenge includes setting things in motion using simple ST2 templates.
- part 1: Managing XML Files With Sublime Text 2
- part 2: Fetching Google Spreadsheets as XML
- part 3: Transforming plists into XML
- part 4: creating a RESTful Python API With Bottle
About the challenge
This is part of an ongoing project, a simple recipe manager. I already have a bunch of recipes in various formats which I want to consolidate, manage, and print using an existing HTML template I am happy with. To start things off I will use Sublime Text 2’s templating and build tools to edit files quickly.
Some artefacts are available on GitHub.
Data storage
XML is pretty much the most flexible data format I can think of. It can be XSL-transformed easily into other formats, including HTML. And it can be viewed directly in a web browser as well. In theory I could apply a CSS directly to it, but I already have HTML / CSS I am happy with, so I’d rather transform the XML to that.
The document structure will be very simple, a bunch of tags (title, descriptions, source, etc) only a few of which have another level of subtags of their own - ingredients, directions, tags, and cuisine. A simple pseudo-YAML representation would be (* meaning ‘zero or more of this node’, and ? meaning ‘optional node’)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Using Sublime Text 2 to manage XML files
1 2 3 4 | |
To hit the ground running and create some XML files quickly before the app is ready, I will use Sublime Text 2 for managing files.
Using Sublime Text 2 File templates and snippets
1 2 3 4 5 6 7 8 9 10 | |
The File Templates package extends the built in Snippet system to file creations. This scenario is about setting it up and using it.
- I created my Sublime project
- I installed the File Templates package using ST2 Package Control
- Created my template in Packages / User. Sadly, templates are global, they can’t be project specific. However, the template can point to a file which can sit somewhere within the currently opened project if needed, which is handy. In my case I just hardcoded the complete path as I will never use those templates for anyhing else.
- Another handy thing with the templates is that you can set up some variables, and when you create a new file ST2 will show field names for each of them. I am not entirely sure how more useful than tab stops this feature is in this particular case, but worth trying it out anyway.
- My template is below. The actual template is in a file called recipe.xml in my project. The arguments node lists all the variables I will be asked about when creating a new file. One of them, $name, will be used to save the file as.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
- The XML template itself is pretty simple. It includes a link to an xsl document for transforming, tabstops, and a few step nodes. The ingredient nodes, being slightly more complex, will sit in a snippet.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | |
- For the ingredients, I created a ST2 snippet for each ingredient. As the snippet content is inside a CDATA node, I couldn’t find a way to have CDATAs within in it. I will have to remember to use XML entities there.
1 2 3 4 5 6 7 8 9 10 11 12 | |
- Tested, and everything works as expected.
Viewing and printing the recipe
1 2 3 4 5 | |
- I am not a fan of applying css directly to XML, so I will use XSL instead to transform the XML to the HTML template I already have. The only snag is that the XML has to be served from a web server, as some browsers don’t allow XML to load XSL locally.
- That’s not a problem though, as I already have Apache running locally, so I simply created a folder for the recipes there, and an _assets folder with my XSL / CSS / imagas.
- The XSL is basically the HTML document I already had, pasted in a template that matches the root node, with a lot of value-ofs for variable substitution and a couple of for-each loops for steps and ingredients. I don’t print out meta information, as it uses valuable space, so these are not needed in the output.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | |
- I add a link to the XSL inside the XML template
1 2 3 | |
- I created a couple of recipes manually, loaded them in browsers, and tried to print them. It all looks good.
Challenge 100% complete
That was a simple quick job. It is actually quite a quick way to do data entry, but of course I am limited to using one machine. In part 2 I will start importing some data into it.
Some artefacts are available on GitHub.