Runtime Selection of a Implementation

Hi All

I’m still finding my way around Clojure but wondered if someone with more experience might be able to point me in the right direction.

I love Hiccup for HTML markup and have used it to write my own functions to generate Bootstrap styled components - nothing fancy just things like text input with the correct classes applied. I then got to thinking what if someone wanted to use Hiccup with semantic-ui or some other CSS framework? I then wondered if you could do this in a generic way so that you could somehow define which CSS framework you wanted to use and call a generic function like create-text-input and it would automatically apply the appropriate styling.

It “feels” to me like this is a job for Protocols/Records or mutlimethods. I’m wondering what approach someone with more Clojure experience might take to this problem?

cheers

Dave

On one hand, I feel it’s unlikely that you want to swap UI frameworks at runtime, because of the potential impact in terms of degrading user experience and also because they are not really equivalent, so I think you’d end up with the lowest common denominator rather than the union of all their features.

That being said, in terms of implementing it I think you can always take a tree of hiccup markup and apply some transformations to the class names used in the tags. I’m thinking you could start with some markup like

(def my-button
  [:div
    [:button.primary "Click me"]])

you would build a function that takes a framework name, a hiccup fragment and walks (in the clojure.walk sense) it, replacing the class names as needed so they match the framework:

(to-framework :bootstrap my-button)
;; => [:div [:button.btn.primary "Click me"]]

where you’d use the framework name to look up the rules in some big dictionary (eg. {:bootstrap {:primary :btn.primary ,,,} :semantic-ui {,,,}})

Note that this is super simplified and also unlikely to work because different CSS frameworks use different levels of nested tags for anything non-trivial (eg. you need several different divs or spans depending on the framework) … maybe using custom tags like [:button-primary ,,,] might work?

Thanks @dfuenzalida. My bad for not being clear in my original post - I didn’t think that a user would change frameworks mid application but rather have a generic set of functions that “knew” about different frameworks so I could develop my website using bootstrap but then switching to say a different UI framework didn’t involve going thorugh and changing all the css classes by hand.

I also agree that different UI frameworks have different layout semantics so this might be a bit of a pipe dream :-).

I’ll play with your suggestion though and see where I get to.

Once again - many thanks for the help.

cheers

Dave

Conceptually simple: just define an abstract notation that you can transform algorithmically to any of your favorite presentation notations. Then write the transformations. An example of this from a century ago is DocBook, which excited a cottage industry of transformations to text, Perl POD, LaTex, HTML, RTF, PDF…

And there is a Clojure connection! A marvelous library for “HTML-ish” to “HTML-ish” notation transformations is Christophe Grand’s “Enlive”.