6 ms·
This is a pretty interesting post, but I'm seeing a common thread in most "experience reports" regarding making a webapp in Clojure. They're all built with wit
by codewright 14y ago
This is a pretty interesting post, but I'm seeing a common thread in most "experience reports" regarding making a webapp in Clojure.
They're all built with with the presumption that the person doing the frontend work (HTML, CSS, JS) will also be doing the backend (Clojure, database) coding.
This is almost never the case in my line of work.
Hiccup violates this principle by embedding the html in my Clojure and Enlive couples markup with data tightly in ways that horrify me.
The only approach I've seen that could work for more serious projects is using stencil because then the map of data you pass to the template-side is a 'contract' of sorts, but they can work with the data you pass however it works for them.
That's somewhat regrettable as I prefer Jinja-style templating to mustache, but Stencil (mustache) is the only viable alternative I've found.
I cannot possibly be the only person with a keen interest in Clojure who hasn't abandoned division of labor.
- kinleyd 14y agoI think most of the examples assume a single developer beginning the process of learning Clojure. That would explain what appears to be the assumption that one person will be handling both the front- and back-ends because it's easier to set up simple examples this way.
- asmala 14y agoBased on my experience, Hiccup is more productive than just about anything else if the frontend person is the backend person or otherwise comfortable with Clojure. The ability to easily and cleanly define and combine abstractions in the presentation layer has been big productivity boost for me as a solo developer. As a concrete example, a small hobby project I did resulted in a fairly comprehensive library of Bootstrap helpers with very little effort: * https://github.com/asmala/giddyup https://github.com/asmala/giddyup I don't have much experience with Enlive but I find the approach is intriguing. On paper it seems perfect for clean separation of markup and logic, but you're right that careless use of the library leads to tight coupling due to the selector naming. I wonder if it would be possible to circumvent this issue using custom HTML attributes or even pseudo-CFML custom tags to indicate logical units in HTML?
- cgrand-net 14y agoEnlive's author here. I prefer to think of templates as a mapping between data and presentation. When the HTML provided by the designers changes drastically you only need to update selectors in your templates and be done with it. The same is true of the data you pass to templates: when the schema change you have to change the template. A template is both a contract on some properties of the input HTML provided by the designer and on the input data provided by the logic layer.
- asmala 14y agoGotcha. How would you handle minor HTML changes, e.g. something like this: <!-- Original --> <span class="username">joe</span> <!-- New --> <span class="username"><strong>joe</strong></span> Updating the selector in the template is easy enough but seems a bit tedious if the design team decides to go for italics next week. Another option would be adding another CSS class or a data attribute to indicate which element should wrap username. How do you usually handle such scenarios?
- cgrand-net 14y agoBy doing such a change they violates their contract. Can't you negotiate an alternative change? Eg the strong around the span or using styles instead of strong or move the username class to the strong tag? Anyway if you really want to program defensively against such changes, roll your own replacement to content fn which would replace the cornets not of the current node but of all its terminal descendants. I'd like to know more about your workflow.
- deleted 14y ago[deleted]
- asmala 14y agoMy example above was possibly too simplistic. I'm not using Enlive at the moment but am merely trying to gauge what kinds of contracts would allow the developers and designers work together most efficiently. I can imagine a fairly big difference between, for example, the following two contracts: a) "Don't touch the markup without an explicit agreement between the two of us." b) "Please make sure you have an element with a data-content-for='user.username' somewhere in the HTML."