Introduction

In my previous post I spoke about ReST. It’s not able to do what I want, which is a nuisance. But most of the post of about coding forms such as that on the MathTran home page using Django templates. In the course of the post I come to the conclusion that providing such forms is a matter just for the template, and has nothing much to do with the view! Finally, I make some remarks about AJAX, which is used (along with some rather improper dynamic HTML) in the present implementation.

Some problems with ReST

I’m now using ReST to author content for the website, and I’m finding it awkward. I quite like to put a link to be followed at the end of a sentence. Something like: Instructions on how to do learn TeX are here. (This link is broken at the time of writing.) However, ReST does not allow me to use ‘here’ twice in the same page, but pointing to different web pages. I find that this cramps my style, and in time there will be an example here.

Here’s another problem. The new home page will have a two-column layout, with main content on the left, and news on the right. I will, of course, use CSS to do the styling. And so I have to create two content DIV’s in the body. I can do this with ReST by having separate pages for the main content and the news, and this might be the best thing to do, but I don’t want to be forced into doing that by the architecture of ReST.

Finally, on the MathTran home page there is a form, that allows users to experiment with TeX. I don’t want to hardcode this form into the ReST source for the home page, and in fact I can’t, because I’ll need Django to put some results in under the form. And so it looks as if I’ll be forced into some appalling hack, such as putting a special string such as {{ my_form }} in the ReST source, which Django can then replace by the form. In short, a tiny templating language, processing the output of ReST.

I decided to switch from authoring in HTML because it is more work than it should be. But it seems that ReST can also produce additional work.

CSS and ReST

I’m going to use the CSS float: right style to get the two-column layout, and that requires the sidebar DIV to appear before the content DIV in the HTML. This might be a design fault in HTML/CSS, but I don’t think so. In any case, this is another example of how ReST is not fitting in well with other parts of the system. In my previous post I explained how I was having to do a hack to get the title to come out right. That said, I’m pleased that I’m using CSS, and seem to be getting to grips with the separation of content and style. I’m using Simon Collison’s beginner’s book as a reference.

The TeX data entry form

The present and new MathTran home pages will have a TeX data entry form, that allows the user to experiment with MathTran. This form, perhaps with variation, will be used elsewhere on the new site. It is an important component, and it’s implementation will make more use of the framework Django provides.

On the current site the form was written using JavaScript plus dynamic HTML, and prior to that we used a CGI script. The nice thing about the JavaScript approach, besides the nice user interface is provided, is that it allowed the form to be reused across the site without copying large chunks of code.

But some users might not be able to use JavaScript, or might for good reasons prefer not to use it. I’m beginning to value more the approach, that the site should be made accessible first, and then JavaScript can be used to enhance functionality. Not using JavaScript makes the site easier to test. And now that I’m using Django with its template language, the form should be easy to reuse.

The challenge here is to refactor the existing functionality so that business logic belongs to the view, presentation belongs to the template, style belongs to the CSS style sheet, and there are sufficient hooks to allow JavaScript and dynamic HTML to replace the logic in the view.

Ajax and Django forms

It’s now Sunday 3rd February, and I’m going to summarise the progress I’ve made. First, and this is important, I now understand the problem. It is this. In the current MathTran website pages some pages contain ‘user feedback’ data entry forms, that are created using JavaScript and function using some Ajax (to get the TeX log and the depth of the image). I don’t want to rely on JavaScript in this way, because it is repeating all the problems of Dynamic HTML of a few years back, as described in Chris Heilmann’s book, which I am using as guidance for good practice. I would like to provide the existing functionality on the new site without using JavaScript, and to enhance the interface by using JavaScript, if JavaScript is available.

So that is is the description of the problem. A bit of thinking tells us why that is a problem. Django has a View + Template architecture (the Model is not used here). But the DHTML approach so to speak promotes ordinary markup into interactive elements. And so to achieve similar functionality for the author of the web page or Django template the View is not involved either. These forms provide what I have called user feedback or more specifically the opportunity to experiment with TeX and some examples. They are a matter for the author of the template/page, not the programmer of the view. In particular, they should be available on any template, just as H1 headings are available on a view.

This brings me to the thing I liked about the DHMTL approach I followed, which is that the page author supplies minimal markup, and ‘the system’ provides the rest. The page author does not have to copy-and-paste boilerplate code. This is good, but using client-side JavaScript as the system that provides the rest is not a good idea. Except it’s not clear that for ordinary users (as opposed to power users such as Djangonauts) there is an alternative to coding in ordinary HTML.

I explored the problem without properly understanding it (and with gaps in my Django knowledge), and this turned out to be a good thing to do. First of all, I coded one of these forms using the View-Template architecture. I then realised that the Template shouldn’t really be tied to the view in this way. This was particularly acute when there were to be two, three or more of these forms on a template.

Using a working example

At this point I had a working example, so I knew it could be done. Also, the example provided a helpful framework for further exploration. So the thing to do was to do everything in the Template. (I could have deduced this from an abstract analysis of the problem, but it was good to get the experience into my coding fingers, and to have a working example.) So now I was casting about, without any other route, for a way to do the form using the Template only.

At this point I recalled that a well-written template does not change any data. This is part of the design philosophy of Django templates. In Chapter 4 of The Django Book we read A template cannot set a variable or change the value of a variable and that custom template tags can be written that do allow this. So that is what I was forced into doing, by the in my view quite reasonable requirements. By the way, being trained as a mathematician, I’m quite fond of problems that have exactly one solution. In mathematics it’s often easier to find something, if you know there is only one of them to be found. So here I actually liked the way the logic of the situation forced me into a particular solution, and I also liked the solution that so appeared.

So I sat down, motivated, to write a custom template tag that did what I want, and I had something working by the end of the day. It’s not ready to post anywhere yet, but I can show you how a preliminary form of the template interface.

<form>
{% mathtran wobble %}{# Assigns a value to the variable wobble #}
<p>TeX input: {{wobble.elt}}</p>
<input type="text" name="wobble" size="50" value="{{wobble.value}}"/>
<input type="hidden" name="old_wobble" value="{{wobble.old_value}}"/>
<input type="submit" name="set_wobble" value="Try it"/>
<p>TeX output: {{wobble.img}}</p>
<p>TeX errors: {{wobble.log}}</p>

This, of course, contains a large amount of boilerplate code that should be incorporated into the behaviour and properties of the mathtran tag.

Conclusion

Coding these forms properly is more work that I thought at first, particularly if I’m to do it properly. But the payoff is likely to be code that can be reused by any Django site that wants to use the MathTran service. Finally, there is a Django wiki page on AJAX which has some useful links.

Advertisements