From 58a20ed7708e65e94e063e1ef8f2170872c74c83 Mon Sep 17 00:00:00 2001 From: David Botton Date: Wed, 25 May 2022 14:00:55 -0400 Subject: [PATCH] added clob-web-site template to builder --- FUTURE.md | 7 - templates/projects/clog-web-site/README.md | 8 + templates/projects/clog-web-site/tmpl.asd.lt | 9 + templates/projects/clog-web-site/tmpl.lisp.lt | 180 ++++++++++++++++++ tools/clog-builder-settings.lisp | 7 +- 5 files changed, 203 insertions(+), 8 deletions(-) create mode 100644 templates/projects/clog-web-site/README.md create mode 100644 templates/projects/clog-web-site/tmpl.asd.lt create mode 100644 templates/projects/clog-web-site/tmpl.lisp.lt diff --git a/FUTURE.md b/FUTURE.md index 417468d..a29f869 100644 --- a/FUTURE.md +++ b/FUTURE.md @@ -1,8 +1,6 @@ - Future tutorials for builder: -Deploying a CLOG website - part in WEBSITE.md Creating a native application -Mobile development - u/eql5 has working When to use page vs panel Plug-in panels for use on other sites Demo between different models - stateless, webpage, windows @@ -13,11 +11,6 @@ Demo between different models - stateless, webpage, windows - Right click menus CLOG-GUI -- Project scaffolding generator - done the template system in Builder - 1) Basic builder project - done - 2) CLOG-GUI builder project - done - 3) Builder website - - Improvement to CLOG-GUI menus to enable/disable or switch menus based on current window/panel - Menu builder for Builder diff --git a/templates/projects/clog-web-site/README.md b/templates/projects/clog-web-site/README.md new file mode 100644 index 0000000..066ff85 --- /dev/null +++ b/templates/projects/clog-web-site/README.md @@ -0,0 +1,8 @@ +# New CLOG project +### _Your Name _ + +This is a project to do ... something. + +## License + +Specify license here diff --git a/templates/projects/clog-web-site/tmpl.asd.lt b/templates/projects/clog-web-site/tmpl.asd.lt new file mode 100644 index 0000000..89c7d19 --- /dev/null +++ b/templates/projects/clog-web-site/tmpl.asd.lt @@ -0,0 +1,9 @@ +(asdf:defsystem #:<%= (@ sys-name) %> + :description "New CLOG Websight System" + :author "some@one.com" + :license "BSD" + :version "0.0.0" + :serial t + :depends-on (#:clog) + :components ((:file "<%= (@ sys-name) %>"))) + diff --git a/templates/projects/clog-web-site/tmpl.lisp.lt b/templates/projects/clog-web-site/tmpl.lisp.lt new file mode 100644 index 0000000..7e36479 --- /dev/null +++ b/templates/projects/clog-web-site/tmpl.lisp.lt @@ -0,0 +1,180 @@ +(defpackage #:<%= (@ sys-name) %> + (:use #:cl #:clog #:clog-web #:clog-auth #:clog-web-dbi) + (:export start-app)) + +(in-package :<%= (@ sys-name) %>) + +;; +;; Setup website structure, database and CLOG +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defvar *sql-connection* nil) + +;; Default user/pass is username: admin and password: admin + +;; /content is our root content URL, if you are authorized as an +;; editor or admin you are able to add additional pages by going to +;; the url /content/whatever and then click to add page. If you want +;; it in the menu you would just need to add the url to the +;; menu. There is no need to add handlers for pages under /content as +;; when we initalized CLOG we used the option :extended-routing so +;; that a URL start with /content/ will be sent to the same handler as +;; /content in this case on-main. So our about page has no handler set +;; but functions as we added to out database. + + ; Menu Menu Item URL Handler Actions Auth +(defparameter *menu* `(("Features" (("Home" "/") + ("Login" "/login" on-login :login) + ("Signup" "/signup" on-signup :signup) + ("Change Password" "/pass" on-new-pass :change-password) + ("Content" "/content" on-main :content) + ("Logout" "/logout" on-logout :logout))) + ("Admin" (("User List" "/users" on-users :users))) + ("Help" (("About" "/content/about")))) + "Setup website menu") + +(defun start-app (&key (port 8080)) + ;; Here we add authorizations for content and editting content, not just + ;; access to pages. + (add-authorization '(:guest :member) '(:content-show-comments)) + (add-authorization '(:guest) '(:login :signup)) + (add-authorization '(:member) '(:logout + :change-password + :content-comment)) + (add-authorization '(:editor) '(:content-edit)) + (add-authorization '(:admin) '(:users :content-admin)) + ;; Setup database connection + (when *sql-connection* + (dbi:disconnect *sql-connection*)) + (let ((db-dir (format nil "~A~A" (asdf:system-source-directory :<%= (@ sys-name) %>) "<%= (@ sys-name) %>.db"))) + (setf *sql-connection* (dbi:connect :sqlite3 :database-name db-dir)) + (format t "Database location: ~A~%" db-dir)) + ;; Check if need to setup sample data + (handler-case + (dbi:fetch (dbi:execute (dbi:prepare *sql-connection* "select * from config"))) + (error () + (print "Create database and tables.") + (create-base-tables *sql-connection*) + ;; A main page was added, but let's also add an about page: + (dbi:do-sql + *sql-connection* + (sql-insert* "content" `(:key "about" + :title "About" + :value "All about this site." + :createdate (,*sqlite-timestamp*)))))) + ;; Setup clog + (initialize 'on-main + :port port + :long-poll-first t + :extended-routing t + :static-root (merge-pathnames "./www/" + (asdf:system-source-directory :<%= (@ sys-name) %>)) + :boot-function (clog-web-meta + "Some meta data about site")) + (clog-web-routes-from-menu *menu*) + ;; see clog/WEBSITE.md for directions on installing this as a webserver + (open-browser)) + +;; +;; Look and Feel +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun init-site (body) + "Setup the website, called on each url switch" + ;; Initialize the clog-web environment + (clog-web-initialize body) + ;; Instantly reload other windows open on authentication change + (set-on-authentication-change body (lambda (body) + (url-replace (location body) "/"))) + ;; Initialzie the clog-web-site environment + (let ((profile (get-profile body *sql-connection*))) + (create-web-site body + :settings '(:color-class "w3-blue-gray" + :border-class "" + :signup-link "/signup" + :login-link "/login") + :profile profile + ;; We define the roles simply if logged out a :guest + ;; if logged in a :member and if username is admin + ;; a :member, :editor and :admin. + :roles (if profile + (if (equalp "admin" + (getf profile :|username|)) + '(:member :editor :admin) + '(:member)) + '(:guest)) + :title "This site" + :footer "(c) 2022 Someone" + :logo nil))) + +;; +;; URL Path Handlers +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun on-login (body) + (init-site body) + (create-web-page + body + :login `(:menu ,*menu* + :on-submit ,(lambda (obj) + (if (login body *sql-connection* + (name-value obj "username") + (name-value obj "password")) + (url-replace (location body) "/") + (clog-web-alert obj "Invalid" "The username and password are invalid." + :time-out 3 + :place-top t)))) + :authorize t)) + +(defun on-logout (body) + (logout body) + (url-replace (location body) "/")) + +(defun on-signup (body) + (init-site body) + (create-web-page body + :signup `(:menu ,*menu* + :content ,(lambda (body) + (sign-up body *sql-connection*))) + :authorize t)) + +(defun on-main (body) + (init-site body) + (create-web-page body :index `(:menu ,*menu* + :content ,(clog-web-content *sql-connection* + :comment-table "content")))) + +(defun on-users (body) + (init-site body) + (create-web-page body :users + `(:menu ,*menu* + :content ,(lambda (body) + (let ((users (dbi:fetch-all + (dbi:execute + (dbi:prepare + *sql-connection* + "select * from users"))))) + (dolist (user users) + (let* ((box (create-div body)) + (suser (create-span box :content (getf user :|username|))) + (rbut (create-button box :content "Reset Password" + :class "w3-margin-left"))) + (declare (ignore suser)) + (set-on-click rbut (lambda (obj) + (declare (ignore obj)) + (reset-password *sql-connection* + (getf user :|username|)) + (setf (disabledp rbut) t) + (setf (text rbut) "Done")))))))) + :authorize t)) + +(defun on-new-pass (body) + (init-site body) + (create-web-page body + :change-password `(:menu ,*menu* + :content ,(lambda (body) + (change-password body *sql-connection*))) + :authorize t)) diff --git a/tools/clog-builder-settings.lisp b/tools/clog-builder-settings.lisp index 28c47b4..73e8bf2 100644 --- a/tools/clog-builder-settings.lisp +++ b/tools/clog-builder-settings.lisp @@ -1676,4 +1676,9 @@ :code "ncwp" :type :system :www "templates/www/" - :loc "templates/projects/clog-web/"))) + :loc "templates/projects/clog-web/") + '(:name "New CLOG-WEB-SITE Project" + :code "ncws" + :type :system + :www "templates/www/" + :loc "templates/projects/clog-web-site/")))