// component_titles[i] corresponds to component_names[i - 1], i >= 1
env.component_names = component_names
env.component_titles = component_titles
- console.log('cn', component_names)
- console.log('ct', component_titles)
// note: menu_titles.length === menu_names.length + 1
// menu_titles[0] corresponds to /, is 'Home' or similar
- // menu_titles[i] corresponds to menu_names[i - 1], i >= 1a
+ // menu_titles[i] corresponds to menu_names[i - 1], i >= 1
// (navbar has Home appearing at same level as its immediate children)
- console.log('mn', menu_names)
- console.log('mt', menu_titles)
await page(
env,
let dir = index === -1 ? '' : env.parsed_url.pathname.slice(1, index)
div.scrollbar-fix {
- div.container {
- div.row.align-items-center.py-3 {
- div.col-sm-8 {
- b.h1 {
- div.mr-3(style="display: inline-block; vertical-align: -40px; width: 128px; height: 128px;") {
+ div.container-fluid {
+ div.row {
+ div.'col-md-2'.bg-gray-200 {
+ div.'mt-1'.mb-4 {
+ div(style="width: 128px; height: 128px;") {
_out.push(avatar_maker)
}
- 'nick.downing.id'
+ b.h1 {
+ `${site_title}`
+ }
}
- }
- div.'col-sm-4' {
- div.'mb-1'.text-right {
+
+ div.mb-2 {
span#navbar-signed-in-status {
if (signed_in_as !== undefined)
- 'Signed in.' //`Signed in as ${signed_in_as}.`
+ 'Signed in.'
else
- 'Browsing as guest.'
+ 'Signed out.'
}
' '
if (signed_in_as !== undefined)
a#navbar-sign-out(href="#" hidden) {'Sign out'}
}
- form(action="/search/index.html") {
+ form.mb-4(action="/search/index.html") {
div.input-group {
input.form-control(name="query" type="text" placeholder="Search" aria-describedby="search-button") {}
div.input-group-append {
}
}
}
- }
- //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-expand-lg.navbar-dark.bg-primary.scrollbar-fix {
- div.container {
- //a.navbar-brand(href="#") {'Navbar'}
- //' '
- button.navbar-toggler(type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation") {
- span.navbar-toggler-icon {}
- }
- div.collapse.navbar-collapse#navbarSupportedContent {
- ul.navbar-nav.mr-auto {
- // the active entry in the navbar bar is based on which top-level
- // page we are under, even if we are not directly on that page
- // but one of its children, this may be unexpected as the active
- // entry does not highlight on hover, but you can still click it;
- // we determine here the path to the corresponding top-level page
- let component_prefix = component_names.slice(0, 1)
-
- for (let i = 0; i < menu_titles.length; ++i) {
- // construct path to the top-level page about to be described
- let menu_prefix =
- i == 0 ? [] : [menu_names[i - 1]]
- let menu_prefix_path =
- menu_prefix.map(name => '/' + name).join('') + '/index.html'
-
- if (arrays_equal(menu_prefix, component_prefix))
- li.nav-item.active {
- a.nav-link(href=menu_prefix_path) {
- `${menu_titles[i]}`
- span.sr-only {' (current)'}
+ //nav.navbar.navbar-expand-lg.navbar-dark.bg-primary.scrollbar-fix {
+ //a.navbar-brand(href="#") {'Navbar'}
+ //' '
+ //button.navbar-toggler(type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation") {
+ // span.navbar-toggler-icon {}
+ //}
+ //div.collapse.navbar-collapse#navbarSupportedContent {
+ ul.nav.flex-column { //ul.navbar-nav.mr-auto {
+ // the active entry in the navbar bar is based on which top-level
+ // page we are under, even if we are not directly on that page
+ // but one of its children, this may be unexpected as the active
+ // entry does not highlight on hover, but you can still click it;
+ // we determine here the path to the corresponding top-level page
+ let component_prefix = component_names.slice(0, 1)
+
+ for (let i = 0; i < menu_titles.length; ++i) {
+ // construct path to the top-level page about to be described
+ let menu_prefix =
+ i == 0 ? [] : [menu_names[i - 1]]
+ let menu_prefix_path =
+ menu_prefix.map(name => '/' + name).join('') + '/index.html'
+
+ if (arrays_equal(menu_prefix, component_prefix))
+ li.nav-item.active {
+ a.nav-link(href=menu_prefix_path) {
+ `${menu_titles[i]}`
+ span.sr-only {' (current)'}
+ }
+ }
+ else
+ li.nav-item {
+ a.nav-link(href=menu_prefix_path) {
+ `${menu_titles[i]}`
+ }
+ }
}
- }
- else
- li.nav-item {
- a.nav-link(href=menu_prefix_path) {
- `${menu_titles[i]}`
+ //li.nav-item.dropdown {
+ // a.nav-link.dropdown-toggle#navbarDropdown(href="#" role="button" data-toggle="dropdown" aria-expanded="false") {
+ // 'Dropdown'
+ // }
+ // div.dropdown-menu(aria-labelledby="navbarDropdown") {
+ // a.dropdown-item(href="#") {
+ // 'Action'
+ // }
+ // ' '
+ // a.dropdown-item(href="#") {
+ // 'Another action'
+ // }
+ // div.dropdown-divider {}
+ // a.dropdown-item(href="#") {
+ // 'Something else here'
+ // }
+ // }
+ //}
+ //li.nav-item {
+ // a.nav-link.disabled {
+ // 'Disabled'
+ // }
+ //}
+ //}
+ //ul.navbar-nav.ml-auto {
+ li.nav-item.mt-4 {
+ a.nav-link#navbar-give-feedback(href="#") {'Give feedback'}
}
}
- }
- //li.nav-item.dropdown {
- // a.nav-link.dropdown-toggle#navbarDropdown(href="#" role="button" data-toggle="dropdown" aria-expanded="false") {
- // 'Dropdown'
- // }
- // div.dropdown-menu(aria-labelledby="navbarDropdown") {
- // a.dropdown-item(href="#") {
- // 'Action'
- // }
- // ' '
- // a.dropdown-item(href="#") {
- // 'Another action'
- // }
- // div.dropdown-divider {}
- // a.dropdown-item(href="#") {
- // 'Something else here'
- // }
- // }
- //}
- //li.nav-item {
- // a.nav-link.disabled {
- // 'Disabled'
- // }
+ //}
//}
}
- ul.navbar-nav.ml-auto {
- li.nav-item {
- a.nav-link#navbar-give-feedback(href="#") {'Give feedback'}
+
+ div.col-md-9 {
+ await body(_out)
+
+ footer.page-footer.grid-gutter-background.py-5 {
+ a(rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/") {
+ img(alt="Creative Commons License" style="border-width:0;" src="/images/by-sa_3.0_88x31.png") {}
+ }
+ p {
+ 'This website is '
+ a(href="https://git.ndcode.org/public/nick_site.git") {
+ 'open source'
+ }
+ ' and licensed under a '
+ a(rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/") {
+ 'Creative Commons Attribution-ShareAlike 3.0 Unported License'
+ }
+ '.'
+ }
+
+ p.mb-0 {`Copyright © ${new XDate(env.now).getUTCFullYear()} ${copyright}.`}
}
}
}
}
}
- div.scrollbar-fix {
- div.container {
- await body(_out)
- }
- }
- footer.scrollbar-fix {
- div.container {
- a(rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/") {
- img(alt="Creative Commons License" style="border-width:0;" src="/images/by-sa_3.0_88x31.png") {}
- }
- p {
- 'This website is '
- a(href="https://git.ndcode.org/public/nick_site.git") {
- 'open source'
- }
- ' and licensed under a '
- a(rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/") {
- 'Creative Commons Attribution-ShareAlike 3.0 Unported License'
- }
- '.'
- }
-
- p {`Copyright © ${new XDate(env.now).getUTCFullYear()} ${copyright}.`}
- }
- }
// hidden part
div.modal#navbar-sign-in-modal(tabindex="-1") {
// not show status/dialog, as it causes an annoying flicker
return
- id_navbar_signed_in_status.textContent = 'Signed in.' //`Signed in as ${email}.`
+ id_navbar_signed_in_status.textContent = 'Signed in.'
id_navbar_sign_in.hidden = true
id_navbar_sign_up.hidden = true
id_navbar_sign_out.hidden = false
// not show status/dialog, as it causes an annoying flicker
return
- id_navbar_signed_in_status.textContent = 'Browsing as guest.'
+ id_navbar_signed_in_status.textContent = 'Signed out.'
id_navbar_sign_in.hidden = false
id_navbar_sign_up.hidden = false
id_navbar_sign_out.hidden = true
// apply this to a div inside the body tag
// prevents page shifting to left/right as scrollbar appears/disappears
-// it works by calculating the width of the scrollbar and then adding
-// the corresponding amount of padding to left to keep things centered
-// see https://stackoverflow.com/questions/45524214/how-do-i-stop-my-web-content-from-shifting-left-when-the-vertical-scrollbar-appe
+// uses negative margin to force content to be drawn under the scrollbar
+// (this is useful for modals since scrollbar disappears during a modal)
+// note: intended to be used with div.container which adds padding for
+// media sizes sm and above, don't do it for xs to avoid losing content
.scrollbar-fix {
- padding-left: calc(100vw - 100%);
+ @include media-breakpoint-up(sm) {
+ margin-right: calc(100% - 100vw);
+ }
+}
+
+// place a container div around entire page, and then use this
+// to make the background on navbar or footer appear full-width
+.extend-background {
+ margin-left: calc(-.5 * (100vw - 100%));
+ margin-right: calc(-.5 * (100vw - 100%));
+ padding-left: calc(.5 * (100vw - 100%));
+ padding-right: calc(.5 * (100vw - 100%));
+}
+
+// use within a grid column to extend the background to left/right
+.grid-gutter-background {
+ margin-left: -.5 * $grid-gutter-width;
+ margin-right: -.5 * $grid-gutter-width;
+ padding-left: .5 * $grid-gutter-width;
+ padding-right: .5 * $grid-gutter-width;
}
// needed for svg icons inside buttons, card headers, etc
margin-bottom: .5em;
}
-footer, .footer {
- padding-top: 35px;
- padding-bottom: 25px;
+.page-header {
+ background-color: theme-color-level("primary", $alert-bg-level);
+}
+
+.page-footer {
background-color: $gray-400;
a {
color: $footer-link-color;