|
From: | Amirouche Boubekki |
Subject: | Re: sfx: baby steps of an html templating engine based on skribillo's skribe reader and sxml |
Date: | Fri, 31 Jul 2015 14:03:42 +0200 |
User-agent: | Roundcube Webmail/1.1.2 |
Here an exemple use in scheme code: ;;; ;;; This requires at least a `index.sfx` file and `person.scm` where ;;; a `<person>` record is defined. ;;; ;; (use-modules (person)) ;; (define persons (list (make-person "amirouche" 30) ;; (make-person "julien" 30) ;; (make-person "mez" 27) ;; (make-person "moh" 113))) ;; (define bindings `((value ,(make-parameter 42)) ;; (title '(h1 "Héllo (again (and again)) hacker!")) ;; (persons ,persons))) ;; (with-output-to-file "index.html" ;; (lambda () (render "index.sfx" bindings))) I attached the updated `sfx.scm` with required files to test it.There still one area where it can be improved regarding template resolution/finding. Right now it simply look for templates according the default `(open)` behavior which looks
in cwd (current working directory). Best regards Le 2015-07-30 18:52, Amirouche Boubekki a écrit :
Le 2015-07-30 13:55, Amirouche Boubekki a écrit :Héllo, I've been lurking around skribillo and artanis. I don't really like the rails-like syntax of artanis, even if it has its use-cases and I wanted to hack on something "small", so I've put together sfx. The code of skribe reader is included in sfx.scm. So the only dependency is guile (2.0.11) andguile-reader that you can install using `guix package -i guile-reader`.This bare template language has the following features: - wanna be simpler sxml syntax - templates with custom environment - external libraries loading inside the template # Wanna be simpler sxml syntaxSkribe reader (implemented with guile-reader) provide a handy syntax toboth define keywords and quasiquote. In an sxml context those features are used to implemented attributes and text nodes. ## attributes Attributes in sxml are defined as follow: (div (@ (id "shell")) "This the main area")Instead of requiring the nesting of `(attribute-name attribute-value)` sfx usethe simpler keyword syntax `:keyword`. The above snippet becomes: (div (@ :id "shell") "This the main area") I'm not sure it's worth the trouble of diverting from sxml standard. That said, it looks more like plain xml. ## text nodes Text nodes can be defined as (p [héllo hacker]) This is looks the same as the default reader. It becomes handy when you include an inline element inside the text node: (p [héllo ,(b [hacker]) `,()` is a special syntax of skribe reader which provides `(unquote)` inside [bracket] `quasiquote`. With the default guile reader, this must be written as: (p "héllo " (b "hacker"))This is looks verbose and prone to error. One must not forget the space in thestring before the `(b)` element. # templates with custom environment Right now this part of the template language is not really userfriendly. But you can pass custom variables to the template but those must be parameters. In the example sfx.scm (which includes example use of the procedures) the environment in which the template is evaled is defined as follow: (define value (make-parameter 42)) (define amirouche (make-person "amirouche" 30)) (define env (let ((value value) (amirouche amirouche)) (the-environment))) Then `value` can be echo'ed inside the template using the unquote syntax `,()`, e.g. (p [Here is a lucky number for you «,(value)»]) As you can see the previous snippet, there is also a `<record>` record inside the environment. One can (maybe) provide in the environment the required procedures to echo the correct fields but this is verbose. Instead sfx use `(use-modules)` inside the template definition file. This is presented in the following and last part. # external libraries loading inside the template Currently it's (only) possible to do `(use-modules)` inside the template file. The template file looks like the following: ``` (use-modules (person)) `(html (body (p [My name is ,(person-name amirouche)]))) ``` I could not make procedure definition work inside the template, this my be linked to the way I eval the template. It's shame because for quick and dirty hacks it can be handy like defining mini-templates inside the big template. This is my second try at this and having a look at the code of haunt [1] was helpful. Hope this helps! [1] https://git.dthompson.us/haunt.gitSorry for the double posting. This mail is not a duplicate. I though that the implementation `extend` would be more involving. `extend` is the dual of `include`. Given a base template `base.sfx` you define placeholders say `,(main)` and `,(sidebar)` and the rest is the "shell" of the application ie. the part of GUI that is always the same over the application. If `index.sfx` inherit `base.sfx` the context in which `base.sfx` is rendered is the same as the context used to render `ìndex.sfx` plus the variables defined/passed in `ìndex.sfx` to `base.sfx`. In the following example, `title` and `intro` are evaled and then added to `(current-module)` environment with which `base.sfx` is rendered. (extend "base.sfx" (current-module) `((title `(h1 [Héllo again hacker!!]))(intro "This is a little presentation of sfx template language")))I don't how to make `(current-module)` disappear but it's also more explicit. I'm not sure. `extend` implement a pattern similar to inheritance in OOP. I attach complete code with an example. There is small doc in the header of the file.
-- Amirouche ~ amz3 ~ http://www.hyperdev.fr
sfx.scm
Description: Text document
base.sfx
Description: Text document
index.sfx
Description: Text document
person.scm
Description: Text document
[Prev in Thread] | Current Thread | [Next in Thread] |