;; (in-package #:cl-user) (defpackage #:rails-to-caveman.view (:use #:cl) ;; #:rails-to-caveman.locale) (:import-from #:rails-to-caveman.config #:*template-directory*) (:import-from #:caveman2 #:*response* #:response-headers) (:import-from #:djula #:add-template-directory #:compile-template* #:render-template* #:*djula-execute-package*) (:import-from #:datafly #:encode-json) (:export #:render #:render-json)) (in-package #:rails-to-caveman.view) (djula:add-template-directory *template-directory*) (defparameter *template-registry* (make-hash-table :test 'equal)) (defun render (template-path &optional env) (let ((template (gethash template-path *template-registry*))) (unless template (setf template (djula:compile-template* (princ-to-string template-path))) (setf (gethash template-path *template-registry*) template)) (apply #'djula:render-template* template nil env))) (defun render-json (object) (setf (getf (response-headers *response*) :content-type) "application/json") (datafly:encode-json object)) ;; ;; Execute package definition (defpackage rails-to-caveman.djula (:use #:cl #:3bmd #:rails-to-caveman.locale #:cl-who) (:import-from #:caveman2 #:url-for) (:import-from #:cl-ppcre #:regex-replace-all) (:export #:title! ; Added in Chapter 3 (Mockup section). #:date-options )) ;; in-package and let code added in Chapter 3, also. This is ;; preperation for Switching Layout Templates section. (in-package #:rails-to-caveman.djula) ; Make sure this states your app name. (let(title) (defun title! (&optional sub) (if sub (format nil "~@[~A - ~]~:(~A~)" (setf title sub) ;; Make sure find-system states your app name. #.(asdf:coerce-name(asdf:find-system :rails-to-caveman))) title))) ; End of Chapter 3 additional code. (setf djula:*djula-execute-package* (find-package :rails-to-caveman.djula)) ;;; This is a custom filter which is was added in Chapter 3 ;;; (Routing). Apparently, this is a filter which is part of the djula ;;; project's TODOs. This filter is used in 'step13.html' (in ;;; /templates directory). (djula::def-filter :break(it) (cl-ppcre:regex-replace-all #\newline it "
")) (djula::def-filter :i18n(it) (rails-to-caveman.locale::with-i18n (rails-to-caveman.locale::rails-to-caveman (rails-to-caveman.locale::find-acceptable-locale (rails-to-caveman.locale::parse-accept-language (rails-to-caveman.locale::accept-language)))) it)) (djula::def-filter :simple-format (it) (with-output-to-string (s) (3bmd:parse-string-and-print-to-stream (cl-ppcre:regex-replace-all #\newline it "
") s))) #| LACK OF 'DJULA' DOES NOT MEAN IT IS NOT PART OF IT (date-options) ==================================================================== Even though it does not have 'djula' attached to it. This is a filter which is applied in '/templates/articles/forms.html' primarily. The guide (Chapter 9) does not state where to put this function but you get errors when you try and render the form in the browser and that is where it specifies there is no 'djula filter' function going by that name. |# (defun date-options (&key (start 0) (end 0) (target start) labels) (loop :for i :upfrom start :to end :collect (cl-who:with-html-output-to-string(*standard-output*) ((:option :value i :selected (when(eql i target) "selected")) (princ (if labels (aref labels i) i)))) :into options :finally (return (format nil "~{~A~%~}" options))))