Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Friday, December 3, 2010

Stupid Template Languages

For years I've been absolutely certain that I really prefer stupid template languages any time I'm generating HTML. The less the template language can do the better. Since I spend most of my time coding in Python you might assume this applies just to Python, but I think it also applies to anything where you have the power to readily mix HTML generation and code.

The biggest annoyance I have with smart template languages (Mako, Genshi, Jinja2, PHP, PerlColdFusion, etc) is that you have the capability to mix core business logic with your end views, hence violating the rules of Model-View-Controller architecture. While the web can be hard to match to MVC, in general you aren't supposed to do that sort of thing. I've made the mistake of putting core logic in the wrong places in the past, but I'm proud to say I've gotten good at avoiding that particular mistake.

I don't work in a vacuum.

I often work on projects crafted by others, some who decided for arcane/brilliant/idiotic reasons to mix the kernel of their applications in template function/macros. This is only possible in Smart Template Languages! If they were using a Stupid Template Language they would have been forced put their kernel code in a Python file where it applies, not in a template that was supposed to just render HTML or XML or plain text.

What it comes down to is that Smart Template Languages designers assume that developers are smart enough to avoid making this mistake. Stupid Template Languages designers assume that developers generally lack the discipline to avoid creating horrific atrocities that because of unnecessary complexity have a bus factor of 1.

So what is a Smart Template Language?

In my own vernacular, template languages that let you write functions/macros are what I call a Smart Template Language. Some of them are brilliantly executed, the example of Jinja2 comes to mind, but invariably I suffer through abuse of its Macro control structure as implemented by others.

Misery Cubed a.k.a. Genius Template Languages

Next comes Genius Template Languages, which take things a step further. These template languages allow you to not only define functions/macros, but also let you embed unrestricted Python (or Java or Ruby or whatever) in the template. This 'feature' lets you code your entire application in the templates!  In the Python world what comes to mind is Mako and Genshi, but I'm sure there are many other tools with this 'capability'.

I like Stupid Template Languages!

Stupid Template Languages don't let you define functions/macros. They don't let you embed Python code. They barely let you define variables and often have simplistic control architectures.

For Django efforts, which is about 70% of my work, I like the Django Template Language (DTL). Since it is used by a huge community, there are a ton of useful apps which have it as a dependency. Switching away from it would mean cutting myself off from a large ecosphere of tools I can use to not reinvent the wheel.

Back in my Zope/Plone days I really, really enjoyed the Template Attribute Language (TAL) because it was stupid too. If I needed an XML generation template language and could import it easily I might consider using it again, or perhaps Chameleon, which is a new, improved version . The downside is that they come paired with another tool paired with it, METAL, which gave it macros. My own experience with METAL is that it was all too easy to do what we developers do with Smart Template Languages.

But DTL and TAL are slow!

So what?

If you want to boost your performance, first try caching. There are a ton of tools you can use, with Varnish being one I keep seeing in action. Read the docs on your favorite web framework's caching engine and apply what you learn. And Djangonauts should read up on Mike Malone as much as possible.

If after all that the site still delivers slow content and it appears to be a template language issue, then identify the bottleneck content and consider alternatives for that one portion. My favorite response is a bit of AJAX. Use your framework to render the content as JSON and have JavaScript parse it into legible content, a task which JQuery makes trivial.

Tuesday, May 11, 2010

Using modernizr to help with canvas

On my current project I've been using a little bit of the HTML5 Canvas element to provide a little bell/whistle. However, the problem with Canvas is that not all browsers support it. Out of the box though Canvas gives you a quick and handy way of dealing with that problem:

<div id="content">
    <div id="demo-space-wrapper">
        <canvas height="100" id="demo-space" width="100">
            This text is displayed if the client browser does not support HTML5 Canvas.
        </canvas>
    </div>
</div>

The problem with this approach is that if your layout expects to have an object there and your client's use of Internet Explorer doesn't include the Canvas extension then this could damage the overall feel of your layout.

And that is where Modernizr comes in to play. It is a trivial to use JavaScript library that makes it possible to detect if a browser can use Canvas or any other HTML control. So what I did was take the Modernizr Canvas detection documentation and apply it to my JavaScript. With that in hand I wrote this:

// check for canvas
if (Modernizr.canvas) {
    // We have canvas so add a rectangle
    var demospace = document.getElementById('demo-space');
    var context = demospace.getContext('2d');
    context.fillStyle = "rgb(255,0,0)";
    context.fillRect(10, 10, 10, 10)            
} else {
    // No canvas. Remove the layout space to preserve the layout.
    var ul = document.getElementById('content');
    var li = document.getElementById('demo-space-wrapper');
    ul.removeChild(li);
};

Wednesday, September 2, 2009

I want to give a class or talk at Pycon 2010

For Pycon 2010, classes/tutorials would be pretty easy are easy to cook up. I can think of two I can do, right after each other:
The first class gets you started with Django core bits and pieces. The second would show you Pinax and what things you can do with it.

The problem is that I'm not sure what to do when it comes to talks. Current ideas:
  • A reprise of our upcoming Pinax tutorial at DjangoCon
  • How to suffer through SOAP web services using Python even though REST is so much better (I might be too bitter for this one).
  • Why I like stupid template languages (expanding on a tangent of this article).
  • Lets move widgets into HTML templates and out of python code! Modern JavaScript libraries makes this easy!
  • Using JQuery + Django to make 508/WAC compliant AJAX applications
Thoughts? Suggestions?

Friday, April 17, 2009

What I learned at Pycon 2009

Why write a repetition about all the things that everyone else has documented the greatness of Pycon 2009 when I can write about the awesome stuff I learned?
  • How to use Python via XLRD and XLWT to handle truly brobdingnagian Excel files (8 million records anyone) without anything Microsoft.
  • New Internet scraping tools like html5lib and mechanize to reinforce lxml and the fading but still lovable BeautifulSoup.
  • Many awesome things about the Sphinx documentation experience.
  • That spending a day in test focused sessions is an intense experience.
  • argparse makes writing command line python interactions so much easier.
  • Good rules of thumb for breaking apart applications in not just Django, but for python modules in general.
  • Git! The Pinax community embraced Git just as I was started to work on it. I owe a lot to Brian Rosner's patient coaching, and Jannis Leidel's patience.
  • That I am addicted to checking on the Github graphs to see how I compare.
  • 15 minutes of sitting next to James Tauber gave me the grounding I wanted in JQuery event handling.
  • That people who hate XML based template languages HATE them. HATE HATE HATE.
  • Mashed potatoes and bacon pizza is yummy. And spinach and anchovy pizza rocks. Yes, I ate anchovies and oddly enough liked them.
  • I really want to teach python, Django, and Pinax. I may not be the best coder by far, but I think this could be the largest contribution I ever make to this community.
Some of what I need to follow up on
Did I miss anything? Let me know!

Thursday, April 9, 2009

Show me your open source Django blog application

Want your blog engine to be used by NASA?

Unlike everyone else in the Django world, I have not written a blog application.

Instead I want to use your blog application. Definitely for my upcoming blog transfer to my own personal site (Blogger's limitations annoy me), and possibly for use in NASA Science Mission Directorate Spacebook project. So what am I looking for in your blog?

In no particular order these are the must-haves:
  • Elegant user interface.
  • Follows Django/Python best practices.
  • Easy to integrate into another application (which should be the case if you followed the above point).
  • Code highlighting via pygments.
  • Relies on JQuery for JavaScript, and degrades properly.
  • Publishes legal RSS feeds.
  • Allows for use of several input formats (Restructured Text, Markdown, etc)
  • Hooks for integrating WYSIWYG editor
  • Allows for multiple users each with their own blog.
  • Renders humanely in FF, Safari, and IE 6, 7, and 8.
  • Any sort of decent documentation.
In no particular order these are the nice-to-haves:
  • Publishes ATOM feeds.
  • Allows for multiple users on a particular blog.
  • Already has a WYSIWYG editor.
  • Handy import/export functions that follow whatever standards Blogger might have.
Candidate killers:
  • I have my own server space. Plus, NASA has its own servers. So Google App Engine compliant blog systems need to also support the standard Django ORM.
  • I am doing this in Django/Pinax/Python/PostGreSql on Linux. Systems that do not play well there need not apply.
What do you get out of this if I pick your blog engine?

Well, as much as I am a fan of Pinax, the default blog application doesn't do everything we want it to do for Spacebook. So your application might become the blog engine used by us. And when we launch, we'll be sharing credit with anyone who contributed from the open source community to our efforts.

Edit on August 26th, 2010: I solved how to do this research by co-authoring Django Packages which gives us this handy reference. Also, at this point in time, as part of larger systems, I've written several blog systems for clients.

Thursday, February 7, 2008

Sorting by dates in Plone tables

This is a little harder than it seems, and thats because of the 'magic' of JavaScript and how it handles alphanumeric sorts. Lets your dates are rendered thus in a table (along with some other columns):

January 30, 1991
April 01, 2007
March 15, 2000
July 30, 2000

Now a user clicks on the dates column and you've got problems:

April 01, 2007
January 30, 1991
July 30, 2000
March 15, 2000

We are still sorting alphanumerically, and not by dates! Now I could jump into the Plone JavaScript and hack a fix, but that would be lots of work and would mean I would have to be able to handle any variations on localization. Not a good thing! So instead I do this:

19910130 January 30, 1991
20070401 April 01, 2007
20000315 March 15, 2000
20000730 July 30, 2000

As you can see, sorts will be accurate (albeit ugly). The way to fix the ugliness is to put a span around the ugly part and give it a style of 'display:none;'.

But why not just use the unformatted date like 2000/01/01 instead of a format without slashes?

Good question. The reason is that the Plone JavaScript has problems with forward slashes. You'll start seeing funny errors in your sorts, such as dates set in July 2000 showing up before items in June 2000. I think the JavaScript is evaluating (numbers with slashes and then sorting them as shown in this case:

2000/03/15 March 15, 2000 = 44 March 15, 2000
2000/07/30 July 30, 2000 = 7 July 30, 2000

Hence you see the mad purpose of my fix and also what happens with loosely typed languages if you are not careful.