.*.deps
.*.html
+.*.json
.*.jst
.*.less
.*.min
{
+ "site_url": "https://www.ndcode.org",
"site_title": "NDCODE",
- "navigation": [
- "/index.html",
- "/contact.html",
- "/jsdoc/index.html",
- "/sphinx/index.html"
- ],
- "page_to_title": {
- "/index.html": "Home",
- "/contact.html": "Contact",
- "/jsdoc/index.html": "JSDoc",
- "/sphinx/index.html": "Sphinx"
- }
+ "contact_from": "NDCODE Contact <contact@ndcode.org>",
+ "contact_to": "Nick Downing <nick@ndcode.org>",
+ "feedback_from": "NDCODE Feedback <feedback@ndcode.org>",
+ "feedback_to": "Nick Downing <nick@ndcode.org>",
+ "copyright": "Integration Logic Pty Ltd trading as NDCODE and contributors"
}
--- /dev/null
+{
+ "entries": [
+ {"dir": "contact", "name": "Contact", "navbar": true},
+ {"dir": "jsdoc", "name": "JSDoc", "navbar": true},
+ {"dir": "sphinx", "name": "Sphinx", "navbar": true},
+ {"dir": "search", "name": "Search"}
+ ]
+}
if test $# -lt 1
then
- url=http://localhost
+ url=http://localhost:8080
else
url="$1"
fi
--- /dev/null
+let assert = require('assert')
+
+return async (env, _out) => {
+ let pathname = env.parsed_url.pathname
+ assert(pathname.slice(0, 1) === '/')
+
+ // find number of path components, their positions, and names
+ let components = [{index: 0, name: 'Home'}]
+ for (let i = 1, j; (j = pathname.indexOf('/', i)) !== -1; i = j + 1) {
+ let menu = await env.site.get_menu(`${pathname.slice(0, i)}_menu.json`)
+ let dir = pathname.slice(i, j)
+ components.push({index: j, name: menu.entries[menu.index[dir]].name})
+ }
+
+ // present components as breadcrumbs, except last one as text
+ h2 {
+ for (let i = 0; i < components.length - 1; ++i) {
+ a.text-h4(
+ href=`${pathname.slice(0, components[i].index)}/index.html`
+ ) {`${components[i].name}`}
+ ' '
+ span.text-h5 {'>'}
+ ' '
+ }
+ `${components[components.length - 1].name}`
+ }
+}
+++ /dev/null
-let querystring = require('querystring')
-let stream_buffers = require('stream-buffers')
-let XDate = require('xdate')
-
-return async env => {
- let navbar = await _require('/navbar.jst')
- let contact_form = await _require('/contact_form.jst')
-
- await navbar(
- env,
- async _out => {},
- async _out => {
- h1 {'Contact NDCODE'}
-
- div(style="height: 15px;") {}
-
- if (env.request.method == 'POST') {
- let write_stream = new stream_buffers.WritableStreamBuffer()
- let data = new Promise(
- (resolve, reject) => {
- write_stream.
- on('finish', () => {resolve(write_stream.getContents())}).
- on('error', () => {reject()})
- }
- )
- env.request.pipe(write_stream)
- let query = querystring.parse((await data).toString())
- let full_email = `${query.first_name} ${query.last_name} <${query.email}>`
- console.log('received contact form:', full_email)
-
- // save the form contents in a dated logfile, so that we can
- // recover manually if the email doesn't send for some reason
- date = new XDate()
- query.date = date.toUTCString()
-
- await env.site.ensure_dir('/_logs')
- env.site.modify_json(
- `/_logs/contact_${date.toUTCString('yyyyMMdd')}.json`,
- [],
- async result => {result.value.push(query)}
- )
-
- // send email (asynchronously)
- ;(await env.site.get_emailjs('/_config/email_contact.json')).send(
- {
- text: query.message,
- from: 'Contact form <contact@ndcode.org>',
- 'reply-to': full_email,
- to: 'Nick Downing <nick@ndcode.org>',
- subject:
- Object.prototype.hasOwnProperty.call(query, 'company') ?
- 'Enquiry: ' + query.company :
- 'Enquiry'
- },
- (err, message) => {
- if (err)
- console.error(err.stack || err.message)
- else
- console.log('sent contact email:', full_email)
- }
- )
-
- p {'Thanks! We\'ll be in touch as soon as we can.'}
- }
- else {
- p {'Do you require more information or consulting assistance with integrating the projects on this site? We\'d love to hear from you.'}
-
- await contact_form(env, _out)
- }
- }
- )
-}
--- /dev/null
+let querystring = require('querystring')
+let stream_buffers = require('stream-buffers')
+let XDate = require('xdate')
+
+return async env => {
+ let breadcrumbs = await _require('/breadcrumbs.jst')
+ let globals = await env.site.get_json('/_config/globals.json')
+ let navbar = await _require('/navbar.jst')
+
+ await navbar(
+ env,
+ async _out => {},
+ async _out => {
+ await breadcrumbs(env, _out)
+
+ if (env.request.method == 'POST') {
+ let write_stream = new stream_buffers.WritableStreamBuffer()
+ let data = new Promise(
+ (resolve, reject) => {
+ write_stream.
+ on('finish', () => {resolve(write_stream.getContents())}).
+ on('error', () => {reject()})
+ }
+ )
+ env.request.pipe(write_stream)
+ let query = querystring.parse((await data).toString())
+ console.log('received contact form:', query.email)
+
+ // save the form contents in a dated logfile, so that we can
+ // recover manually if the email doesn't send for some reason
+ date = new XDate()
+ query.date = date.toUTCString()
+
+ await env.site.ensure_dir('/_logs')
+ env.site.modify_json(
+ `/_logs/contact_${date.toUTCString('yyyyMMdd')}.json`,
+ [],
+ async result => {result.value.push(query)}
+ )
+
+ // send email (asynchronously)
+ let emailjs_contact = await env.site.get_emailjs(
+ '/_config/email_contact.json'
+ )
+ emailjs_contact.send(
+ {
+ from: globals.contact_from,
+ 'reply-to':
+ `${query.first_name} ${query.last_name} <${query.email}>`,
+ to: globals.contact_to,
+ subject:
+ Object.prototype.hasOwnProperty.call(query, 'company') ?
+ 'Enquiry: ' + query.company :
+ 'Enquiry',
+ text: query.message
+ },
+ (err, message) => {
+ if (err)
+ console.error(err.stack || err.message)
+ else
+ console.log('sent contact email:', query.email)
+ }
+ ) // ignore returned promise
+
+ p {'Thanks! We\'ll be in touch as soon as we can.'}
+ }
+ else {
+ p {'Do you require more information or consulting assistance with integrating the projects on this site? We\'d love to hear from you.'}
+
+ form#contact-form(method="post" action="index.html" role="form") {
+ div.row {
+ div.col-md-6 {
+ div.form-group {
+ label(for="contact_form_first_name") {'First name *'}
+ input.form-control#contact_form_first_name(type="text" name="first_name" placeholder="Please enter your first name" required="required" data-error="First name is required.") {}
+ div.help-block.with-errors {}
+ }
+ }
+ div.col-md-6 {
+ div.form-group {
+ label(for="contact_form_last_name") {'Last name *'}
+ input.form-control#contact_form_last_name(type="text" name="last_name" placeholder="Please enter your last name" required="required" data-error="Last name is required.") {}
+ div.help-block.with-errors {}
+ }
+ }
+ }
+ div.row {
+ div.col-md-6 {
+ div.form-group {
+ label(for="contact_form_company") {'Company'}
+ input.form-control#contact_form_company(type="text" name="company" placeholder="Please enter your company") {}
+ div.help-block.with-errors {}
+ }
+ }
+ div.col-md-6 {
+ div.form-group {
+ label(for="contact_form_email") {'Email *'}
+ input.form-control#contact_form_email(type="email" name="email" placeholder="Please enter your email" required="required" data-error="Valid email is required.") {}
+ div.help-block.with-errors {}
+ }
+ }
+ }
+ div.row {
+ div.col-md-12 {
+ div.form-group {
+ label(for="contact_form_message") {'Message *'}
+ textarea.form-control#contact_form_message(name="message" placeholder="Please explain your application" rows="4" required="required" data-error="Please, leave us a message.") {}
+ div.help-block.with-errors {}
+ }
+ }
+ }
+ p {} // fix this later
+ div.row {
+ div.col-md-12 {
+ input.btn.btn-success.btn-send(type="submit" value="Send message") {}
+ }
+ }
+ p {} // fix this later
+ div.row {
+ div.col-md-12 {
+ p.text-muted {
+ strong {'*'}
+ 'These fields are required.'
+ //'Contact form template by '
+ //a(href="https://bootstrapious.com/p/how-to-build-a-working-bootstrap-contact-form" target="_blank") {'Bootstrapious'}
+ //'.'
+ }
+ }
+ }
+ }
+ }
+ },
+ async _out => {}
+ )
+}
+++ /dev/null
-return async (env, _out) => {
- form#contact-form(method="post" action="contact.html" role="form") {
- div.row {
- div.col-md-6 {
- div.form-group {
- label(for="contact_form_first_name") {'First name *'}
- input.form-control#contact_form_first_name(type="text" name="first_name" placeholder="Please enter your first name" required="required" data-error="First name is required.") {}
- div.help-block.with-errors {}
- }
- }
- div.col-md-6 {
- div.form-group {
- label(for="contact_form_last_name") {'Last name *'}
- input.form-control#contact_form_last_name(type="text" name="last_name" placeholder="Please enter your last name" required="required" data-error="Last name is required.") {}
- div.help-block.with-errors {}
- }
- }
- }
- div.row {
- div.col-md-6 {
- div.form-group {
- label(for="contact_form_company") {'Company'}
- input.form-control#contact_form_company(type="company" name="company" placeholder="Please enter your company") {}
- div.help-block.with-errors {}
- }
- }
- div.col-md-6 {
- div.form-group {
- label(for="contact_form_email") {'Email *'}
- input.form-control#contact_form_email(type="email" name="email" placeholder="Please enter your email" required="required" data-error="Valid email is required.") {}
- div.help-block.with-errors {}
- }
- }
- }
- div.row {
- div.col-md-12 {
- div.form-group {
- label(for="contact_form_message") {'Message *'}
- textarea.form-control#contact_form_message(name="message" placeholder="Please explain your situation" rows="4" required="required" data-error="Please, leave us a message.") {}
- div.help-block.with-errors {}
- }
- }
- }
- p {} // fix this later
- div.row {
- div.col-md-12 {
- input.btn.btn-success.btn-send(type="submit" value="Send message") {}
- }
- }
- p {} // fix this later
- div.row {
- div.col-md-12 {
- p.text-muted {
- strong {'*'}
- 'These fields are required.'
- //'Contact form template by '
- //a(href="https://bootstrapious.com/p/how-to-build-a-working-bootstrap-contact-form" target="_blank") {'Bootstrapious'}
- //'.'
- }
- }
- }
- }
-}
let XDate = require('xdate')
return async env => {
- if (env.request.method == 'POST') {
+ let globals = await env.site.get_json('/_config/globals.json')
+
+ let message
+ if (env.request.method === 'POST') {
let write_stream = new stream_buffers.WritableStreamBuffer()
let data = new Promise(
(resolve, reject) => {
)
env.request.pipe(write_stream)
let query = querystring.parse((await data).toString())
- console.log('received feedback form:', JSON.stringify(query)) //query.page)
+ console.log('received feedback form:', query.page)
// save the form contents in a dated logfile, so that we can
// recover manually if the email doesn't send for some reason
)
// send email (asynchronously)
- ;(await env.site.get_emailjs('/_config/email_feedback.json')).send(
+ let emailjs_feedback = await env.site.get_emailjs(
+ '/_config/email_feedback.json'
+ )
+ emailjs_feedback.send(
{
+ from: globals.feedback_from,
+ to: globals.feedback_to,
+ subject: 'Page: ' + query.page,
text: query.message,
- from: 'Feedback form <feedback@ndcode.org>',
- to: 'Nick Downing <nick@ndcode.org>',
- subject: 'Page: ' + query.page
},
(err, message) => {
if (err)
console.log('sent feedback email:', query.page)
}
)
+
+ message = 'Thanks!'
}
- env.site.serve(env, 200, Buffer.from('Thanks!'), 'feedback_form.html.jst')
+ else
+ message = 'Please POST.'
+
+ env.site.serve(env, 200, Buffer.from(message), 'feedback.html.jst')
}
+++ /dev/null
-return async (env, _out) => {
- form#feedback-form(method="post" action="feedback.html" role="form") {
- div.row {
- div.col-md-12 {
- div.form-group {
- label(for="feedback-form-message") {'Message *'}
- textarea.form-control#feedback-form-message(name="message" placeholder="Please tell us your thoughts" rows="4" required="required" data-error="Please, leave us a message.") {}
- div.help-block.with-errors {}
- }
- }
- }
- p {} // fix this later
- div.row {
- div.col-md-12 {
- p.text-muted {
- strong {'*'}
- 'These fields are required.'
- //'Contact form template by '
- //a(href="https://bootstrapious.com/p/how-to-build-a-working-bootstrap-feedback-form" target="_blank") {'Bootstrapious'}
- //'.'
- }
- }
- }
- input.btn.btn-success.btn-send(style="display: none;" type="submit" value="Send message") {}
- }
-}
return async env => {
+ let breadcrumbs = await _require('/breadcrumbs.jst')
let icon_jst = await env.site.get_min_svg('/_svg/icon_jst.svg')
let navbar = await _require('/navbar.jst')
let icon_pitree = await env.site.get_min_svg('/_svg/icon_pitree.svg')
await navbar(
env,
+ // head
async _out => {},
+ // body
async _out => {
- h1 {'NDCODE projects'}
+ await breadcrumbs(env, _out)
p {'We have developed these projects because we wanted to do things differently — and make our vision come to life. At times our vision is quite radical and creative, at other times we just fall back on good engineering and making it as simple as possible.'}
p {'Given that we do things differently, we have generally had to build up each idea into a complete framework that provides a comprehensive solution to a family of problems. Please do contribute to help make each framework more comprehensive over time.'}
- p {'Go on, take a look inside!'}
+ p {
+ 'Go on, take a look inside! '
+ i {'[Actually don\'t because it\'s still under construction]'}
+ }
ul.nav.nav-stacked {
li {
}
}
}
- }
+ },
+ // scripts
+ async _out => {}
)
}
+let assert = require('assert')
let XDate = require('xdate')
-return async (env, head, body) => {
- let feedback_form = await _require('/feedback_form.jst')
+return async (env, head, body, scripts) => {
+ //let cart = await _require('/online_store/cart.jst')
let globals = await env.site.get_json('/_config/globals.json')
- let icon_search = await env.site.get_min_svg('/_svg/icon_search.svg')
+ //let icon_cart_small = await env.site.get_min_svg('/_svg/icon_cart_small.svg')
+ let icon_search_mono = await env.site.get_min_svg('/_svg/icon_search_mono.svg')
let logo_large = await env.site.get_min_svg('/_svg/logo_large.svg')
+ let menu = await env.site.get_menu('/_menu.json')
let page = await _require('/page.jst')
+ //let session = await _require('/session.jst')
+
+ // initialize env.sessions, env.session_key, env.session
+ //await session(env)
+
+ // initialize env.cart
+ //await cart(env)
await page(
env,
// head
async _out => {
+ // extract top-level directory name
+ assert(env.parsed_url.pathname.slice(0, 1) === '/')
+ let index = env.parsed_url.pathname.indexOf('/', 1)
+ let dir = index === -1 ? '' : env.parsed_url.pathname.slice(1, index)
+
title {
_out.push(
- globals.site_title +
- ": " +
- (globals.page_to_title[env.parsed_url.pathname] || env.parsed_url.pathname)
+ globals.site_title + ': ' + (
+ dir.length === 0 ?
+ 'Home' :
+ menu.entries[menu.index[dir]].name
+ )
)
}
},
// body
async _out => {
+ // extract top-level directory name
+ assert(env.parsed_url.pathname.slice(0, 1) === '/')
+ let index = env.parsed_url.pathname.indexOf('/', 1)
+ let dir = index === -1 ? '' : env.parsed_url.pathname.slice(1, index)
+
div(style="padding-left: calc(100vw - 100%);") {
- div.container(style="margin-top: 15px; margin-bottom: 15px;") {
- //div.row {
- // div.col-sm-12(style="text-align: right;") {
- // a(href="/login.html") {'Login'}
- // }
- //}
+ div.container(style="margin-top: 5px; margin-bottom: 5px;") {
div.row {
div.'col-sm-8'.vbottom {
_out.push(logo_large)
}
div.'col-sm-4'.vbottom(style="padding-bottom: 15px;") {
- form(action="/search.html") {
+ //div {
+ // let signed_in =
+ // Object.prototype.hasOwnProperty.call(env.session, 'account')
+ // span#signed-in-status {
+ // if (signed_in)
+ // `Signed in as ${env.session.account}.`
+ // else
+ // 'Browsing as guest.'
+ // }
+ // ' '
+ // if (signed_in)
+ // a#sign-in(href="" hidden="") {'Sign in'}
+ // else
+ // a#sign-in(href="") {'Sign in'}
+ // ' '
+ // if (signed_in)
+ // a#sign-out(href="") {'Sign out'}
+ // else
+ // a#sign-out(href="" hidden="") {'Sign out'}
+ //}
+ //p {}
+
+ form(action="/search/index.html") {
div.input-group {
input.form-control(name="query" type="text" placeholder="Search") {}
span.input-group-btn {
button.btn.btn-default(type="submit") {
- _out.push(icon_search)
+ _out.push(icon_search_mono)
}
}
}
}
}
+ //div.'col-sm-1'.vbottom {
+ // // a nested div is used to avoid hover colour on the padding
+ // div.nav-li-a(style="text-align: center;") {
+ // a(href="/online_store/view_cart/index.html") {
+ // div.cart-icon {
+ // _out.push(icon_cart_small)
+ // }
+ // div.cart-number {
+ // div.cart-circle {
+ // `${(env.cart.items || []).length}`
+ // }
+ // }
+ // }
+ // }
+ //}
}
}
}
nav.navbar.navbar-default(style="margin-top: 0px; margin-bottom: 0px;") {
div(style="padding-left: calc(100vw - 100%);") {
div.container { //-fluid") {
- // Brand and toggle get grouped for better mobile display
+ // Brand and toggle get grouped for better mobile display
div.navbar-header {
button.navbar-toggle.collapsed(type="button" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false") {
span.sr-only {'Toggle navigation'}
//a.navbar-brand(href="#") {'Brand'}
}
- // Collect the nav links, forms, and other content for toggling
+ // Collect the nav links, forms, and other content for toggling
div.collapse.navbar-collapse#bs-example-navbar-collapse-1 {
ul.nav.navbar-nav {
- let navigation = globals.navigation
- for (let i = 0; i < navigation.length; ++i) {
- let page = navigation[i]
- let title = globals.page_to_title[page] || page
- if (page === env.parsed_url.pathname)
- li.active {
- a(href=page) {
- `${title}`
- span.sr-only {'(current)'}
- }
+ if (dir.length === 0)
+ li.active {
+ a(href="/index.html") {
+ 'Home'
+ span.sr-only {'(current)'}
}
- else
- li {
- a(href=page) {`${title}`}
+ }
+ else
+ li {
+ a(href="/index.html") {
+ 'Home'
}
- }
+ }
+ let entries = menu.entries
+ for (let i = 0; i < entries.length; ++i)
+ if (entries[i].navbar)
+ if (entries[i].dir === dir)
+ li.active {
+ a(href=`/${entries[i].dir}/index.html`) {
+ `${entries[i].name}`
+ span.sr-only {'(current)'}
+ }
+ }
+ else
+ li {
+ a(href=`/${entries[i].dir}/index.html`) {
+ `${entries[i].name}`
+ }
+ }
}
ul.nav.navbar-nav.navbar-right {
li {
- a#give-feedback {'Give feedback'}
+ a#give-feedback(href="") {'Give feedback'}
}
- }
+ }
}
}
}
}
- div(style="padding-left: calc(100vw - 100%);") {
+ div(style="padding-left: calc(100vw - 100%); margin-bottom: 50px;") {
div.container {
await body(_out)
}
p {'Example code fragments embedded within the text are placed in the public domain unless otherwise noted.'}
- p {`Copyright © ${new XDate().getUTCFullYear()} Integration Logic Pty Ltd trading as NDCODE and contributors.`}
+ p {`Copyright © ${new XDate().getUTCFullYear()} ${globals.copyright}.`}
}
}
// hidden part
+ //div#sign-in-modal.modal.fade(role="dialog") {
+ // div.modal-dialog {
+ // div.modal-content {
+ // div.modal-header {
+ // button.close(type="button" data-dismiss="modal") {
+ // '×'
+ // }
+ // h4.modal-title {
+ // 'Sign in'
+ // }
+ // }
+ // div.modal-body {
+ // form#sign-in-form(method="post" action="/sign_in.json" role="form") {
+ // div.row {
+ // div.col-md-12 {
+ // div.form-group {
+ // label(for="sign-in-form-email") {'Email'}
+ // input.form-control#sign-in-form-email(type="text" name="email" placeholder="Please enter your email address" required="required" data-error="Email address is required.") {}
+ // div.help-block.with-errors {}
+ // }
+ // }
+ // }
+ // div.row {
+ // div.col-md-12 {
+ // div.form-group {
+ // label(for="sign-in-form-password") {'Password'}
+ // input.form-control#sign-in-form-password(type="password" name="password" required="required" placeholder="Please enter your password" data-error="Password is required.") {}
+ // div.help-block.with-errors {}
+ // }
+ // }
+ // }
+ // input.btn.btn-success.btn-send(style="display: none;" type="submit" value="Sign in") {}
+ // }
+
+ // p {
+ // 'No account yet? '
+ // a(href="/my_account/sign_up/index.html") {'Sign up'}
+ // }
+
+ // p {
+ // 'Forgot password? '
+ // a(href="/my_account/password_reset/index.html") {'Password reset'}
+ // }
+ // }
+ // div.modal-footer {
+ // button.btn.btn-primary(type="submit" form="sign-in-form") {
+ // 'Sign in'
+ // }
+ // button.btn.btn-default(type="button" data-dismiss="modal") {
+ // 'Cancel'
+ // }
+ // }
+ // }
+ // }
+ //}
+
div#feedback-modal.modal.fade(role="dialog") {
div.modal-dialog {
div.modal-content {
p {
'Did you notice something not quite right, or just want to share your impression of this page?'
}
- await feedback_form(env, _out)
+ form#feedback-form(method="post" action="/feedback.html" role="form") {
+ div.row {
+ div.col-md-12 {
+ div.form-group {
+ label(for="feedback-form-message") {'Message *'}
+ textarea.form-control#feedback-form-message(name="message" placeholder="Please tell us your thoughts" rows="4" required="required" data-error="Please, leave us a message.") {}
+ div.help-block.with-errors {}
+ }
+ }
+ }
+ p {} // fix this later
+ div.row {
+ div.col-md-12 {
+ p.text-muted {
+ strong {'*'}
+ 'These fields are required.'
+ //'Contact form template by '
+ //a(href="https://bootstrapious.com/p/how-to-build-a-working-bootstrap-feedback-form" target="_blank") {'Bootstrapious'}
+ //'.'
+ }
+ }
+ }
+ input.btn.btn-success.btn-send(style="display: none;" type="submit" value="Send message") {}
+ }
}
div.modal-footer {
button.btn.btn-primary(type="submit" form="feedback-form") {
'Submit'
}
button.btn.btn-default(type="button" data-dismiss="modal") {
- 'Close'
+ 'Cancel'
}
}
}
},
// scripts
async _out => {
- // when feedback form is submitted, do not reload the page
+ //script(src="/js/sha256.js") {}
+
script {
- $(document).ready(function() {
- $('#give-feedback').click(function() {
- $('#feedback-modal').modal('show')
- $('#feedback-form-message').text('')
- })
- $('#feedback-modal').on('shown.bs.modal', function() {
- $('#feedback-form-message').focus()
- })
- $(document).on('submit', '#feedback-form', function(e) {
- e.preventDefault()
- $.ajax({
- url: '/feedback.html',
- type: 'POST',
- data: {
- page: window.location.href,
- message: $('#feedback-form-message').val()
- },
- success: function(data, textStatus, jqXHR) {
- $('#feedback-modal').modal('hide')
- $('#message-modal-message').text(data)
- $('#message-modal').modal('show')
- },
- error: function(jqXHR, textStatus, errorThrown) {
- $('#feedback-modal').modal('hide')
- $('#message-modal-message').text(errorThrown)
- $('#message-modal').modal('show')
- }
- })
- })
- })
+ //function get_cookie(name) {
+ // let entries = document.cookie.split(';');
+ // for (let i = 0; i < entries.length; ++i) {
+ // let fields = entries[i].split('=');
+ // if (fields[0].trim() === name)
+ // return decodeURIComponent(fields[1]);
+ // }
+ // return undefined;
+ //}
+
+ //// this function can be overridden in a further script
+ //function sign_in_out(status) {
+ //}
+
+ $(document).ready(
+ () => {
+ //// sign in form
+ //$('#sign-in').click(
+ // () => {
+ // $('#sign-in-form-email').text('')
+ // $('#sign-in-form-password').text('')
+ // $('#sign-in-modal').modal('show')
+ // return false
+ // }
+ //)
+ //$('#sign-in-modal').on(
+ // 'shown.bs.modal',
+ // () => {
+ // $('#sign-in-form-email').focus()
+ // }
+ //)
+ //// when sign in form is submitted, do not reload the page
+ //$(document).on(
+ // 'submit',
+ // '#sign-in-form',
+ // e => {
+ // e.preventDefault()
+ // $.ajax(
+ // {
+ // url: '/my_account/sign_in.json',
+ // type: 'POST',
+ // data: {
+ // email: $('#sign-in-form-email').val(),
+ // password: sha256(
+ // get_cookie('session_key') +
+ // $('#sign-in-form-password').val()
+ // ).toString('hex')
+ // },
+ // success: (data, textStatus, jqXHR) => {
+ // $('#sign-in-modal').modal('hide')
+ // switch (data.result) {
+ // case 1: // success
+ // $('#signed-in-status').text(data.signed_in_status)
+ // $('#sign-in').hide()
+ // $('#sign-out').show()
+ // sign_in_out(true) // notify navbar caller
+ // break
+ // case 2: // redirect
+ // location.href = data.redirect_href
+ // break
+ // }
+ // $('#message-modal-message').text(data.message)
+ // $('#message-modal').modal('show')
+ // },
+ // error: (jqXHR, textStatus, errorThrown) => {
+ // $('#sign-in-modal').modal('hide')
+ // $('#message-modal-message').text(errorThrown)
+ // $('#message-modal').modal('show')
+ // }
+ // }
+ // )
+ // }
+ //)
+
+ //// sign out button
+ //$('#sign-out').click(
+ // () => {
+ // $.ajax(
+ // {
+ // url: '/my_account/sign_out.json',
+ // type: 'GET',
+ // success: (data, textStatus, jqXHR) => {
+ // if (data.result) {
+ // $('#signed-in-status').text(data.signed_in_status)
+ // $('#sign-in').show()
+ // $('#sign-out').hide()
+ // sign_in_out(false) // notify navbar caller
+ // }
+ // $('#message-modal-message').text(data.message)
+ // $('#message-modal').modal('show')
+ // },
+ // error: (jqXHR, textStatus, errorThrown) => {
+ // $('#message-modal-message').text(errorThrown)
+ // $('#message-modal').modal('show')
+ // }
+ // }
+ // )
+ // return false
+ // }
+ //)
+
+ // feedback form
+ $('#give-feedback').click(
+ () => {
+ $('#feedback-form-message').text('')
+ $('#feedback-modal').modal('show')
+ return false
+ }
+ )
+ $('#feedback-modal').on(
+ 'shown.bs.modal',
+ () => {
+ $('#feedback-form-message').focus()
+ }
+ )
+ // when feedback form is submitted, do not reload the page
+ $(document).on(
+ 'submit',
+ '#feedback-form',
+ e => {
+ e.preventDefault()
+ $.ajax(
+ {
+ url: '/feedback.html',
+ type: 'POST',
+ data: {
+ page: window.location.href,
+ message: $('#feedback-form-message').val()
+ },
+ success: (data, textStatus, jqXHR) => {
+ $('#feedback-modal').modal('hide')
+ $('#message-modal-message').text(data)
+ $('#message-modal').modal('show')
+ },
+ error: (jqXHR, textStatus, errorThrown) => {
+ $('#feedback-modal').modal('hide')
+ $('#message-modal-message').text(errorThrown)
+ $('#message-modal').modal('show')
+ }
+ }
+ )
+ }
+ )
+ }
+ )
}
+
+ await scripts(_out)
}
)
}
+let assert = require('assert')
let querystring = require('querystring')
return async env => {
- let globals = await env.site.get_json('/_config/globals.json')
+ let breadcrumbs = await _require('/breadcrumbs.jst')
let navbar = await _require('/navbar.jst')
let zet_site = await env.site.get_zettair('/_zet/site')
env,
async _out => {},
async _out => {
- h1 {'Search results'}
+ async function breadcrumbs_str(pathname) {
+ assert(pathname.slice(0, 1) === '/')
+
+ // find names of path components
+ console.log('pathname', pathname)
+ let components = ['Home']
+ for (let i = 1, j; (j = pathname.indexOf('/', i)) !== -1; i = j + 1) {
+ let menu
+ try {
+ menu = await env.site.get_menu(`${pathname.slice(0, i)}_menu.json`)
+ }
+ catch (e) {
+ return pathname // fallback
+ }
+ let dir = pathname.slice(i, j)
+ if (!Object.prototype.hasOwnProperty.call(menu.index, dir))
+ return pathname // fallback
+ components.push(menu.entries[menu.index[dir]].name)
+ }
+
+ return components.join(' > ')
+ }
+
+ await breadcrumbs(env, _out)
h4 {
'Query: '
for (let i = 0; i < search.results.length; ++i) {
let page = search.results[i].auxiliary
li {
- a(href=page) {`${globals.page_to_title[page] || page}`}
+ a(href=page) {`${await breadcrumbs_str(page)}`}
br {}
p {_out.push(search.results[i].summary)} // note: contains HTML
}
ul.pagination {
for (let i = 0; i * 10 < search.total_results; ++i) {
- let page = '/search.html?' + querystring.stringify(
+ let page = '/search/index.html?' + querystring.stringify(
{query: query, first: i * 10}
)
let text = (i + 1).toString()
}
else
p {'No results'}
- }
+ },
+ async _out => {}
)
}