Merge branch 'main' of git.sr.ht:~marcuskammer/dev.metalisp.sbt

This commit is contained in:
Marcus Kammer 2024-02-13 16:55:06 +01:00
commit d7301662ad
11 changed files with 696 additions and 9 deletions

View file

@ -1,7 +1,7 @@
#+title: Creating a Questionnaire using cl-sbt/questionnaire Macros in a Web Application #+title: Creating a Questionnaire using cl-sbt/questionnaire Macros in a Web Application
#+author: Marcus Kammer #+author: Marcus Kammer
#+email: marcus.kammer@mailbox.org #+email: marcus.kammer@mailbox.org
#+date: 2024-02-04T13:11+01:00 #+date: 2024-02-10T12:45+01:00
* Introduction * Introduction
Questionnaires are powerful tools for gathering information and insights from Questionnaires are powerful tools for gathering information and insights from
@ -22,7 +22,7 @@ like single-choice, multiple-choice, or open-ended questions.
- Multiple Choice: Questions that allow multiple answers. - Multiple Choice: Questions that allow multiple answers.
- Text: Open-ended questions for free text input. - Text: Open-ended questions for free text input.
* Integrating cl-sbt/questionnaire Macros * Integrating dev.metalisp.sbt/component/questionnaire Macros
To create a questionnaire in your Common Lisp web application, To create a questionnaire in your Common Lisp web application,
cl-sbt/questionnaire macros can be employed. These macros generate the HTML cl-sbt/questionnaire macros can be employed. These macros generate the HTML

View file

@ -0,0 +1,110 @@
<!DOCTYPE html>
<html lang=en data-bs-theme=dark>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width, initial-scale=1">
<title>Product Experience Survey</title>
<link rel=stylesheet type=text/css
href=https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css>
</head>
<body>
<h1 class=visually-hidden>Product Experience Survey</h1>
<main class=container>
<form class=py-5 action=/submit method=post>
<fieldset>
<legend>How often do you use our software?</legend>
<ol>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-beh-useage"
for=group-beh-useage-daily>
<input class=form-check-input type=radio name=group-beh-useage
value=daily id=group-beh-useage-daily> Daily</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-beh-useage"
for=group-beh-useage-weekly>
<input class=form-check-input type=radio name=group-beh-useage
value=weekly id=group-beh-useage-weekly> Weekly</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-beh-useage"
for=group-beh-useage-monthly>
<input class=form-check-input type=radio name=group-beh-useage
value=monthly id=group-beh-useage-monthly> Monthly</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-beh-useage"
for=group-beh-useage-lessfrequently>
<input class=form-check-input type=radio name=group-beh-useage
value=less-frequently id=group-beh-useage-lessfrequently> Less frequently</label>
</div>
</ol>
<hr class=my-4>
</fieldset>
<fieldset>
<legend>What features do you use the most?</legend>
<ol>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-beh-feature"
for=group-beh-feature-bookmarks>
<input class=form-check-input type=checkbox name=group-beh-feature
value=bookmarks id=group-beh-feature-bookmarks> Bookmarks</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-beh-feature"
for=group-beh-feature-kpi>
<input class=form-check-input type=checkbox name=group-beh-feature
value=kpi id=group-beh-feature-kpi> KPI</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-beh-feature"
for=group-beh-feature-contacts>
<input class=form-check-input type=checkbox name=group-beh-feature
value=contacts id=group-beh-feature-contacts> Contacts</label>
</div>
</ol>
<hr class=my-4>
</fieldset>
<fieldset>
<legend>Have you used our software for along period of time?</legend>
<ol>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-beh-longuse"
for=group-beh-longuse-yes>
<input class=form-check-input type=radio name=group-beh-longuse
value=yes id=group-beh-longuse-yes> Yes</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-beh-longuse"
for=group-beh-longuse-no>
<input class=form-check-input type=radio name=group-beh-longuse
value=no id=group-beh-longuse-no> No</label>
</div>
</ol>
<hr class=my-4>
</fieldset>
<button class="btn btn-primary" type=submit>Submit</button>
</form>
</main>
<script
src=https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js></script>
</body>
</html>

View file

@ -0,0 +1,148 @@
<!DOCTYPE html>
<html lang=en data-bs-theme=dark>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width, initial-scale=1">
<title>Product Experience Survey</title>
<link rel=stylesheet type=text/css
href=https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css>
</head>
<body>
<h1 class=visually-hidden>Product Experience Survey</h1>
<main class=container>
<form class=py-5 action=/submit method=post>
<fieldset>
<legend>What is your age range?</legend>
<ol>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-demo-age-range"
for=group-demo-age-range-1824>
<input class=form-check-input type=radio name=group-demo-age-range
value=18-24 id=group-demo-age-range-1824> 18-24</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-demo-age-range"
for=group-demo-age-range-2534>
<input class=form-check-input type=radio name=group-demo-age-range
value=25-34 id=group-demo-age-range-2534> 25-34</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-demo-age-range"
for=group-demo-age-range-3544>
<input class=form-check-input type=radio name=group-demo-age-range
value=35-44 id=group-demo-age-range-3544> 35-44</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-demo-age-range"
for=group-demo-age-range-4554>
<input class=form-check-input type=radio name=group-demo-age-range
value=45-54 id=group-demo-age-range-4554> 45-54</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-demo-age-range"
for=group-demo-age-range-55>
<input class=form-check-input type=radio name=group-demo-age-range
value=55+ id=group-demo-age-range-55> 55+</label>
</div>
</ol>
<hr class=my-4>
</fieldset>
<fieldset>
<legend>What is your gender?</legend>
<ol>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-demo-gender"
for=group-demo-gender-male>
<input class=form-check-input type=radio name=group-demo-gender
value=male id=group-demo-gender-male> Male</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-demo-gender"
for=group-demo-gender-female>
<input class=form-check-input type=radio name=group-demo-gender
value=female id=group-demo-gender-female> Female</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-demo-gender"
for=group-demo-gender-nonbinary>
<input class=form-check-input type=radio name=group-demo-gender
value=non-binary id=group-demo-gender-nonbinary> Non-binary</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-demo-gender"
for=group-demo-gender-prefernottosay>
<input class=form-check-input type=radio name=group-demo-gender
value=prefer-not-to-say id=group-demo-gender-prefernottosay> Prefer not to say</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-demo-gender"
for=group-demo-gender-other>
<input class=form-check-input type=radio name=group-demo-gender
value=other id=group-demo-gender-other> Other</label>
</div>
<li>
<!-- FORM/CTRL -->
<div class=mb-3>
<label class="form-label group-demo-gender"
for=group-demo-gender-other>Other</label>
<input class=form-control id=group-demo-gender-other type=text
name=group-demo-gender>
</div>
</ol>
<hr class=my-4>
</fieldset>
<fieldset>
<legend>What is your profession?</legend>
<ol>
<li>
<!-- FORM/CTRL -->
<div class=mb-3>
<label class="form-label group-demo-profession"
for=group-demo-profession-profession>Profession</label>
<input class=form-control id=group-demo-profession-profession
type=text name=group-demo-profession>
</div>
</ol>
<hr class=my-4>
</fieldset>
<fieldset>
<legend>What is your educational background?</legend>
<ol>
<li>
<!-- FORM/CTRL -->
<div class=mb-3>
<label class="form-label group-demo-edu"
for=group-demo-edu-lastdegree>Last Degree</label>
<input class=form-control id=group-demo-edu-lastdegree type=text
name=group-demo-edu>
</div>
</ol>
<hr class=my-4>
</fieldset>
<button class="btn btn-primary" type=submit>Submit</button>
</form>
</main>
<script
src=https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js></script>
</body>
</html>

View file

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang=en data-bs-theme=dark>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width, initial-scale=1">
<title>Product Experience Survey</title>
<link rel=stylesheet type=text/css
href=https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css>
</head>
<body>
<h1 class=visually-hidden>Product Experience Survey</h1>
<main class=container>
<form class=py-5 action=/submit method=post>
<fieldset>
<legend>Where are you located?</legend>
<ol>
<li>
<!-- FORM/CTRL -->
<div class=mb-3>
<label class="form-label group-geo-loca" for=group-geo-loca-country>Country</label>
<input class=form-control id=group-geo-loca-country type=text
name=group-geo-loca>
</div>
</ol>
<hr class=my-4>
</fieldset>
<fieldset>
<legend>Which timezone do you operate in?</legend>
<ol>
<li>
<!-- FORM/CTRL -->
<div class=mb-3>
<label class="form-label group-geo-timezone"
for=group-geo-timezone-timezone>Timezone</label>
<input class=form-control id=group-geo-timezone-timezone type=text
name=group-geo-timezone>
</div>
</ol>
<hr class=my-4>
</fieldset>
<button class="btn btn-primary" type=submit>Submit</button>
</form>
</main>
<script
src=https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js></script>
</body>
</html>

View file

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang=en data-bs-theme=dark>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width, initial-scale=1">
<title>Product Experience Survey</title>
<link rel=stylesheet type=text/css
href=https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css>
</head>
<body>
<h1 class=visually-hidden>Product Experience Survey</h1>
<main class=container>
<form class=py-5 action=/submit method=post>
<fieldset>
<legend>What challenges, if any, does our software help you overcome?</legend>
<ol>
<li>
<!-- FORM/CTRL -->
<div class=mb-3>
<label class="form-label group-nc-challenges"
for=group-nc-challenges-pleasedescribe>Please describe</label>
<input class=form-control id=group-nc-challenges-pleasedescribe
type=text name=group-nc-challenges>
</div>
</ol>
<hr class=my-4>
</fieldset>
<fieldset>
<legend>How could we improve to better meet your needs?</legend>
<ol>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-nc-improve"
for=group-nc-improve-pleasedescribe>
<input class=form-check-input type=radio name=group-nc-improve
value=please-describe id=group-nc-improve-pleasedescribe> Please describe</label>
</div>
</ol>
<hr class=my-4>
</fieldset>
<button class="btn btn-primary" type=submit>Submit</button>
</form>
</main>
<script
src=https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js></script>
</body>
</html>

View file

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang=en data-bs-theme=dark>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width, initial-scale=1">
<title>Product Experience Survey</title>
<link rel=stylesheet type=text/css
href=https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css>
</head>
<body>
<h1 class=visually-hidden>Product Experience Survey</h1>
<main class=container>
<form class=py-5 action=/submit method=post>
<fieldset>
<legend>What do you value most in our software?</legend>
<ol>
<li>
<!-- FORM/CTRL -->
<div class=mb-3>
<label class="form-label group-psy-value"
for=group-psy-value-mostvalue>Most value</label>
<input class=form-control id=group-psy-value-mostvalue type=text
name=group-psy-value>
</div>
</ol>
<hr class=my-4>
</fieldset>
<fieldset>
<legend>What motivates you to use our software?</legend>
<ol>
<li>
<!-- FORM/CTRL -->
<div class=mb-3>
<label class="form-label group-psy-motivate"
for=group-psy-motivate-yourmotivation>Your motivation</label>
<input class=form-control id=group-psy-motivate-yourmotivation
type=text name=group-psy-motivate>
</div>
</ol>
<hr class=my-4>
</fieldset>
<button class="btn btn-primary" type=submit>Submit</button>
</form>
</main>
<script
src=https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js></script>
</body>
</html>

View file

@ -0,0 +1,124 @@
<!DOCTYPE html>
<html lang=en data-bs-theme=dark>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width, initial-scale=1">
<title>Product Experience Survey</title>
<link rel=stylesheet type=text/css
href=https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css>
</head>
<body>
<h1 class=visually-hidden>Product Experience Survey</h1>
<main class=container>
<form class=py-5 action=/submit method=post>
<fieldset>
<legend>How would you rate your comfort level with technology?</legend>
<ol>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-tcl-likeart"
for=group-tcl-likeart-1veryuncomfortable>
<input class=form-check-input type=radio name=group-tcl-likeart
value=1---very-uncomfortable
id=group-tcl-likeart-1veryuncomfortable> 1 - Very Uncomfortable</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-tcl-likeart"
for=group-tcl-likeart-2slightlyuncomfortable>
<input class=form-check-input type=radio name=group-tcl-likeart
value=2---slightly-uncomfortable
id=group-tcl-likeart-2slightlyuncomfortable> 2 - Slightly Uncomfortable</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-tcl-likeart"
for=group-tcl-likeart-3neutral>
<input class=form-check-input type=radio name=group-tcl-likeart
value=3---neutral id=group-tcl-likeart-3neutral> 3 - Neutral</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-tcl-likeart"
for=group-tcl-likeart-4quitecomfortable>
<input class=form-check-input type=radio name=group-tcl-likeart
value=4---quite-comfortable
id=group-tcl-likeart-4quitecomfortable> 4 - Quite Comfortable</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-tcl-likeart"
for=group-tcl-likeart-5verycomfortable>
<input class=form-check-input type=radio name=group-tcl-likeart
value=5---very-comfortable
id=group-tcl-likeart-5verycomfortable> 5 - Very Comfortable</label>
</div>
</ol>
<hr class=my-4>
</fieldset>
<fieldset>
<legend>How frequently do you adopt new technologies?</legend>
<ol>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-tcl-adopt"
for=group-tcl-adopt-alwaysimanearlyadopter>
<input class=form-check-input type=radio name=group-tcl-adopt
value=always---i&#39;m-an-early-adopter.
id=group-tcl-adopt-alwaysimanearlyadopter> Always - I&#39;m an early adopter.</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-tcl-adopt"
for=group-tcl-adopt-oftenistayontopoftechnologicaladvancesandadoptthemfrequently>
<input class=form-check-input type=radio name=group-tcl-adopt
value=often---i-stay-on-top-of-technological-advances-and-adopt-them-frequently.
id=group-tcl-adopt-oftenistayontopoftechnologicaladvancesandadoptthemfrequently> Often - I stay on top of
technological advances and adopt them frequently.</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-tcl-adopt"
for=group-tcl-adopt-sometimesiadoptnewtechnologiesnowandthen>
<input class=form-check-input type=radio name=group-tcl-adopt
value=sometimes---i-adopt-new-technologies-now-and-then.
id=group-tcl-adopt-sometimesiadoptnewtechnologiesnowandthen> Sometimes - I adopt new technologies now and then.</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-tcl-adopt"
for=group-tcl-adopt-rarelyionlyadoptnewtechnologieswhenitsnecessaryforworkorotherimportanttasks>
<input class=form-check-input type=radio name=group-tcl-adopt
value=rarely---i-only-adopt-new-technologies-when-it&#39;s-necessary-for-work-or-other-important-tasks.
id=group-tcl-adopt-rarelyionlyadoptnewtechnologieswhenitsnecessaryforworkorotherimportanttasks> Rarely - I only
adopt new technologies when it&#39;s necessary for work or other important tasks.</label>
</div>
<li>
<!-- FORM/CHECKABLE -->
<div class=form-check>
<label class="form-check-label group-tcl-adopt"
for=group-tcl-adopt-neveriavoidadoptingnewtechnologiesunlessabsolutelyrequired>
<input class=form-check-input type=radio name=group-tcl-adopt
value=never---i-avoid-adopting-new-technologies-unless-absolutely-required.
id=group-tcl-adopt-neveriavoidadoptingnewtechnologiesunlessabsolutelyrequired> Never - I avoid adopting new
technologies unless absolutely required.</label>
</div>
</ol>
<hr class=my-4>
</fieldset>
<button class="btn btn-primary" type=submit>Submit</button>
</form>
</main>
<script
src=https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js></script>
</body>
</html>

View file

@ -0,0 +1,164 @@
* Create lisp package
#+begin_src lisp
(defpackage user-research-app
(:use :cl)
(:import-from :dev.metalisp.sbt :with-page)
(:import-from :dev.metalisp.sbt/pattern/questionnaire :questionnaire))
#+end_src
#+RESULTS:
: #<PACKAGE "USER-RESEARCH-APP">
* Demographics
#+name: demographics-survey
#+begin_src lisp :results output file :file-ext html
(in-package :user-research-app)
(defun generate-demographics-survey ()
"Generates an HTML page with questionnaires using questionnaire macros."
(with-output-to-string (spinneret:*html*)
(with-page (:title "Product Experience Survey" :main-con t)
(questionnaire "/submit"
(:ask "What is your age range?"
:group "demo-age-range"
:choices (:single "18-24" "25-34" "35-44" "45-54" "55+"))
(:ask "What is your gender?"
:group "demo-gender"
:choices (:single "Male" "Female" "Non-binary" "Prefer not to say" "Other" :text "Other"))
(:ask "What is your profession?"
:group "demo-profession"
:choices (:text "Profession"))
(:ask "What is your educational background?"
:group "demo-edu"
:choices (:text "Last Degree"))))))
(format t (generate-demographics-survey))
#+end_src
#+RESULTS: demographics-survey
[[file:demographics-survey.html]]
* Geographics
#+name: geographics-survey
#+begin_src lisp :results output file :file-ext html
(in-package :user-research-app)
(defun generate-geographics-survey ()
"Generates an HTML page with questionnaires using questionnaire macros."
(with-output-to-string (spinneret:*html*)
(with-page (:title "Product Experience Survey" :main-con t)
(questionnaire "/submit"
(:ask "Where are you located?"
:group "geo-loca"
:choices (:text "Country"))
(:ask "Which timezone do you operate in?"
:group "geo-timezone"
:choices (:text "Timezone"))))))
(format t (generate-geographics-survey))
#+end_src
#+RESULTS: geographics-survey
[[file:geographics-survey.html]]
* Behavioral
#+name: behavioral-survey
#+begin_src lisp :results output file :file-ext html
(in-package :user-research-app)
(defun generate-behavioral-survey ()
"Generates an HTML page with questionnaires using questionnaire macros."
(with-output-to-string (spinneret:*html*)
(with-page (:title "Product Experience Survey" :main-con t)
(questionnaire "/submit"
(:ask "How often do you use our software?"
:group "beh-useage"
:choices (:single "Daily" "Weekly" "Monthly" "Less frequently"))
(:ask "What features do you use the most?"
:group "beh-feature"
:choices (:multiple "Bookmarks" "KPI" "Contacts"))
(:ask "Have you used our software for along period of time?"
:group "beh-longuse"
:choices (:single "Yes" "No"))))))
(format t (generate-behavioral-survey))
#+end_src
#+RESULTS: behavioral-survey
[[file:behavioral-survey.html]]
* Psychographics
#+name: psychographics-survey
#+begin_src lisp :results output file :file-ext html
(in-package :user-research-app)
(defun generate-psychographics-survey ()
"Generates an HTML page with questionnaires using questionnaire macros."
(with-output-to-string (spinneret:*html*)
(with-page (:title "Product Experience Survey" :main-con t)
(questionnaire "/submit"
(:ask "What do you value most in our software?"
:group "psy-value"
:choices (:text "Most value"))
(:ask "What motivates you to use our software?"
:group "psy-motivate"
:choices (:text "Your motivation"))))))
(format t (generate-psychographics-survey))
#+end_src
#+RESULTS: psychographics-survey
[[file:psychographics-survey.html]]
* Needs/Challenges
#+name: nc-survey
#+begin_src lisp :results output file :file-ext html
(in-package :user-research-app)
(defun generate-nc-survey ()
"Generates an HTML page with questionnaires using questionnaire macros."
(with-output-to-string (spinneret:*html*)
(with-page (:title "Product Experience Survey" :main-con t)
(questionnaire "/submit"
(:ask "What challenges, if any, does our software help you overcome?"
:group "nc-challenges"
:choices (:text "Please describe"))
(:ask "How could we improve to better meet your needs?"
:group "nc-improve"
:choices (:single "Please describe"))))))
(format t (generate-nc-survey))
#+end_src
#+RESULTS: nc-survey
[[file:nc-survey.html]]
* Technology Comfort Level
#+name: tcl-survey
#+begin_src lisp :results output file :file-ext html
(in-package :user-research-app)
(defun generate-tcl-survey ()
"Generates an HTML page with questionnaires using questionnaire macros."
(with-output-to-string (spinneret:*html*)
(with-page (:title "Product Experience Survey" :main-con t)
(questionnaire "/submit"
(:ask "How would you rate your comfort level with technology?"
:group "tcl-likeart"
:choices (:single "1 - Very Uncomfortable" "2 - Slightly Uncomfortable" "3 - Neutral" "4 - Quite Comfortable" "5 - Very Comfortable"))
(:ask "How frequently do you adopt new technologies?"
:group "tcl-adopt"
:choices (:single "1 - Always - I'm an early adopter." "2 - Often - I stay on top of technological advances and adopt them frequently." "3 - Sometimes - I adopt new technologies now and then." "4 - Rarely - I only adopt new technologies when it's necessary for work or other important tasks." "5 - Never - I avoid adopting new technologies unless absolutely required."))))))
(format t (generate-tcl-survey))
#+end_src
#+RESULTS: tcl-survey
[[file:tcl-survey.html]]

View file

@ -1,8 +1,6 @@
;;;; -*- mode: lisp; coding: utf-8; tab-width: 4; fill-column: 100; indent-tabs-mode: nil; -*-
;;;; accordion.lisp ;;;; accordion.lisp
;;;; ;;;; This file defines a package for generating Bootstrap accordion components using Common Lisp macros.
;;;; This file defines a package for generating Bootstrap accordion components
;;;; using Common Lisp macros.
(defpackage dev.metalisp.sbt/component/accordion (defpackage dev.metalisp.sbt/component/accordion
(:documentation "A package for generating Bootstrap accordions.") (:documentation "A package for generating Bootstrap accordions.")
(:use :cl) (:use :cl)

View file

@ -1,6 +1,6 @@
;;;; -*- mode: lisp; coding: utf-8; tab-width: 4; fill-column: 100; indent-tabs-mode: nil; -*- ;;;; -*- mode: lisp; coding: utf-8; tab-width: 4; fill-column: 100; indent-tabs-mode: nil; -*-
;;;; main - Provide general functions. ;;;; main.lisp
;;;; Provide general functions.
(defpackage dev.metalisp.sbt (defpackage dev.metalisp.sbt
(:use :cl) (:use :cl)
(:export (:export

View file

@ -253,7 +253,7 @@ Returns multiple values:
- The group name (GROUP) - The group name (GROUP)
- The choices (CHOICES)" - The choices (CHOICES)"
(let ((splitted-list (split-list-by-keyword question))) (let ((splitted-list (split-list-by-keyword question)))
(apply #'values (mapcar (lambda (x) (cadr x)) splitted-list)))) (apply #'values (mapcar (lambda (x) (nth 1 x)) splitted-list))))
(defmacro questionnaire (action &body body) (defmacro questionnaire (action &body body)
"This macro generates an HTML form composed of multiple questions, each rendered using the `question' macro. "This macro generates an HTML form composed of multiple questions, each rendered using the `question' macro.