;; See the file LICENCE for licence information. (in-package :ucw) (eval-always (shadowing-import '(cl-l10n:locale cl-l10n:locale-name) :ucw) (use-package :cl-l10n :ucw) (use-package :cl-l10n :ucw-user) (setup-readtable)) (defvar *client-timezone*) (defun reload-ucw-resources () "This method reloads the UCW resources needed by some UCW services. Invoke after your :lang package has been set up." (flet ((system-relative-pathname (system path) (merge-pathnames path (asdf:component-pathname (asdf:find-system system))))) (let ((resource-dir (system-relative-pathname :ucw (make-pathname :directory (list :relative "src" "l10n" "resources") :name :wild :type "lisp")))) (ucw.l10n.debug "Looking for UCW resources in dir ~S" resource-dir) (dolist (resource-file (directory resource-dir)) (ucw.l10n.info "Loading UCW resource file ~S" resource-file) (load resource-file))))) (defmacro define-js-resources (locale &body resources) "Wraps defresources and registers the resources being defined as js resources, which means that they are going to be sent down to the client side in a cacheable js file." `(progn (register-js-resources ,@(iter (for (name . body) in resources) (when (> (length body) 1) (error "How should we send functional resources to js? ~S has arguments..." name)) (collect `',name))) (defresources ,locale ,@resources))) (defclass l10n-tal-generator (file-system-generator) () (:documentation "TAL File system generator which maps template names to files while considering the locale of the request context.")) (defmethod yaclml:template-truename ((generator l10n-tal-generator) (name pathname)) ;; first see if there's a locale specific version (when-bind locales (context.locale *context*) (ucw.l10n.debug "Looking for tal directory with locales ~A" locales) (iter (for locale in locales) (for file = (make-pathname :defaults name :directory (list :relative (locale-name locale)))) (ucw.l10n.debug "Trying tal file ~A" file) (awhen (call-next-method generator file) (ucw.l10n.debug "Found locale specific tal directory ~A" it) (return-from yaclml:template-truename it)))) ;; no locale for this context, use the default (ucw.l10n.debug "No locale specific tal directory found for locale file ~A" name) (call-next-method)) (deftag-macro (local-time &key (relative-mode t)) (<:span :class "timestamp" (<:as-html (ucw.lang:timestamp local-time :relative-mode relative-mode)))) (def-tag-handler ,filename))) (defun render-url-to-file-with-modification-timestamp (filename directory &key (url-prefix "static/") icon content) (let* ((absolute-filename (merge-pathnames filename directory))) (<:span :class "file-url" (<:a :href (concatenate 'string url-prefix (namestring filename)) (<:as-html content) (when icon (<:img :class "file-icon" :src icon))) (<:as-html " (") (ucw.lang:file-last-modification-timestamp<> absolute-filename) (<:as-html ")")))) (def-tag-handler (hash-table-count cache) (purge-cache-size-of self)) (> now (+ (last-purged-at-of self) (purge-interval-of self)))) (ucw.rerl.dispatcher.info "~S is purging its cache" self) (setf (last-purged-at-of self) now) (clrhash cache)) (let ((key (i18n-parenscript-dispatcher-cache-key))) (ucw.rerl.dispatcher.debug "~S is storing cached js with key ~S" self key) (setf (gethash key cache) value)))) ;; let's redefine the old ucw stubs, so that already expanded #""'s will work, too (defun ucw-lookup-resource (name args) (lookup-resource name args)) (defun ucw-capitalize-first-letter (str) (capitalize-first-letter str)) ;; and change the functions to be the cl-l10n versions for later expansions of the reader macro (setf *sharpquote-resource-lookup-function* 'lookup-resource) (setf *sharpquote-capitalize-first-letter-function* 'capitalize-first-letter)