├── .gitignore
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── base-2018
├── README.md
├── css
│ ├── bulma.css
│ └── theme.css
├── index.twig
├── js
│ ├── app.js
│ └── normalizeBrightness.js
├── listing.twig
├── not-found.twig
├── page.twig
├── partials
│ ├── _aside.twig
│ ├── _footer.twig
│ ├── _fresh_install.twig
│ ├── _header.twig
│ ├── _master.twig
│ ├── _navbar.twig
│ ├── _no_content.twig
│ ├── _record_meta.twig
│ ├── _recordfooter.twig
│ ├── _sub_menu.twig
│ ├── _sub_menu_footer.twig
│ ├── _sub_recent_records.twig
│ └── _sub_taxonomylinks.twig
├── record.twig
├── search.twig
├── source
│ ├── gulpfile.js
│ ├── javascript
│ │ └── app.js
│ ├── package-lock.json
│ ├── package.json
│ └── scss
│ │ ├── _breakpointdebug.scss
│ │ ├── _settings.scss
│ │ ├── _typography.scss
│ │ ├── bulma.scss
│ │ └── theme.scss
├── theme.yaml
└── wireframes
│ ├── Base-2018 detail.monopic
│ ├── Base-2018 detail.png
│ ├── Base-2018 homepage.monopic
│ ├── Base-2018 homepage.png
│ ├── Base-2018 homepage_widgets.monopic
│ ├── Base-2018 homepage_widgets.png
│ ├── Base-2018 listing.monopic
│ ├── Base-2018 listing.png
│ ├── Base-2018 search results.monopic
│ ├── Base-2018 search results.png
│ ├── Base-2018 showcase.monopic
│ └── Base-2018 showcase.png
├── base-2021
├── README.md
├── css
│ ├── base-2021.css
│ └── tailwind
│ │ └── base-2021.css
├── img
│ ├── hero.png
│ └── logo.svg
├── index.twig
├── js
│ └── app.js
├── listing.twig
├── macros.twig
├── package-lock.json
├── package.json
├── partials
│ ├── _block_header.twig
│ ├── _contact_form_extension.twig
│ ├── _contact_form_static.twig
│ ├── _footer.twig
│ ├── _index_3_column_block.twig
│ ├── _index_3_column_block_images.twig
│ ├── _index_CTA.twig
│ ├── _index_contact_with_map.twig
│ ├── _index_divider_bottom.twig
│ ├── _index_divider_top.twig
│ ├── _index_hero.twig
│ ├── _index_home_block.twig
│ ├── _index_pricing_block.twig
│ ├── _index_team.twig
│ ├── _index_vertical_block.twig
│ ├── _latest_few_of_everything.twig
│ ├── _master.twig
│ ├── _menu.twig
│ ├── _navigation.twig
│ ├── _record_author.twig
│ ├── _record_divider_top.twig
│ ├── _record_header_author.twig
│ ├── _record_newsletter_sub.twig
│ ├── _record_prev_next.twig
│ └── _socials.twig
├── postcss.config.js
├── record.twig
├── tailwind.config.js
├── theme.yaml
└── yarn.lock
├── composer.json
├── screenshots
├── screenshot1.png
├── screenshot2.png
└── screenshot3.png
└── skeleton
├── README.md
├── css
└── simple.css
├── index.twig
├── listing.twig
├── partials
├── _aside.twig
├── _footer.twig
├── _fresh_install.twig
├── _header.twig
├── _image.twig
├── _master.twig
├── _recordfooter.twig
├── _sub_menu.twig
├── _sub_menu_header.twig
└── _sub_taxonomylinks.twig
├── record.twig
├── search.twig
└── theme.yaml
/.gitignore:
--------------------------------------------------------------------------------
1 | composer.lock
2 | vendor/
3 | node_modules/
4 | bower_components/
5 | .DS_Store
6 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Changelog
2 | =========
3 |
4 | Version 2.0.0, 2018-03-14
5 |
6 | - Added 'base-2018' theme
7 | - Updating a handful of dependencies in 'base-2018', move from NPM to Yarn
8 | - Updating a handful of dependencies in 'skeleton'
9 |
10 | Version 1.0.4, 2017-11-14
11 |
12 | - Tiny fix for imagelists in 'fields'.
13 |
14 | Version 1.0.3, 2017-11-01
15 |
16 | - Change: Handle new blocks types
17 |
18 | Version 1.0.2, 2017-10-14
19 |
20 | - Improve the usage of the `_sub_fields.twig` partial for repeaters
21 |
22 | Version 1.0.1, 2017-10-03
23 |
24 | - Fix 404-ing link
25 | - Some extra safeguards against exceptions in "strict" mode.
26 | - Add spacing to control and output structures to aide readability
27 | - Comment out parameters that override config
28 |
29 | Version 1.0, 2017-07-14
30 |
31 | - Updating a handful of dependencies in 'base-2016'
32 | - Added 'skeleton' theme
33 | - Move to bolt/themes repo.
34 |
35 | Previous versions, as Base 2016
36 | ------------------------------
37 |
38 | Version 2.2
39 |
40 | - Replaced `gulp-minify-css` with `cssnano`.
41 | - Updated Foundation for Sites to 6.3.1.
42 |
43 | Version 2.1
44 |
45 | - `partials/_sub_fields.twig` is now included
46 |
47 | Version 2.0
48 |
49 | - Updated for Foundation 6.3
50 |
51 | Version 1.0
52 |
53 | - Initial release.
54 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Bolt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Bolt Themes
2 | ===========
3 |
4 | This is a Bolt-specific base package for the default theme templates. This
5 | package gets installed with Bolt by default, so there should be no need to pull
6 | it in manually.
7 |
--------------------------------------------------------------------------------
/base-2018/README.md:
--------------------------------------------------------------------------------
1 | Bolt Base-2018 Theme
2 | ====================
3 |
4 | Base-2018 is a clean theme for Bolt, built on top of [Bulma][bulma].
5 | To learn more about specific Bulma components, check out the
6 | [Bulma Documentation][bulma-docs].
7 |
8 | Features included with Base-2018
9 | --------------------------------
10 |
11 | Base-2018 comes with all of the great features that are found in Bolt, the
12 | Bulma framework, and a few things more. Simply put, if it works in Bulma,
13 | it will work in Bulma for Bolt. The theme also includes:
14 |
15 | - Sass(scss) or CSS Versions
16 | - Optional Yarn and Gulp Support
17 | - And much, much more!
18 |
19 | Requirements for Base-2018
20 | --------------------------
21 |
22 | You can use whatever you want – seriously. You can use Gulp, Yarn, Codekit or
23 | nothing at all. It’s completely up to you how you decide to build your theme –
24 | Bulma for Bolt will stay out of your workflow as much as possible.
25 |
26 | This theme does include Sass, Javascript and Gulp files, and is optimized for a
27 | Gulp-based workflow. To get the most out of this theme, Gulp is highly
28 | recommended. However, if you're not using Gulp yet, you can also modify the
29 | compiled CSS files as is.
30 |
31 | File Structure
32 | --------------
33 |
34 | These are the most important files, included in this theme.
35 |
36 | ```
37 | .
38 | ├── css/
39 | │ ├── bulma.css - The compiled Bulma CSS framework
40 | │ └── theme.css - Theme-specific CSS
41 | ├── js/
42 | │ ├── app.js - Theme-specific Javascript
43 | │ └── normalizeBrightness.js - A required javascript file
44 | ├── partials/
45 | │ ├── _aside.twig - Partial for the sidebar. With fixed content, or widgets
46 | │ ├── _footer.twig - Partial for the footer below every page
47 | │ ├── _fresh_install.twig - Partial that's shown on fresh installs with some instructions
48 | │ ├── _header.twig - Partial for the header banner with the site title
49 | │ ├── _master.twig - Twig template, that is uses to 'extend' all pages (See 'template inheritance')
50 | │ ├── _navbar.twig - Partial with the navigation bar shown on top of every page
51 | │ ├── _no_content.twig - Partial that's shown when there is no homepage present
52 | │ ├── _record_meta.twig - Partial with meta-information shown at the top of a page or entry
53 | │ ├── _recordfooter.twig - Partial with meta-information below a page or entry
54 | │ ├── _sub_field_blocks.twig - Partial with blocks, used by `_sub_fields.twig`
55 | │ ├── _sub_fields.twig - Partial used to render contenttypes with an undertermined amount of fields
56 | │ ├── _sub_menu.twig - Partial with macro for rendering the drop-down menu
57 | │ ├── _sub_menu_footer.twig - Partial with macro for rendering the menu in the footer
58 | │ ├── _sub_pager.twig - Partial with the markup for the pagination ([1|2|3|…])
59 | │ ├── _sub_recent_records.twig - Partial for the "latest records" block
60 | │ └── _sub_taxonomylinks.twig - Partial with the markup for the links to taxonomies like categories and tags
61 | ├── source/
62 | │ ├── javascript/
63 | │ │ └── app.js - Source app.js file
64 | │ ├── node_modules/
65 | │ ├── scss/
66 | │ │ ├── _breakpointdebug.scss
67 | │ │ ├── _settings.scss
68 | │ │ ├── _typography.scss
69 | │ │ ├── bulma.scss
70 | │ │ └── theme.scss
71 | │ ├── gulpfile.js - Build task script for Gulp.
72 | │ ├── package.json - Configuration for used Node / Gulp packages.
73 | │ └── yarn.lock
74 | ├── README.md
75 | ├── index.twig
76 | ├── listing.twig
77 | ├── not-found.twig
78 | ├── page.twig
79 | ├── record.twig
80 | ├── search.twig
81 | └── theme.yaml
82 | ```
83 |
84 | Installation
85 | ------------
86 |
87 | No need to install anything. This theme comes with Bolt. Don't forget to set
88 | `theme: base-2018` in your `config.yaml` file, if it doesn't show up already.
89 |
90 | Getting Started
91 | ---------------
92 |
93 | This theme was developed to be as "tinker friendly" as possible. Depending on
94 | your area of expertise and experience with different front-end development
95 | techniques, you can modify the CSS of this theme on different 'levels':
96 |
97 | - If you're familiar with Bulma and Gulp, you can finetune which parts of
98 | Bulma are included, as well as all their settings. See the
99 | `source/scss/bulma.scss` and `source/gulpfile.js` files.
100 | - If you do know a bit of SCSS, you can work in `source/scss/theme.scss` and
101 | `source/scss/_settings.scss` files.
102 | - Otherwise you can just make your changes in the compiled css at `css/theme.css`.
103 |
104 | The templates themselves are the `.twig` files in the root of the theme folder,
105 | as well as the additional helper files in the `partials` folder.
106 |
107 | Modifying the HTML of the theme
108 | -------------------------------
109 |
110 | All HTML parts of the theme are made in Twig. If you're not familiar with Twig
111 | yet, be sure to read the Bolt documentation on Twig, as well as the official
112 | Twig documentation.
113 |
114 | This theme uses a concept called 'template inheritance'. From other themes or
115 | CMS'es, you might be familiar with seeing each page 'include' a header and a
116 | 'footer'. Instead, we have one 'master' template, which are extended by each of
117 | the different templates. You can read more about this concept on the
118 | [Twig site - Template Inheritance][inheritance] or here:
119 | [Dealing With Themes And Layouts With Twig][theme-twig]
120 |
121 | For example, take a look at one of the simpler templates, `record.twig`:
122 |
123 | ```twig
124 | {% extends 'partials/_master.twig' %}
125 |
126 | {% block main %}
127 |
128 |
{{ record.title }}
129 |
130 | {{ block('sub_fields', 'partials/_sub_fields.twig') }}
131 |
132 | {{ include('partials/_recordfooter.twig', { 'record': record }) }}
133 |
134 | {% endblock main %}
135 | ```
136 |
137 | You'll notice the first line that states that the template 'extends' the
138 | `_master.twig` partial. The rest of the template is the `{% block %}`, which
139 | overrides the 'main' block in the master template. Inside the block is just an
140 | `
` element with the record title, a `sub_fields` block (defined in
141 | `partials/_sub_fields.twig`) that will output the fields that are defined for
142 | this ContentType, and it closes with an include of `_recordfooter.twig` to
143 | display some meta data, like the author, date and permalink.
144 |
145 | As you can see, we can still use 'include' for small blocks of HTML, even though
146 | we're using template inheritance. This way we can keep our themes very
147 | structured and organized.
148 |
149 | ### Showing all fields without defining them
150 |
151 | Because this is a general purpose theme, we try to make it work without problems
152 | for any defined ContentType. This means we'll need to render all available
153 | fields in the template without knowledge of which fields are defined exactly.
154 | To do this, we're using the `_sub_fields.twig` partial. Simply said, this
155 | partial goes over all fields in the ContentType, and outputs them in a generic
156 | way. It's used like this:
157 |
158 | ```twig
159 | {% with { 'record': record, 'common': true, 'extended': true, 'repeaters': true } %}
160 | {{ block('sub_fields', 'partials/_sub_fields.twig') }}
161 | {% endwith %}
162 | ```
163 |
164 | The `with` tag is used to scope variables: This way they will be available
165 | within the block, but not outside. The partial has a few "options" you can set
166 | this way:
167 |
168 | | Option | Description |
169 | |------------------|-------------|
170 | | `record` | The Record to use in the display. Defaults to `record` |
171 | | `common` | Whether or not to include common fields like 'text', 'html', 'textarea', 'image' and 'video' in the output. Defaults to `true` |
172 | | `extended` | Whether or not to include all other regular fields (like 'date', 'select' and others) in the output. Defaults to `false` |
173 | | `repeaters` | Whether or not to include repeater fields in the output. Defaults to `false` |
174 | | `exclude` | field names to exclude, even though they might otherwise be included |
175 | | `skip_uses` | By default the field that's used as the slug is skipped, under the assumption that it corresponds to the title of the page. To disable this, set `'skipuses': false` |
176 |
177 | Note: `templatefields` are included in `common` and `extended`, where applicable.
178 |
179 | Theme structure
180 | ---------------
181 |
182 | In the diagram below, you'll see the wat most pages are structured. In this case,
183 | `index.twig`. In the HTML, you will see it extends `_master.twig`, which can be found in
184 | the `partials/` folder. Inside this file, the global structure of all pages is laid out:
185 | The basic HTML structure, and a handful of other included partials.
186 |
187 | ```
188 | index.twig structure _topbar.twig
189 |
190 | │
191 | ├─────────────────────────┴────────────────────────────────┤
192 |
193 | ┌────────────────────────────────────────────┬───────────────┐
194 | _sub_menu.twig ──▶ │ Home link1 link2 link3 │______ [Search]│ ◀── _search.twig
195 | ├────────────────────────────────────────────┴───────────────┤
196 | │••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••│
197 | │•••••••••••••••••••••••(header image)•••••••••••••••••••••••│ ◀── _header.twig
198 | │•••••••••••••••••••••••(name of site)•••••••••••••••••••••••│
199 | │••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••│
200 | │ ┌──────────────────(main content)─┐ ┌────────────(aside)─┐ │
201 | │ │Lorem ipsum dolor sit amet │ │Lorem ipsum dolor │ │
202 | │ │ │ │sit amet. Consec- │ │
203 | │ │Consectetur adipiscing elit. Nunc│ │tetur adipiscing. │ │
204 | │ │omni virtuti vitium contrario │ │ │ │
205 | │ │nominehgpponitur. Non enim, si │ │Latest X │ │
206 | │ │malum est dolor, carere eo malo │ │ - intellegetur │ │
207 | │ │satis est ad bene vivendum. Duo │ │ - Expectoque │ │
208 | │ │Reges: constructio interrete. │ │ - videantur │ │ ◀── _aside.twig
209 | │ │ │ │ │ │
210 | │ └─────────────────────────────────┘ │Latest Y │ │
211 | │ ┌─────────────────────────────────┐ │ - intellegetur │ │
212 | │ │Lorem ipsum dolor sit amet │ │ - Expectoque │ │
213 | │ │ │ │ - videantur │ │
214 | │ │Consectetur adipiscing elit. Nunc│ │ │ │
215 | │ │omni virtuti vitium contrario │ │ │ │
216 | ┬ ├─┴─────────────────────────────────┴─┴────────────────────┴─┤
217 | _footer.twig ──┤ │ (C) 2016 Home link1 link2 link3 │ ◀── _sub_menu.twig
218 | ┴ └────────────────────────────────────────────────────────────┘
219 |
220 | ├────────────────────────────┬─────────────────────────────────┤
221 | │
222 |
223 | _master.twig
224 | ```
225 |
226 | Options in `theme.yaml`
227 | -----------------------
228 |
229 | This theme comes with its own configuration file, named `theme.yaml`. In this
230 | file you can set certain specific options for the theme, such as the default
231 | images for the header, the position of the 'aside' sidebar, and the global
232 | layout.
233 |
234 | Finally, the last section defines the settings for which templates are used for
235 | which types of pages. The templates you will set in this config file will
236 | override the ones in the global `config/bolt/config.yaml`, so beware!
237 |
238 | ```
239 | # maintenance_template: maintenance_default.twig
240 | homepage_template: index.twig
241 | record_template: record.twig
242 | listing_template: listing.twig
243 | search_results_template: search.twig
244 | notfound: notfound.twig
245 | ```
246 |
247 | For details on which page is used when, see the next section in this document.
248 |
249 | Working with the `.twig` files
250 | ------------------------------
251 |
252 | You are free to do what you want, when it comes to the .twig files. Out-of-the-
253 | box, this theme comes with a handful of templates, that correspond to
254 | the default ContentTypes when you have a fresh install of Bolt.
255 |
256 | Most of the templates will be pretty straightforward, especially if you're
257 | familiar with the concept of Template Inheritance. The main templates are:
258 |
259 | - `index.twig`: Used as the frontpage or homepage of the site.
260 | - `listing.twig`: This template is used for listing overviews of all kind, like
261 | `/pages` for all records in the 'pages ContentType' or `category/movies` for
262 | all records that have the 'movies' category assigned to them. Note that
263 | 'search' uses its own template, though.
264 | - `not-found.twig`: This template is used as the template that's shown when the
265 | visitor hits a non-existing page on the website.
266 | - `page.twig`: The detail page for a single record of the 'pages' ContentType.
267 | Automatically picked up by Bolt, if the name matches.
268 | - `record.twig`: The "generic" detail page for a single record page. This is
269 | used as the fallback, if there's no specific template set for a single record
270 | page.
271 | - `search.twig`: This page displays the search results and a search box, to
272 | search again.
273 |
274 | Working with the `.scss` files
275 | ------------------------------
276 |
277 | This theme uses Node, NPM and Gulp to run the tasks to compile and minify the
278 | Sass and Javascript files. If you don't have Node, NPM and Gulp yet, install
279 | them from [Nodejs.org](https://nodejs.org) and [Gulpjs.com](https://gulpjs.com).
280 |
281 | To install the theme's dependencies, run the following in the source directory:
282 |
283 | ```
284 | npm install
285 | ```
286 |
287 | Now you can simply run `npm run start` to compile the javascript and sass
288 | files. This will build the files, and it will continue to monitor changes to
289 | the `.scss` files. If you make a change, the compiled files will be updated
290 | immediately. When you're ready to deploy, and put the site in production, be
291 | sure to build the files and minify them:
292 |
293 | ```
294 | npm run build
295 | ```
296 |
297 | This will build the files that you can deploy, or put into your versioning
298 | system.
299 |
300 | If you're interested to learn more about the process, these two tutorials on
301 | Gulp (which is what we use under the hood) might be of interest to you:
302 |
303 | - https://markgoodyear.com/2014/01/getting-started-with-gulp/
304 | - https://travismaynard.com/writing/getting-started-with-gulp
305 |
306 | [bulma]: http://bulma.io/
307 | [bulma-docs]: https://bulma.io/documentation/overview/start/
308 | [inheritance]: http://twig.sensiolabs.org/doc/tags/extends.html
309 | [theme-twig]: http://hugogiraudel.com/2013/11/12/themes-layouts-twig/
310 |
--------------------------------------------------------------------------------
/base-2018/css/theme.css:
--------------------------------------------------------------------------------
1 | h1,h2,h3,h4,h5,h6{font-family:Bitter,serif}li a,p a{text-decoration:underline}
2 |
3 | /*!
4 | * baguetteBox.js
5 | * @author feimosi
6 | * @version %%INJECT_VERSION%%
7 | * @url https://github.com/feimosi/baguetteBox.js
8 | */#baguetteBox-overlay{display:none;opacity:0;position:fixed;overflow:hidden;top:0;left:0;width:100%;height:100%;z-index:2;background-color:#222;background-color:rgba(0,0,0,.8);transition:opacity .5s ease}#baguetteBox-overlay.visible{opacity:1}#baguetteBox-overlay .full-image{display:inline-block;position:relative;width:100%;height:100%;text-align:center}#baguetteBox-overlay .full-image figure{display:inline;margin:0;height:100%}#baguetteBox-overlay .full-image img{display:inline-block;width:auto;height:auto;max-height:100%;max-width:100%;vertical-align:middle;box-shadow:0 0 8px rgba(0,0,0,.6)}#baguetteBox-overlay .full-image figcaption{display:block;position:absolute;bottom:0;width:100%;text-align:center;line-height:1.8;white-space:normal;color:#ccc;background-color:#000;background-color:rgba(0,0,0,.6);font-family:sans-serif}#baguetteBox-overlay .full-image:before{content:"";display:inline-block;height:50%;width:1px;margin-right:-1px}#baguetteBox-slider{position:absolute;left:0;top:0;height:100%;width:100%;white-space:nowrap;transition:left .4s ease,transform .4s ease}#baguetteBox-slider.bounce-from-right{animation:a .4s ease-out}#baguetteBox-slider.bounce-from-left{animation:b .4s ease-out}@keyframes a{0%{margin-left:0}50%{margin-left:-30px}to{margin-left:0}}@keyframes b{0%{margin-left:0}50%{margin-left:30px}to{margin-left:0}}.baguetteBox-button#next-button,.baguetteBox-button#previous-button{top:50%;top:calc(50% - 30px);width:44px;height:60px}.baguetteBox-button{position:absolute;cursor:pointer;outline:none;padding:0;margin:0;border:0;border-radius:15%;background-color:#323232;background-color:rgba(50,50,50,.5);color:#ddd;font:1.6em sans-serif;transition:background-color .4s ease}.baguetteBox-button:focus,.baguetteBox-button:hover{background-color:rgba(50,50,50,.9)}.baguetteBox-button#next-button{right:2%}.baguetteBox-button#previous-button{left:2%}.baguetteBox-button#close-button{top:20px;right:2%;right:calc(2% + 6px);width:30px;height:30px}.baguetteBox-button svg{position:absolute;left:0;top:0}.baguetteBox-spinner{width:40px;height:40px;display:inline-block;position:absolute;top:50%;left:50%;margin-top:-20px;margin-left:-20px}.baguetteBox-double-bounce1,.baguetteBox-double-bounce2{width:100%;height:100%;border-radius:50%;background-color:#fff;opacity:.6;position:absolute;top:0;left:0;animation:c 2s infinite ease-in-out}.baguetteBox-double-bounce2{animation-delay:-1s}@keyframes c{0%,to{transform:scale(0)}50%{transform:scale(1)}}code[class*=language-],pre[class*=language-]{color:#000;background:none;text-shadow:0 1px #fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;tab-size:4;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-]::selection,code[class*=language-] ::selection,pre[class*=language-]::selection,pre[class*=language-] ::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.visually-hidden:not(:focus):not(:active){position:absolute!important;height:1px;width:1px;overflow:hidden;clip:rect(1px,1px,1px,1px)}.skip-link{position:absolute;top:60px;z-index:1}.navbar-brand .navbar-item,.skip-link{font-family:Bitter,serif;font-size:1.5rem;font-weight:700}.navbar-end{align-items:center}@media screen and (max-width:768px){.navbar-end form{padding:1rem}.navbar-end form .control:first-child{width:100%}}.notification ul{margin:.5em 1.4em;list-style-type:disc}.teaser{font-weight:700;margin-bottom:1rem}.card,.card-content{display:flex;flex-direction:column;height:100%}.card-content .button:last-child{margin-top:auto}.card-content p{height:100%}.section-latest-entries .buttons{margin-top:1.5rem}.tags{margin-top:3rem}.tags .label{margin-right:.5em}.section-record .image{margin-top:3rem;margin-bottom:3rem}.button{text-decoration:none}p.meta{margin-top:1rem;color:#777;font-size:90%}@media screen and (max-width:768px){.media{flex-direction:column}}.media-right{flex-shrink:1;margin-left:0}@media screen and (max-width:768px){.media-right{order:-1;width:100%;margin-bottom:1rem}}.imageholder img{width:100%}.notification>.delete{right:.5rem;top:.5rem}.hero-image{background-repeat:no-repeat;background-position:50%;background-size:cover;margin-top:52px}.hero.is-large .hero-body{padding-bottom:4rem;padding-top:4rem}.hero.is-large .hero-body h1.title,.hero.is-large .hero-body h2.subtitle{text-shadow:2px 2px 15px rgba(0,0,0,.4)}.hero.is-large .hero-body h1.title{font-size:2rem;font-weight:700}.hero.is-large .hero-body h2.subtitle{font-size:1.5rem}@media print,screen and (min-width:769px){.hero.is-large .hero-body{padding-bottom:12rem;padding-top:12rem}.hero.is-large .hero-body h1.title{font-size:2.5rem}.hero.is-large .hero-body h2.subtitle{font-size:1.875rem}}@media screen and (min-width:1024px){.hero.is-large .hero-body{padding-bottom:16rem;padding-top:16rem}.hero.is-large .hero-body h1.title{font-size:3rem}.hero.is-large .hero-body h2.subtitle{font-size:2.25rem}}.footer{padding:2rem 1.5rem}[data-background-image]{position:relative}[data-background-image] .dark-overlay{content:"";display:block;position:absolute;top:0;left:0;width:100%;height:100%;background-color:#000}pre .tag{margin:0;padding:0;background-color:transparent;display:inherit;font-size:inherit}pre .number{font-size:1em}
--------------------------------------------------------------------------------
/base-2018/index.twig:
--------------------------------------------------------------------------------
1 | {% extends 'partials/_master.twig' %}
2 |
3 | {% block main %}
4 |
5 |
6 |
7 |
8 |
9 |
10 | {# Remove this include if you don't need it anymore. #}
11 | {{ include('partials/_fresh_install.twig') }}
12 |
13 | {% setcontent homepage = "homepage" limit 1 returnsingle %}
14 | {% if homepage %}
15 |
16 |
{{ homepage.title }}
17 |
{{ homepage.teaser }}
18 | {{ homepage.content }}
19 |
20 | {% include 'partials/_record_meta.twig' with {'record': homepage } %}
21 |
22 | {% else %}
23 | {# Remove this include if you don't need it anymore. #}
24 | {{ include('partials/_no_content.twig') }}
25 | {% endif %}
26 |
95 |
96 |
97 | {% include "partials/_sub_recent_records.twig" %}
98 |
99 | {% endblock main %}
100 |
--------------------------------------------------------------------------------
/base-2018/js/normalizeBrightness.js:
--------------------------------------------------------------------------------
1 | // From: https://github.com/antoningrele/img-brightness-normalization
2 |
3 | function normalizeBrightness(coeff=1.25) {
4 |
5 | document.querySelectorAll('[data-background-image]').forEach(function(div) {
6 |
7 | /* Get the div's image background url and apply to the style */
8 | var imageUrl = div.dataset.backgroundImage;
9 | div.style.background = "url('" + imageUrl + "')";
10 |
11 | /* Prepare a dom image for canvas manipulation*/
12 | var background = new Image();
13 | background.src = imageUrl;
14 |
15 | /* When the dom image loads, proceed with the calculations */
16 | background.onload = function() {
17 |
18 | var brightness = getBrightness(background);
19 | div.dataset.brightness = brightness;
20 |
21 | /* The more opaque the overlay, the darker the image.
22 | A coefficient of 1 will equate the overlay's opacity with the image's brightness.
23 | A higher coefficient will leave more room for differences between the images, but
24 | will avoid darkening your images too much. */
25 | var darkOverlayOpacity = brightness / coeff;
26 | div.style.background = `
27 | linear-gradient(rgba(0,0,0,${darkOverlayOpacity}),
28 | rgba(0,0,0,${darkOverlayOpacity})),
29 | url(${imageUrl})
30 | `;
31 | div.style.backgroundSize = "cover";
32 | div.style.backgroundPosition = "center";
33 | }
34 | })
35 | }
36 |
37 |
38 | function getBrightness(img) {
39 |
40 | /* Returns a brightness value between 0 and 1 based on the image's brightness */
41 |
42 | var rgb = getAverageColor(img)
43 | var brightness255 = (rgb.r * 2 + rgb.g *3 + rgb.b) / 6
44 | var brightness = brightness255 / 255
45 | return brightness
46 |
47 | }
48 |
49 | function getAverageColor(img) {
50 |
51 | /* Returns an RGB object of an image's average color */
52 |
53 | var canvas = document.createElement('canvas');
54 | var ctx = canvas.getContext('2d');
55 | var width = canvas.width = img.naturalWidth;
56 | var height = canvas.height = img.naturalHeight;
57 |
58 | ctx.drawImage(img, 0, 0);
59 |
60 | var imageData = ctx.getImageData(0, 0, width, height);
61 | var data = imageData.data;
62 | var r = 0;
63 | var g = 0;
64 | var b = 0;
65 |
66 | for (var i = 0; i < data.length; i += 4) {
67 | r += data[i];
68 | g += data[i+1];
69 | b += data[i+2];
70 | }
71 |
72 | r = Math.floor(r / (data.length / 4));
73 | g = Math.floor(g / (data.length / 4));
74 | b = Math.floor(b / (data.length / 4));
75 |
76 | return { r: r, g: g, b: b };
77 |
78 | }
--------------------------------------------------------------------------------
/base-2018/listing.twig:
--------------------------------------------------------------------------------
1 | {% extends 'partials/_master.twig' %}
2 |
3 | {% block main %}
4 |
5 |
6 | {# This template is used for 'listings': Generic pages that list a number of
7 | records from a certain contenttype. These records are available as an array
8 | called 'records'. In the for-loop below, we iterate over the records that
9 | are on this page. It can be used for overview pages like 'all entries', or
10 | 'all records tagged with kittens'. #}
11 |
12 | {# If used for listing a taxonomy, we add a heading #}
13 | {% if taxonomy is defined %}
14 |
59 | {{ __("Unfortunately, no content could be found. Try another page, or go to the homepage.", {'%paths_root%': path('homepage')} ) }}
60 |
61 |
62 |
63 | {% endfor %}
64 |
65 | {# If there are more records than will fit on one page, the pager is shown. #}
66 | {{ pager(records, template = 'helpers/_pager_bulma.html.twig') }}
67 |
20 | {# #}
21 | Add a Blocks record with slug '404-not-found' to customize this message.
22 | If it's not showing up here, doublecheck that the slug is correct, and that the Block is published.
23 |
26 | {% endif %}
27 |
--------------------------------------------------------------------------------
/base-2018/partials/_recordfooter.twig:
--------------------------------------------------------------------------------
1 | {# This file is inserted as the 'footer' of each listed record. #}
2 |
3 | {# include the 'default' links to taxonomies. Check the documentation for ways to modify and customize
4 | what is output to the browser: https://docs.bolt.cm/contenttypes/taxonomies#displaying-taxonomies-in-templates #}
5 | {{ include('partials/_sub_taxonomylinks.twig', { record: record }) }}
6 |
7 | {% set previous = record|previous('id') %}
8 | {% set next = record|next('id') %}
9 | {% if previous or next %}
10 |
18 | {% endif %}
19 |
20 | {% set relatedrecords = record.related() %}
21 | {% if relatedrecords is not empty %}
22 |
29 |
30 | {% endif %}
31 |
32 |
--------------------------------------------------------------------------------
/base-2018/partials/_sub_menu.twig:
--------------------------------------------------------------------------------
1 | {# This file might seem a little complex, because of the high density of tags.
2 | It uses Twig macros and ternary selectors. Read up on them, if required:
3 | macros: http://twig.sensiolabs.org/doc/templates.html#macros
4 | ternary operators: http://twig.sensiolabs.org/doc/templates.html#other-operators
5 | #}
6 |
7 | {# Make sure the setting for the submenus is defined. #}
8 | {% if withsubmenus is not defined %}
9 | {% set withsubmenus = true %}
10 | {% endif %}
11 |
12 | {# The 'recursive' macro, for inserting one menu item. If it has a submenu, it
13 | invokes itself to insert the items of the submenus. #}
14 | {% macro display_menu_item(item, loop, withsubmenus) %}
15 | {% from _self import display_menu_item %}
16 | {% apply spaceless %}
17 | {% set with_submenu = withsubmenus and item.submenu is not empty %}
18 |
19 | {% if item.submenu and withsubmenus %}
20 |
32 | {% else %}
33 |
34 | {{- item.label|default(item.title) -}}
35 |
36 | {% endif %}
37 |
38 | {% endapply %}
39 | {% endmacro %}
40 |
41 | {# Make the macro available for use #}
42 | {% from _self import display_menu_item %}
43 |
44 | {# The main menu loop: Iterates over the items, calling `display_menu_item` #}
45 | {% for item in menu %}
46 | {% if item.label is defined %}
47 | {{ display_menu_item(item, loop, withsubmenus) }}
48 | {% endif %}
49 | {% endfor %}
50 |
--------------------------------------------------------------------------------
/base-2018/partials/_sub_menu_footer.twig:
--------------------------------------------------------------------------------
1 | {# This file might seem a little complex, because of the high density of tags.
2 | It uses Twig macros and ternary selectors. Read up on them, if required:
3 | macros: http://twig.sensiolabs.org/doc/templates.html#macros
4 | ternary operators: http://twig.sensiolabs.org/doc/templates.html#other-operators
5 | #}
6 |
7 | {# Make sure the setting for the submenus is defined. #}
8 | {% if withsubmenus is not defined %}
9 | {% set withsubmenus = true %}
10 | {% endif %}
11 |
12 | {# The 'recursive' macro, for inserting one menu item. If it has a submenu, it
13 | invokes itself to insert the items of the submenus. #}
14 | {% macro display_menu_item(item, loop, extraclass, withsubmenus) %}
15 | {% from _self import display_menu_item %}
16 | {% apply spaceless %}
17 |
22 | {% endapply %}
23 | {% endmacro %}
24 |
25 | {# Make the macro available for use #}
26 | {% from _self import display_menu_item %}
27 |
28 | {# The main menu loop: Iterates over the items, calling `display_menu_item` #}
29 | {% for item in menu %}
30 | {% if item.label is defined %}
31 | {{ display_menu_item(item, loop, '', withsubmenus) }}
32 | {% endif %}
33 | {% endfor %}
34 |
--------------------------------------------------------------------------------
/base-2018/partials/_sub_recent_records.twig:
--------------------------------------------------------------------------------
1 | {# The next section iterates over all of the contenttypes, and prints a list
2 | of the five latest records of each of them. The 'magic' happens in the
3 | setcontent tag.. `ct.slug` is set to each of the (visible) contenttypes,
4 | and `latest limit 5` ensures we grab the 5 latest published records.
5 | #}
6 |
7 |
8 |
9 | {% for ct in config.get('contenttypes')|filter(ct => not ct.viewless and not ct.singleton) %}
10 | {% setcontent records = ct.slug latest limit 5 %}
11 | {% if records|length %}
12 |
20 |
21 | {% include 'partials/_record_meta.twig' %}
22 |
23 | {# Output all fields, in the order as defined in the contenttype.
24 | To change the generated html and configure the options, see:
25 | https://docs.bolt.cm/templating #}
26 | {% with { 'record': record, 'exclude': [record|image.fieldname|default()] } %}
27 | {{ block('sub_fields', 'helpers/_fields.twig') }}
28 | {% endwith %}
29 |
30 | {# Uncomment this if you wish to dump the entire record to the client, for debugging purposes.
31 | {{ dump(record) }}
32 | #}
33 |
34 | {{ include('partials/_recordfooter.twig', { 'record': record, 'extended': true }) }}
35 |
36 |
6 | {# This template is used for search results. If 'search' is defined,
7 | we display an appropriate title. The 'records' array contains all of the
8 | records matching the current query. If there are no results, the
9 | code in the 'else' part of the for-loop is used. #}
10 |
11 |
18 |
19 | {# Perhaps we post a small teaser, stored in the 'block' named 'Search teaser' #}
20 | {% setcontent block = "block/search-teaser" %}
21 |
22 | {# check if we have 'content'. If so, we know we have have a teaser to display. #}
23 | {% if block.content is defined %}
24 |
86 |
87 | {% endfor %}
88 |
89 | {# If there are more records than will fit on one page, the pager is shown. #}
90 | {{ pager(records, template = 'helpers/_pager_bulma.html.twig') }}
91 |
92 |
93 |
94 | {% endblock main %}
95 |
--------------------------------------------------------------------------------
/base-2018/source/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var $ = require('gulp-load-plugins')();
3 | var argv = require('yargs').argv;
4 |
5 | // Check for --production flag
6 | var PRODUCTION = !!(argv.production);
7 |
8 | // Define base paths for Sass and Javascript.
9 | // File paths to various assets are defined here.
10 | var PATHS = {
11 | sass: [
12 | 'node_modules',
13 | ]
14 | };
15 |
16 | var javascriptFiles = [
17 | 'javascript/app.js',
18 | 'node_modules/baguettebox.js/src/baguetteBox.js',
19 | 'node_modules/prismjs/prism.js',
20 | 'node_modules/prismjs/components/prism-php.js',
21 | 'node_modules/prismjs/components/prism-json.js',
22 | 'node_modules/prismjs/components/prism-yaml.js',
23 | 'node_modules/prismjs/components/prism-bash.js',
24 | 'node_modules/prismjs/components/prism-markup-templating.js',
25 | 'node_modules/prismjs/plugins/line-numbers/prism-line-numbers.js',
26 | 'node_modules/prismjs/plugins/line-highlight/prism-line-highlight.js'
27 | ];
28 |
29 | // Compile Foundation Sass into CSS. In production, the CSS is compressed
30 | gulp.task('bulma-sass', function() {
31 |
32 | return gulp.src('scss/bulma.scss')
33 | .pipe($.sourcemaps.init())
34 | .pipe($.sass({
35 | includePaths: PATHS.sass
36 | })
37 | .on('error', $.sass.logError))
38 | .pipe($.autoprefixer())
39 | .pipe($.if(PRODUCTION, $.cssnano()))
40 | .pipe($.if(!PRODUCTION, $.sourcemaps.write()))
41 | .pipe(gulp.dest('../css'));
42 | });
43 |
44 | // Compile Theme Sass into CSS. Not compressed.
45 | gulp.task('theme-sass', function() {
46 |
47 | return gulp.src('scss/theme.scss')
48 | .pipe($.sourcemaps.init())
49 | .pipe($.sass({
50 | includePaths: PATHS.sass
51 | })
52 | .on('error', $.sass.logError))
53 | .pipe($.autoprefixer())
54 | // If you _do_ want to compress this file on 'production', uncomment the the lines below.
55 | .pipe($.if(PRODUCTION, $.cssnano()))
56 | .pipe($.if(!PRODUCTION, $.sourcemaps.write()))
57 | .pipe(gulp.dest('../css'));
58 | });
59 |
60 | // Set up 'compress' task.
61 | gulp.task('compress', function() {
62 | return gulp.src(javascriptFiles)
63 | .pipe($.if(PRODUCTION, $.uglify()))
64 | .pipe($.concat('app.js'))
65 | .pipe(gulp.dest('../js'));
66 | });
67 |
68 | gulp.task('setproduction', function(done) {
69 | PRODUCTION = true;
70 | done();
71 | });
72 |
73 | // Set up 'default' task, with watches.
74 | gulp.task('default', gulp.series(gulp.parallel('compress', 'bulma-sass', 'theme-sass'), function watch() {
75 | gulp.watch(['scss/**/*.scss'], gulp.series('theme-sass', 'bulma-sass'));
76 | gulp.watch(['javascript/**/*.js'], gulp.series('compress'));
77 | }));
78 |
79 | // Set up 'build' task, without watches and force 'production'.
80 | gulp.task('build', gulp.series(gulp.parallel('setproduction', 'compress', 'bulma-sass', 'theme-sass')));
81 |
82 |
--------------------------------------------------------------------------------
/base-2018/source/javascript/app.js:
--------------------------------------------------------------------------------
1 | document.addEventListener('DOMContentLoaded', function () {
2 |
3 | // Get all "navbar-burger" elements
4 | var $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
5 |
6 | // Check if there are any navbar burgers
7 | if ($navbarBurgers.length > 0) {
8 |
9 | // Add a click event on each of them
10 | $navbarBurgers.forEach(function ($el) {
11 | $el.addEventListener('click', function () {
12 |
13 | // Get the target from the "data-target" attribute
14 | var target = $el.dataset.target;
15 | var $target = document.getElementById(target);
16 |
17 | // Toggle the class on both the "navbar-burger" and the "navbar-menu"
18 | $el.classList.toggle('is-active');
19 | $target.classList.toggle('is-active');
20 |
21 | });
22 | });
23 | }
24 | baguetteBox.run('.container');
25 |
26 | normalizeBrightness();
27 |
28 | document.querySelector('.notification > button.delete').addEventListener('click', function(e) {
29 | e.target.parentElement.style.display = 'none';
30 | }, false);
31 | });
32 |
--------------------------------------------------------------------------------
/base-2018/source/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bolt-base-2018-theme",
3 | "description": "Base 2018",
4 | "version": "0.1.0",
5 | "license": "MIT",
6 | "private": false,
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/bolt/themes"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/bolt/themes/issues",
13 | "email": "bob@twokings.nl"
14 | },
15 | "main": "gulpfile.js",
16 | "dependencies": {
17 | "baguettebox.js": "^1.11.1",
18 | "bulma": "^0.9.0",
19 | "gulp-concat": "^2.6.1",
20 | "prismjs": "^1.27.0"
21 | },
22 | "devDependencies": {
23 | "gulp": "^4.0.2",
24 | "gulp-autoprefixer": "^7.0.1",
25 | "gulp-cssnano": "^2.1.3",
26 | "gulp-if": "^3.0.0",
27 | "gulp-load-plugins": "^2.0.4",
28 | "gulp-sass": "^4.1.0",
29 | "node-sass": "^4.14.1",
30 | "gulp-sourcemaps": "^2.6.5",
31 | "gulp-uglify": "^3.0.2",
32 | "yargs": "^15.4.1"
33 | },
34 | "scripts": {
35 | "start": "gulp",
36 | "build": "gulp build"
37 | },
38 | "browserslist": [
39 | "last 1 version",
40 | "> 1%"
41 | ]
42 | }
43 |
--------------------------------------------------------------------------------
/base-2018/source/scss/_breakpointdebug.scss:
--------------------------------------------------------------------------------
1 | @if ($debug-breakpoint==true) {
2 | body:before {
3 | content: 'mobile';
4 | position: fixed;
5 | text-align: center;
6 | bottom: 0;
7 | left: 0;
8 | width: auto;
9 | background: rgba(0, 0, 0, 0.85);
10 | color: #FFF;
11 | font-weight: bold;
12 | z-index: 999;
13 | padding: 0.5em 2em;
14 |
15 | @include tablet {
16 | content: 'tablet';
17 | }
18 |
19 | @include desktop {
20 | content: 'desktop';
21 | }
22 |
23 | @include widescreen {
24 | content: 'widescreen';
25 | }
26 |
27 | @include fullhd {
28 | content: 'fullhd';
29 | }
30 |
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/base-2018/source/scss/_settings.scss:
--------------------------------------------------------------------------------
1 | // Show the current breakpoints in the lower left corner.
2 | $debug-breakpoint: false;
3 |
4 | // ------------ Settings for Bulma ---------------
5 |
6 | // 1. Import the initial variables
7 | @import "../node_modules/bulma/sass/utilities/initial-variables";
8 | @import "../node_modules/bulma/sass/utilities/functions";
9 |
10 | // 2. Set your own initial variables
11 |
12 | // Colors
13 | $light: rgb(240, 239, 239);
14 | $dark: #444;
15 | $medium: #777;
16 |
17 | // Fonts
18 | $font-sans-serif : 'Roboto', sans-serif; // Base font
19 | $font-serif : 'Bitter', serif; // Headings
20 |
21 | // 3. Set the derived variables
22 |
23 | // Option 1: https://color.adobe.com/ims-construction-colors-color-theme-10555392/
24 | $link: #DF1C31;
25 | $info: #1B2A3F;
26 | $primary: #2873A4;
27 | $success: #F1A42C;
28 |
29 | // Option 2: https://color.adobe.com/mapa-laranja-color-theme-10556928/
30 | // $primary: #C97B5C;
31 | // $info: #3F3430;
32 | // $link: #3F271D;
33 | // $success: #8B7368;
34 |
35 | // Option 3: https://color.adobe.com/WASD-color-theme-10551808/
36 | // $primary: #0D6545;
37 | // $info: #373B3A;
38 | // $link: #0E724E;
39 | // $success: #8B7368;
40 |
41 | // Option 4: https://color.adobe.com/Palette-de-couleurs-1-color-theme-10564608/
42 | // $primary: darken(#9FD4F1, 10);
43 | // $info: #9B8D1F;
44 | // $link: #385681;
45 | // $success: #9C8754;
46 |
47 | // Option 5: Black & White
48 | // $primary: #444;
49 | // $info: #888;
50 | // $link: #385691;
51 | // $success: #777;
52 |
53 | $pre-background: $grey-lighter;
54 | $family-primary: $font-sans-serif;
55 |
56 | // Generic variables
57 | $body-background-color: $white;
58 | $body-weight: $weight-light;
59 | $column-gap: 1.5rem;
60 |
61 | // Title
62 | $title-color: $black;
63 | $title-weight: $weight-normal;
64 | $title-size: 2rem;
65 | $subtitle-size: 1.5rem;
66 |
67 | // Box
68 | $box-radius: 0;
69 | $box-shadow: 0;
70 |
71 | // 4. Setup your Custom Colors
72 | $linkedin: #0077b5;
73 | $linkedin-invert: findColorInvert($linkedin);
74 | $twitter: #55acee;
75 | $twitter-invert: findColorInvert($twitter);
76 | $github: #333;
77 | $github-invert: findColorInvert($github);
78 |
79 | // 5. Import the rest of the "utilities".
80 | @import "../node_modules/bulma/sass/utilities/all";
81 |
--------------------------------------------------------------------------------
/base-2018/source/scss/_typography.scss:
--------------------------------------------------------------------------------
1 | h1, h2, h3, h4, h5, h6 {
2 | font-family: $font-serif;
3 | }
4 |
5 | p a,
6 | li a {
7 | text-decoration: underline;
8 | }
9 |
--------------------------------------------------------------------------------
/base-2018/source/scss/bulma.scss:
--------------------------------------------------------------------------------
1 | // 6. Import the rest of Bulma with settings.
2 |
3 | @import 'settings';
4 | @import '../node_modules/bulma/bulma';
5 |
6 | // Some overrides to set a good default for Symfony Forms / Boltforms styles
7 | .boltform {
8 | & label {
9 | @extend .label;
10 | line-height: 2em;
11 | }
12 |
13 | & input {
14 | @extend .input;
15 | }
16 |
17 | & textarea {
18 | @extend .textarea;
19 | }
20 |
21 | & select {
22 | @extend .select;
23 | }
24 |
25 | & input[type='checkbox'] {
26 | @extend .checkbox;
27 | }
28 |
29 | & input[type='radio'] {
30 | @extend .radio;
31 | }
32 |
33 | & button {
34 | @extend .button;
35 | @extend .is-primary;
36 | }
37 |
38 | }
39 |
40 |
41 | /* Default pagerfanta styles, for pagination */
42 | .pagination {
43 | }
44 |
45 | .pagination a,
46 | .pagination span {
47 | display: inline-block;
48 | background: #f4f9fa;
49 | border: 1px solid #96c4cc;
50 | color: #2c8898;
51 | margin-right: .2em;
52 | padding: .4em .35em;
53 | }
54 |
55 | .pagination a {
56 | text-decoration: none;
57 | }
58 |
59 | .pagination a:hover {
60 | background: #c0dbe0;
61 | color: #982c61;
62 | }
63 |
64 | .pagination .dots {
65 | border-width: 0;
66 | }
67 |
68 | .pagination .current {
69 | background: #c0dbe0;
70 | font-weight: bold;
71 | }
72 |
73 | .pagination .disabled {
74 | border-color: #c0dbe0;
75 | color: #abcfd6;
76 | }
77 |
--------------------------------------------------------------------------------
/base-2018/source/scss/theme.scss:
--------------------------------------------------------------------------------
1 | // Theme specific styling.
2 |
3 | @import 'settings';
4 | @import 'typography';
5 | @import 'breakpointdebug';
6 | @import 'node_modules/baguettebox.js/src/baguetteBox';
7 | @import 'node_modules/prismjs/themes/prism';
8 |
9 | .visually-hidden:not(:focus):not(:active) {
10 | position: absolute !important;
11 | height: 1px;
12 | width: 1px;
13 | overflow: hidden;
14 | clip: rect(1px, 1px, 1px, 1px);
15 | }
16 | .skip-link {
17 | font-family: $font-serif;
18 | font-size: $size-large;
19 | font-weight: bold;
20 | position: absolute;
21 | top: 60px;
22 | z-index: 1;
23 | }
24 |
25 | .navbar-brand {
26 | .navbar-item {
27 | font-family: $font-serif;
28 | font-size: $size-large;
29 | font-weight: bold;
30 | }
31 | }
32 |
33 | .navbar-end {
34 | align-items: center;
35 | @include mobile {
36 | form {
37 | padding: 1rem;
38 | .control:first-child {
39 | width: 100%;
40 | }
41 | }
42 | }
43 | }
44 |
45 | .notification {
46 | ul {
47 | margin: 0.5em 1.4em;
48 | list-style-type: disc;
49 | }
50 | }
51 |
52 | .teaser {
53 | font-weight: bold;
54 | margin-bottom: 1rem;
55 | }
56 |
57 | .card {
58 | display: flex;
59 | flex-direction: column;
60 | height: 100%;
61 | }
62 |
63 | .card-content {
64 | display: flex;
65 | flex-direction: column;
66 | height: 100%;
67 |
68 | .button:last-child {
69 | margin-top: auto;
70 | }
71 |
72 | p {
73 | height: 100%;
74 | }
75 | }
76 |
77 | .section-latest-entries {
78 | .buttons {
79 | margin-top: 1.5rem;
80 | }
81 | }
82 |
83 | .tags {
84 | margin-top: 3rem;
85 | .label {
86 | margin-right: .5em;
87 | }
88 | }
89 |
90 | .section-record {
91 | .image {
92 | margin-top: 3rem;
93 | margin-bottom: 3rem;
94 | }
95 | }
96 |
97 | .button {
98 | text-decoration: none;
99 | }
100 |
101 | p.meta {
102 | margin-top: 1rem;
103 | color: $medium;
104 | font-size: 90%;
105 | }
106 |
107 | .media {
108 | @include mobile {
109 | flex-direction: column;
110 | }
111 | }
112 | .media-right {
113 | flex-shrink: 1;
114 | margin-left: 0;
115 | @include mobile {
116 | order: -1;
117 | width: 100%;
118 | margin-bottom: 1rem;
119 | }
120 | }
121 |
122 | .imageholder {
123 | img {
124 | width: 100%;
125 | }
126 | }
127 |
128 | .notification > .delete {
129 | right: .5rem;
130 | top: .5rem;
131 | }
132 |
133 |
134 | .hero-image {
135 | background-repeat: no-repeat;
136 | background-position: center center;
137 | background-size: cover;
138 | margin-top: 52px;
139 | }
140 |
141 | .hero.is-large .hero-body {
142 | padding-bottom: 4rem;
143 | padding-top: 4rem;
144 | h1.title,
145 | h2.subtitle {
146 | text-shadow: 2px 2px 15px rgba(0, 0, 0, 0.4);
147 | }
148 | h1.title {
149 | font-size: $title-size;
150 | font-weight: bold;
151 | }
152 | h2.subtitle {
153 | font-size: $subtitle-size;
154 | }
155 | @include tablet {
156 | padding-bottom: 12rem;
157 | padding-top: 12rem;
158 | h1.title {
159 | font-size: $title-size * 1.25;
160 | }
161 | h2.subtitle {
162 | font-size: $subtitle-size * 1.25;
163 | }
164 | }
165 | @include desktop {
166 | padding-bottom: 16rem;
167 | padding-top: 16rem;
168 | h1.title {
169 | font-size: $title-size * 1.5;
170 | }
171 | h2.subtitle {
172 | font-size: $subtitle-size * 1.5;
173 | }
174 | }
175 |
176 | }
177 |
178 | .footer {
179 | padding: 2rem 1.5rem
180 | }
181 |
182 | // https://antoningrele.github.io/img-brightness-normalization/normalizeBrightness.css
183 | [data-background-image] { position: relative; }
184 |
185 | [data-background-image] .dark-overlay {
186 | /* This is the element that is going to darken the background image
187 | By default, it's entirely black, but the JS code will give it
188 | some transparency by setting its opacity to a calculated value.
189 | The brighter the image, the higher the opacity, to compensate ! */
190 |
191 | content: "";
192 | display: block;
193 | position: absolute;
194 | top: 0; left: 0;
195 | width: 100%; height: 100%;
196 | background-color: black;
197 | }
198 |
199 | pre {
200 | // Fix tags in PrismJS.
201 | .tag {
202 | margin: 0;
203 | padding: 0;
204 | background-color: transparent;
205 | display: inherit;
206 | font-size: inherit;
207 | }
208 | .number {
209 | font-size: 1em;
210 | }
211 | }
--------------------------------------------------------------------------------
/base-2018/theme.yaml:
--------------------------------------------------------------------------------
1 | # Optional config file for the theme.
2 |
3 | # Variables that are in this file, can be used in your twig template like {{ theme.foo }}
4 |
5 | # Template filenames. If you're creating a theme for distribution, you can specify
6 | # the filenames of the templates here. The templates you will set in this config
7 | # file will override the ones in the global app/config/config.yml, so beware!
8 | # maintenance_template: maintenance_default.twig
9 | # homepage_template: index.twig
10 | # record_template: record.twig
11 | # listing_template: listing.twig
12 | # search_results_template: search.twig
13 | # notfound: not-found.twig
14 |
15 | # Optional overrides. These override the ones in config.yml, but can be set in
16 | # either place.
17 | # taxonomy_sort: DESC
18 | # homepage: page/1
19 | # listing_sort: datepublish DESC
20 | # listing_records: 6
21 | # search_results_records: 10
22 |
23 | # Aliases can be set to restrict images to a specific set of available
24 | # resolutions or to decouple image sizes from template files.
25 | thumbnails:
26 | aliases:
27 | myimageformat:
28 | size: [400,300]
29 | cropping: crop
30 |
--------------------------------------------------------------------------------
/base-2018/wireframes/Base-2018 detail.monopic:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bolt/themes/205f78a1b2999cb08b4570816bcb2185d3dbd3a2/base-2018/wireframes/Base-2018 detail.monopic
--------------------------------------------------------------------------------
/base-2018/wireframes/Base-2018 detail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bolt/themes/205f78a1b2999cb08b4570816bcb2185d3dbd3a2/base-2018/wireframes/Base-2018 detail.png
--------------------------------------------------------------------------------
/base-2018/wireframes/Base-2018 homepage.monopic:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bolt/themes/205f78a1b2999cb08b4570816bcb2185d3dbd3a2/base-2018/wireframes/Base-2018 homepage.monopic
--------------------------------------------------------------------------------
/base-2018/wireframes/Base-2018 homepage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bolt/themes/205f78a1b2999cb08b4570816bcb2185d3dbd3a2/base-2018/wireframes/Base-2018 homepage.png
--------------------------------------------------------------------------------
/base-2018/wireframes/Base-2018 homepage_widgets.monopic:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bolt/themes/205f78a1b2999cb08b4570816bcb2185d3dbd3a2/base-2018/wireframes/Base-2018 homepage_widgets.monopic
--------------------------------------------------------------------------------
/base-2018/wireframes/Base-2018 homepage_widgets.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bolt/themes/205f78a1b2999cb08b4570816bcb2185d3dbd3a2/base-2018/wireframes/Base-2018 homepage_widgets.png
--------------------------------------------------------------------------------
/base-2018/wireframes/Base-2018 listing.monopic:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bolt/themes/205f78a1b2999cb08b4570816bcb2185d3dbd3a2/base-2018/wireframes/Base-2018 listing.monopic
--------------------------------------------------------------------------------
/base-2018/wireframes/Base-2018 listing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bolt/themes/205f78a1b2999cb08b4570816bcb2185d3dbd3a2/base-2018/wireframes/Base-2018 listing.png
--------------------------------------------------------------------------------
/base-2018/wireframes/Base-2018 search results.monopic:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bolt/themes/205f78a1b2999cb08b4570816bcb2185d3dbd3a2/base-2018/wireframes/Base-2018 search results.monopic
--------------------------------------------------------------------------------
/base-2018/wireframes/Base-2018 search results.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bolt/themes/205f78a1b2999cb08b4570816bcb2185d3dbd3a2/base-2018/wireframes/Base-2018 search results.png
--------------------------------------------------------------------------------
/base-2018/wireframes/Base-2018 showcase.monopic:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bolt/themes/205f78a1b2999cb08b4570816bcb2185d3dbd3a2/base-2018/wireframes/Base-2018 showcase.monopic
--------------------------------------------------------------------------------
/base-2018/wireframes/Base-2018 showcase.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bolt/themes/205f78a1b2999cb08b4570816bcb2185d3dbd3a2/base-2018/wireframes/Base-2018 showcase.png
--------------------------------------------------------------------------------
/base-2021/README.md:
--------------------------------------------------------------------------------
1 | Bolt 4 - Base-2021 theme
2 | ========================
3 |
4 | This is the base theme that comes with the installation of Bolt 5.
5 |
6 | Bolt CMS is an open source, adaptable platform for building and running modern
7 | websites. Built on PHP, Symfony and more. [Read the site](https://boltcms.io)
8 | for more info.
9 |
10 | To check out Bolt and set up your first Bolt installation, read [Installing Bolt][installation].
11 |
12 | ---
13 |
14 | 1 Tailwind CSS
15 | --------------
16 |
17 | This theme is based on the framework [Tailwind CSS](https://tailwindcss.com/).
18 | Tailwind CSS is a highly customizable, low-level CSS framework that gives you
19 | all of the building blocks you need to build bespoke designs without any
20 | opinionated styles you have to fight to override.
21 |
22 | 1.1 Development
23 | ---------------
24 |
25 | The raw Tailwind-flavoured CSS-file lives in `css/tailwind/`. In this setup the
26 | CSS will be processed, purged and minified by default. You can disable purging
27 | by setting `purge.enabled`to `false` in `tailwind.config.js` and minification by
28 | commenting out all `cssnano`-related lines in `postcss.config.js`.
29 |
30 | Read more about the process in the [Tailwind CSS / Optimizing for Production][opt] docs.
31 |
32 | During development you can use `yarn watch` to automatically regenerate all css
33 | files. When purging is enabled, this process scrapes all `.twig` files in the
34 | theme folder and tries to find all used selectors. In doing so, all unused
35 | selectors are purged and the final size of tailwind reduces from a couple of
36 | megabytes to some kilobytes.
37 |
38 | 2 Resources
39 | -----------
40 |
41 | - [Tailwind Cheat Sheet](https://nerdcave.com/tailwind-cheat-sheet)
42 | - [Tailwind components](https://tailwindcomponents.com/)
43 | - [Tailwind Toolbox](https://www.tailwindtoolbox.com/)
44 | - [Awsome Tailwind CSS - Large resource of links](https://github.com/aniftyco/awesome-tailwindcss)
45 | - [Bolt CMS documentation](https://docs.bolt.cm/4.0/getting-started/introduction)
46 | - [Twig documentation](https://twig.symfony.com/)
47 |
48 | 3 Editing this theme
49 | --------------------
50 |
51 | The base-2021 theme consists of:
52 |
53 | - Homepage (index.twig)
54 | - Record page (record.twig)
55 | - Listing page (listing.twig)
56 |
57 | You can edit these files to your liking. The themes come with the development
58 | build of Tailwind CSS which is 2380.4kB.
59 | These makes the development as productive as possible, but when you are ready
60 | for production, make sure you 'purge' the CSS.
61 | See the Tailwind documentation for information about [controling the file size](https://tailwindcss.com/docs/controlling-file-size).
62 |
63 | ```
64 | **Important note**
65 | In the folder "tailwind css" is the base css file for generating the Tailwind CSS.
66 | In this file are also some custom CSS rules for the record template.
67 | ```
68 |
69 | [opt]: https://tailwindcss.com/docs/optimizing-for-production
70 | [installation]: https://docs.bolt.cm/installation/installation
71 |
--------------------------------------------------------------------------------
/base-2021/css/base-2021.css:
--------------------------------------------------------------------------------
1 | /*! tailwindcss v2.2.4 | MIT License | https://tailwindcss.com*/
2 |
3 | /*! modern-normalize v1.1.0 | MIT License | https://github.com/sindresorhus/modern-normalize */html{-webkit-text-size-adjust:100%;line-height:1.15;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;margin:0}hr{color:inherit;height:0}code{font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:1em}button,input,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button{text-transform:none}[type=button],[type=submit],button{-webkit-appearance:button}progress{vertical-align:baseline}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}h1,h2,h3,hr,p{margin:0}button{background-color:transparent;background-image:none}ul{list-style:none;margin:0;padding:0}html{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{font-family:inherit;line-height:inherit}*,:after,:before{border:0 solid;box-sizing:border-box}hr{border-top-width:1px}img{border-style:solid}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}button{cursor:pointer}h1,h2,h3{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}button,input,textarea{color:inherit;line-height:inherit;padding:0}code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}embed,iframe,img,svg{display:block;vertical-align:middle}img{height:auto;max-width:100%}*,:after,:before{--tw-border-opacity:1;border-color:rgba(229,231,235,var(--tw-border-opacity))}html{font-size:18px}a,a:hover{text-decoration:underline}a.rounded,a.rounded-full,nav a{text-decoration:inherit}a.pencil-editlink{font-size:75%;opacity:.7;text-decoration:none}a.pencil-editlink:hover{opacity:1}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{bottom:0;left:0;right:0;top:0}.top-0{top:0}.right-0{right:0}.bottom-0{bottom:0}.left-0{left:0}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.order-first{order:-9999}.m-8{margin:2rem}.-m-4{margin:-1rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0{margin-bottom:0;margin-top:0}.my-2{margin-bottom:.5rem;margin-top:.5rem}.my-3{margin-bottom:.75rem;margin-top:.75rem}.my-4{margin-bottom:1rem;margin-top:1rem}.my-6{margin-bottom:1.5rem;margin-top:1.5rem}.my-12{margin-bottom:3rem;margin-top:3rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-8{margin-top:2rem}.mt-16{margin-top:4rem}.mt-auto{margin-top:auto}.-mt-12{margin-top:-3rem}.mr-2{margin-right:.5rem}.mr-3{margin-right:.75rem}.mr-4{margin-right:1rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.mb-10{margin-bottom:2.5rem}.mb-12{margin-bottom:3rem}.ml-1{margin-left:.25rem}.ml-3{margin-left:.75rem}.ml-auto{margin-left:auto}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.hidden{display:none}.h-1{height:.25rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-10{height:2.5rem}.h-20{height:5rem}.h-32{height:8rem}.h-auto{height:auto}.h-full{height:100%}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-10{width:2.5rem}.w-20{width:5rem}.w-64{width:16rem}.w-1\/6{width:16.666667%}.w-5\/6{width:83.333333%}.w-full{width:100%}.max-w-sm{max-width:24rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-5xl{max-width:64rem}.max-w-full{max-width:100%}.max-w-screen-xl{max-width:1280px}.flex-1{flex:1 1 0%}.flex-none{flex:none}.flex-shrink-0{flex-shrink:0}.flex-shrink{flex-shrink:1}.flex-grow{flex-grow:1}.transform{--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;transform:translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.origin-top-right{transform-origin:top right}.rotate-0{--tw-rotate:0deg}.rotate-180{--tw-rotate:180deg}.scale-95{--tw-scale-x:.95;--tw-scale-y:.95}.scale-100{--tw-scale-x:1;--tw-scale-y:1}.resize-none{resize:none}.list-none{list-style-type:none}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.content-center{align-content:center}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.overflow-hidden{overflow:hidden}.break-normal{overflow-wrap:normal;word-break:normal}.rounded-none{border-radius:0}.rounded{border-radius:.25rem}.rounded-md{border-radius:.375rem}.rounded-lg{border-radius:.5rem}.rounded-full{border-radius:9999px}.rounded-t-none{border-top-left-radius:0;border-top-right-radius:0}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.rounded-b-none{border-bottom-left-radius:0;border-bottom-right-radius:0}.rounded-b{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.border-0{border-width:0}.border-2{border-width:2px}.border{border-width:1px}.border-b-2{border-bottom-width:2px}.border-b-4{border-bottom-width:4px}.border-b{border-bottom-width:1px}.border-none{border-style:none}.border-gray-200{--tw-border-opacity:1;border-color:rgba(229,231,235,var(--tw-border-opacity))}.border-gray-400{--tw-border-opacity:1;border-color:rgba(156,163,175,var(--tw-border-opacity))}.focus\:border-indigo-500:focus{--tw-border-opacity:1;border-color:rgba(99,102,241,var(--tw-border-opacity))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity:1;background-color:rgba(255,255,255,var(--tw-bg-opacity))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgba(243,244,246,var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgba(229,231,235,var(--tw-bg-opacity))}.bg-gray-300{--tw-bg-opacity:1;background-color:rgba(209,213,219,var(--tw-bg-opacity))}.hover\:bg-gray-200:hover{--tw-bg-opacity:1;background-color:rgba(229,231,235,var(--tw-bg-opacity))}.hover\:bg-indigo-600:hover{--tw-bg-opacity:1;background-color:rgba(79,70,229,var(--tw-bg-opacity))}.focus\:bg-gray-200:focus{--tw-bg-opacity:1;background-color:rgba(229,231,235,var(--tw-bg-opacity))}.object-cover{-o-object-fit:cover;object-fit:cover}.object-center{-o-object-position:center;object-position:center}.p-1{padding:.25rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.p-10{padding:2.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0{padding-bottom:0;padding-top:0}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.py-4{padding-bottom:1rem;padding-top:1rem}.py-6{padding-bottom:1.5rem;padding-top:1.5rem}.py-8{padding-bottom:2rem;padding-top:2rem}.py-12{padding-bottom:3rem;padding-top:3rem}.py-24{padding-bottom:6rem;padding-top:6rem}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.pt-12{padding-top:3rem}.pt-20{padding-top:5rem}.pt-24{padding-top:6rem}.pr-0{padding-right:0}.pr-3{padding-right:.75rem}.pb-0{padding-bottom:0}.pb-4{padding-bottom:1rem}.pb-6{padding-bottom:1.5rem}.pb-12{padding-bottom:3rem}.pb-20{padding-bottom:5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-sans{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.text-xs{font-size:.75rem;line-height:1rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem}.text-lg,.text-xl{line-height:1.75rem}.text-xl{font-size:1.25rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-5xl{font-size:3rem;line-height:1}.font-normal{font-weight:400}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}.uppercase{text-transform:uppercase}.leading-none{line-height:1}.leading-tight{line-height:1.25}.leading-normal{line-height:1.5}.leading-relaxed{line-height:1.625}.tracking-normal{letter-spacing:0}.tracking-wide{letter-spacing:.025em}.tracking-widest{letter-spacing:.1em}.text-black{--tw-text-opacity:1;color:rgba(0,0,0,var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity))}.text-gray-200{--tw-text-opacity:1;color:rgba(229,231,235,var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgba(156,163,175,var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgba(107,114,128,var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity:1;color:rgba(75,85,99,var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgba(55,65,81,var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgba(31,41,55,var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgba(17,24,39,var(--tw-text-opacity))}.text-indigo-500{--tw-text-opacity:1;color:rgba(99,102,241,var(--tw-text-opacity))}.focus\:text-gray-900:focus,.hover\:text-gray-900:hover{--tw-text-opacity:1;color:rgba(17,24,39,var(--tw-text-opacity))}.underline{text-decoration:underline}.no-underline{text-decoration:none}.hover\:underline:hover{text-decoration:underline}.hover\:no-underline:hover{text-decoration:none}.opacity-0{opacity:0}.opacity-25{opacity:.25}.opacity-100{opacity:1}*,:after,:before{--tw-shadow:0 0 #0000}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,0.1),0 1px 2px 0 rgba(0,0,0,0.06)}.shadow,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,0.1),0 4px 6px -2px rgba(0,0,0,0.05);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}*,:after,:before{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000}.filter{--tw-blur:var(--tw-empty,/*!*/ /*!*/);--tw-brightness:var(--tw-empty,/*!*/ /*!*/);--tw-contrast:var(--tw-empty,/*!*/ /*!*/);--tw-grayscale:var(--tw-empty,/*!*/ /*!*/);--tw-hue-rotate:var(--tw-empty,/*!*/ /*!*/);--tw-invert:var(--tw-empty,/*!*/ /*!*/);--tw-saturate:var(--tw-empty,/*!*/ /*!*/);--tw-sepia:var(--tw-empty,/*!*/ /*!*/);--tw-drop-shadow:var(--tw-empty,/*!*/ /*!*/);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.grayscale{--tw-grayscale:grayscale(100%)}.transition{transition-duration:.15s;transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-transform{transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-75{transition-duration:75ms}.duration-100{transition-duration:.1s}.duration-200{transition-duration:.2s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.article>p{margin:1rem 0}.article>p,.article>ul{font-size:clamp(1.1rem,1.1vw,1.6rem)}.article>ul{list-style-position:inside;list-style-type:disc}.article h1{font-size:clamp(1.875rem,2.5vw,2.25rem)}.article h2{font-size:clamp(1.5rem,2vw,1.875rem)}.article h3{font-size:clamp(1.25rem,1.75vw,1.5rem);font-weight:700}@media (min-width:640px){.sm\:my-4{margin-bottom:1rem;margin-top:1rem}.sm\:mt-0{margin-top:0}.sm\:-mt-6{margin-top:-1.5rem}.sm\:mr-4{margin-right:1rem}.sm\:mr-10{margin-right:2.5rem}.sm\:ml-6{margin-left:1.5rem}.sm\:ml-auto{margin-left:auto}.sm\:w-1\/2{width:50%}.sm\:flex-row{flex-direction:row}.sm\:justify-start{justify-content:flex-start}}@media (min-width:768px){.md\:mt-0{margin-top:0}.md\:-mt-1{margin-top:-.25rem}.md\:mb-0{margin-bottom:0}.md\:mb-2{margin-bottom:.5rem}.md\:ml-0{margin-left:0}.md\:ml-4{margin-left:1rem}.md\:ml-auto{margin-left:auto}.md\:inline-block{display:inline-block}.md\:inline{display:inline}.md\:flex{display:flex}.md\:hidden{display:none}.md\:h-36{height:9rem}.md\:w-48{width:12rem}.md\:w-64{width:16rem}.md\:w-auto{width:auto}.md\:w-1\/2{width:50%}.md\:w-1\/3{width:33.333333%}.md\:flex-grow{flex-grow:1}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:justify-start{justify-content:flex-start}.md\:justify-end{justify-content:flex-end}.md\:justify-between{justify-content:space-between}.md\:px-4{padding-left:1rem;padding-right:1rem}.md\:py-8{padding-bottom:2rem;padding-top:2rem}.md\:pb-0{padding-bottom:0}.md\:text-left{text-align:left}.md\:text-sm{font-size:.875rem;line-height:1.25rem}.md\:text-base{font-size:1rem;line-height:1.5rem}.md\:text-xl{font-size:1.25rem;line-height:1.75rem}.md\:text-3xl{font-size:1.875rem;line-height:2.25rem}}@media (min-width:1024px){.lg\:mx-0{margin-left:0;margin-right:0}.lg\:mt-0{margin-top:0}.lg\:mt-2{margin-top:.5rem}.lg\:-mt-24{margin-top:-6rem}.lg\:mr-0{margin-right:0}.lg\:mb-0{margin-bottom:0}.lg\:ml-auto{margin-left:auto}.lg\:h-48{height:12rem}.lg\:w-1\/2{width:50%}.lg\:w-1\/3{width:33.333333%}.lg\:w-2\/3{width:66.666667%}.lg\:w-1\/4{width:25%}.lg\:flex-wrap{flex-wrap:wrap}.lg\:rounded-l-lg{border-bottom-left-radius:.5rem;border-top-left-radius:.5rem}.lg\:text-5xl{font-size:3rem;line-height:1}}@media (min-width:1280px){.xl\:mt-0{margin-top:0}.xl\:mr-4{margin-right:1rem}}
--------------------------------------------------------------------------------
/base-2021/css/tailwind/base-2021.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | @layer base {
6 | html {
7 | font-size: 18px;
8 | }
9 |
10 | a, a:hover {
11 | text-decoration: underline;
12 | }
13 |
14 | nav a,
15 | a.rounded,
16 | a.rounded-full {
17 | text-decoration: inherit;
18 | }
19 |
20 | a.pencil-editlink {
21 | text-decoration: none;
22 | opacity: 0.7;
23 | font-size: 75%;
24 | }
25 |
26 | a.pencil-editlink:hover {
27 | opacity: 1.0;
28 | }
29 | }
30 |
31 | /* Default grid, as used by the Article field type */
32 | .article-grid {
33 | display: grid;
34 | grid-template-columns: repeat(12, 1fr);
35 | grid-column-gap: 2rem;
36 | grid-row-gap: 0rem;
37 | }
38 |
39 | .article-grid + .article-grid {
40 | margin-top: 1rem;
41 | }
42 |
43 | .article-grid figure, .article-grid img {
44 | margin: 0;
45 | width: 100%;
46 | max-width: 100%;
47 | }
48 |
49 | .article-grid .col-1 { grid-column: span 1; }
50 | .article-grid .col-2 { grid-column: span 2; }
51 | .article-grid .col-3 { grid-column: span 3; }
52 | .article-grid .col-4 { grid-column: span 4; }
53 | .article-grid .col-5 { grid-column: span 5; }
54 | .article-grid .col-6 { grid-column: span 6; }
55 | .article-grid .col-7 { grid-column: span 7; }
56 | .article-grid .col-8 { grid-column: span 8; }
57 | .article-grid .col-9 { grid-column: span 9; }
58 | .article-grid .col-10 { grid-column: span 10; }
59 | .article-grid .col-11 { grid-column: span 11; }
60 | .article-grid .col-12 { grid-column: span 12; }
61 |
62 | .article-grid div p {
63 | margin-top: 0;
64 | }
65 |
66 | @media only screen and (max-width: 600px) {
67 | .article-grid {
68 | grid-template-columns: repeat(1, 1fr);
69 | }
70 |
71 | .article-grid .col-1,
72 | .article-grid .col-2,
73 | .article-grid .col-3,
74 | .article-grid .col-4,
75 | .article-grid .col-5,
76 | .article-grid .col-6,
77 | .article-grid .col-7,
78 | .article-grid .col-8,
79 | .article-grid .col-9,
80 | .article-grid .col-10,
81 | .article-grid .col-11,
82 | .article-grid .col-12 {
83 | grid-column: span 1;
84 | margin-bottom: 1rem;
85 | }
86 | }
87 |
88 | @layer utilities {
89 | @responsive {
90 |
91 | .article>p {
92 | margin: 1rem 0;
93 | font-size: clamp(1.1rem, 1.1vw, 1.6rem);
94 | }
95 |
96 | .article > ol {
97 | list-style-type: decimal;
98 | list-style-position: inside;
99 | font-size: clamp(1.1rem, 1.1vw, 1.6rem);
100 | }
101 |
102 | .article > ul {
103 | list-style-type: disc;
104 | list-style-position: inside;
105 | font-size: clamp(1.1rem, 1.1vw, 1.6rem);
106 | }
107 | .article h1 {
108 | font-size: clamp(1.875rem, 2.5vw, 2.25rem)
109 | }
110 | .article h2 {
111 | font-size: clamp(1.5rem, 2vw, 1.875rem)
112 | }
113 | .article h3 {
114 | font-size: clamp(1.25rem, 1.75vw, 1.5rem);
115 | font-weight: 700;
116 | }
117 | .article h4 {
118 | font-size: clamp(1.125rem, 1.5vw, 1.25rem)
119 | }
120 | .article h5 {
121 | font-size: 1rem;
122 | font-weight: 700;
123 | }
124 | .article h6 {
125 | font-size: 1rem;
126 | font-weight: 600;
127 | }
128 |
129 | .article blockquote>p {
130 | border-left-width: 4px;
131 | border-color: #b2f5ea;
132 | font-style: italic;
133 | margin-top: 2rem;
134 | margin-bottom: 2rem;
135 | padding-left: 2rem;
136 | font-size: clamp(1.875rem, 2.5vw, 2.25rem);
137 | }
138 |
139 | }
140 | }
141 | /* Base grid for "Article" powered Fields */
142 |
--------------------------------------------------------------------------------
/base-2021/img/hero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bolt/themes/205f78a1b2999cb08b4570816bcb2185d3dbd3a2/base-2021/img/hero.png
--------------------------------------------------------------------------------
/base-2021/img/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/base-2021/index.twig:
--------------------------------------------------------------------------------
1 | {% extends 'partials/_master.twig' %}
2 |
3 | {% block main %}
4 |
5 | {% include 'partials/_index_hero.twig' with { content: 'blocks/hero-section' } %}
6 |
7 | {% include 'partials/_index_divider_top.twig' %}
8 |
9 | {% include 'partials/_index_home_block.twig' with { content: 'homepage/1' } %}
10 |
11 | {% include 'partials/_index_vertical_block.twig' with { content: 'blocks/introduction', contenttype: 'pages' } %}
12 |
13 | {% include 'partials/_index_3_column_block_images.twig' with { contenttype: 'entries' } %}
14 |
15 | {% if 'people' in config.get('contenttypes').keys() %}
16 | {% include 'partials/_index_team.twig' with { content: 'blocks/people', contenttype: 'people' } %}
17 | {% endif %}
18 |
19 | {% if 'products' in config.get('contenttypes').keys() %}
20 | {% include 'partials/_index_pricing_block.twig' with { content: 'blocks/products', contenttype: 'products' } %}
21 | {% endif %}
22 |
23 | {% if 'pages' in config.get('contenttypes').keys() %}
24 | {% include 'partials/_index_3_column_block.twig' with { content: 'blocks/about', contenttype: 'pages' } %}
25 | {% endif %}
26 |
27 | {% include 'partials/_index_divider_bottom.twig' with { background: '#FFF' } %}
28 |
29 | {% include 'partials/_index_CTA.twig' with { content: 'blocks/call-to-action' } %}
30 |
31 | {% include 'partials/_index_divider_top.twig' with { background: '#f8fafc' } %}
32 |
33 | {% include 'partials/_index_contact_with_map.twig' %}
34 |
35 | {% endblock main %}
36 |
--------------------------------------------------------------------------------
/base-2021/js/app.js:
--------------------------------------------------------------------------------
1 |
2 | /*Toggle header colours*/
3 | var scrollpos = window.scrollY;
4 | var header = document.getElementById("header");
5 | var navcontent = document.getElementById("nav-content");
6 | var navaction = document.getElementById("navAction");
7 | var brandname = document.getElementById("brandname");
8 | var toToggle = document.querySelectorAll(".toggleColour");
9 |
10 | document.addEventListener('scroll', function() {
11 |
12 | /*Apply classes for slide in bar*/
13 | scrollpos = window.scrollY;
14 |
15 | if(scrollpos > 10){
16 | header.classList.add("bg-white");
17 | header.classList.remove("text-white");
18 | header.classList.add("text-black");
19 | //Use to switch toggleColour colours
20 | for (var i = 0; i < toToggle.length; i++) {
21 | toToggle[i].classList.add("text-black");
22 | toToggle[i].classList.remove("text-white");
23 | }
24 | header.classList.add("shadow");
25 |
26 | }
27 | else {
28 | header.classList.remove("bg-white");
29 | header.classList.remove("text-black");
30 | header.classList.add("text-white");
31 |
32 | //Use to switch toggleColour colours
33 | for (var i = 0; i < toToggle.length; i++) {
34 | toToggle[i].classList.add("text-white");
35 | toToggle[i].classList.remove("text-gray-800");
36 | }
37 |
38 | header.classList.remove("shadow");
39 |
40 |
41 | }
42 |
43 | });
44 |
45 |
46 |
47 | /*Toggle dropdown list*/
48 | /*https://gist.github.com/slavapas/593e8e50cf4cc16ac972afcbad4f70c8*/
49 |
50 | var navMenuDiv = document.getElementById("nav-content");
51 | var navMenu = document.getElementById("nav-toggle");
52 |
53 | document.onclick = check;
54 | function check(e){
55 | var target = (e && e.target) || (event && event.srcElement);
56 |
57 | //Nav Menu
58 | if (!checkParent(target, navMenuDiv) && navMenuDiv) {
59 | // click NOT on the menu
60 | if (checkParent(target, navMenu)) {
61 | // click on the link
62 | if (navMenuDiv.classList.contains("hidden")) {
63 | navMenuDiv.classList.remove("hidden");
64 | } else {
65 | navMenuDiv.classList.add("hidden");
66 | }
67 | } else {
68 | // click both outside link and outside menu, hide menu
69 | navMenuDiv.classList.add("hidden");
70 | }
71 | }
72 | }
73 | function checkParent(t, elm) {
74 | while(t.parentNode) {
75 | if( t == elm ) {return true;}
76 | t = t.parentNode;
77 | }
78 | return false;
79 | }
80 |
81 |
82 | /* Progress bar */
83 | //Source: https://alligator.io/js/progress-bar-javascript-css-variables/
84 | var h = document.documentElement,
85 | b = document.body,
86 | st = 'scrollTop',
87 | sh = 'scrollHeight',
88 | progress = document.querySelector('#progress'),
89 | scroll;
90 | var scrollpos = window.scrollY;
91 | var header = document.getElementById("header");
92 | var navcontent = document.getElementById("nav-content");
93 |
94 | document.addEventListener('scroll', function () {
95 | if(progress) {
96 | /*Refresh scroll % width*/
97 | scroll = (h[st] || b[st]) / ((h[sh] || b[sh]) - h.clientHeight) * 100;
98 | progress.style.setProperty('--scroll', scroll + '%');
99 |
100 | /*Apply classes for slide in bar*/
101 | scrollpos = window.scrollY;
102 | if (scrollpos > 10) {
103 | header.classList.add("bg-white");
104 | header.classList.add("shadow");
105 | } else {
106 | header.classList.remove("bg-white");
107 | header.classList.remove("shadow");
108 | }
109 | }
110 | });
111 |
--------------------------------------------------------------------------------
/base-2021/listing.twig:
--------------------------------------------------------------------------------
1 | {% extends 'partials/_master.twig' %}
2 |
3 | {% block main %}
4 |
5 | {# This template is used for 'listings': Generic pages that list a number of
6 | records from a certain content type. These records are available as an array
7 | called 'records'. In the for-loop below, we iterate over the records that
8 | are on this page. It can be used for overview pages like 'all entries', or
9 | 'all records tagged with kittens'. #}
10 |
11 |
12 |
13 |
14 | {# If used for listing a taxonomy, we add a heading #}
15 | {% if taxonomy is defined %}
16 |
12 |
--------------------------------------------------------------------------------
/base-2021/partials/_contact_form_extension.twig:
--------------------------------------------------------------------------------
1 | {# We've put this in a separate partial, because this is needed for correct
2 | behaviour: The Twig parser parses the entire document, and _then_ executes it.
3 | This means we can't parse a template that checks if a tag might exist or not.
4 | By putting this in a separate file, we circumvent that limitation. #}
5 | {{ boltforms('contact') }}
--------------------------------------------------------------------------------
/base-2021/partials/_contact_form_static.twig:
--------------------------------------------------------------------------------
1 |
4 |
7 |
10 |
--------------------------------------------------------------------------------
/base-2021/partials/_footer.twig:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/base-2021/partials/_index_3_column_block.twig:
--------------------------------------------------------------------------------
1 | {% from 'macros.twig' import edit as edit %}
2 |
3 | {# The name of the `content` is passed in from the index, i.e. "blocks/people" #}
4 | {% setcontent block = (content) returnsingle %}
5 |
6 | {# The name of `contenttype` is passed in from the index, i.e. "people" #}
7 | {% setcontent records = (contenttype) limit 3 random %}
8 |
9 |
10 | {# no `border-b` (border-bottom) #}
11 |
12 | {% include 'partials/_block_header.twig' %}
13 |
14 | {% for record in records %}
15 |
43 |
44 |
--------------------------------------------------------------------------------
/base-2021/partials/_index_3_column_block_images.twig:
--------------------------------------------------------------------------------
1 | {# The name of `contenttype` is passed in from the index, i.e. "entries" #}
2 | {% setcontent records = (contenttype) limit 3 latest %}
3 |
4 |
5 |
6 |
46 |
47 |
--------------------------------------------------------------------------------
/base-2021/partials/_index_CTA.twig:
--------------------------------------------------------------------------------
1 | {% from 'macros.twig' import edit as edit %}
2 |
3 | {# The name of the `content` is passed in from the index, i.e. "blocks/people" #}
4 | {% setcontent block = (content) returnsingle %}
5 |
6 |
7 |
8 |
{{ block|title }}
9 |
10 |
11 |
12 |
{{ block|excerpt }}
13 |
15 | Action!
16 |
17 |
18 |
--------------------------------------------------------------------------------
/base-2021/partials/_index_contact_with_map.twig:
--------------------------------------------------------------------------------
1 | {# Configure the address and location of the map in `public/theme/base-2021/theme.yaml`. #}
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/base-2021/partials/_index_hero.twig:
--------------------------------------------------------------------------------
1 | {% from 'macros.twig' import edit as edit %}
2 |
3 | {# The name of the `content` is passed in from the index, i.e. "blocks/hero" #}
4 | {% setcontent block = (content) returnsingle %}
5 |
6 |
7 |
24 |
--------------------------------------------------------------------------------
/base-2021/partials/_index_home_block.twig:
--------------------------------------------------------------------------------
1 | {% from 'macros.twig' import edit as edit %}
2 |
3 | {# The name of the `content` is passed in from the index, i.e. "homepage/1" #}
4 | {% setcontent block = (content) returnsingle %}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
{{ block|title }} {{ edit(block) }}
14 | {{ block.introduction }}
15 |
16 |
17 |
18 | {% if record|image %}
19 |
20 |
22 |
23 | {% endif %}
24 |
25 |
26 | {{ block.content }}
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/base-2021/partials/_index_pricing_block.twig:
--------------------------------------------------------------------------------
1 | {% from 'macros.twig' import edit as edit %}
2 |
3 | {# The name of the `content` is passed in from the index, i.e. "blocks/products" #}
4 | {% setcontent block = (content) returnsingle %}
5 |
6 | {# The name of `contenttype` is passed in from the index, i.e. "people" #}
7 | {% setcontent records = (contenttype) limit 3 %}
8 |
9 |
10 |
11 |
12 | {% include 'partials/_block_header.twig' %}
13 |
14 |
15 |
16 | {% for record in records %}
17 | {% if loop.index == 2 %}
18 |
19 |
20 |
{{ record|title }} {{ edit(block) }}
21 |
22 |
23 |
✅ {{ record.feature_1 }}
24 |
✅ {{ record.feature_2 }}
25 |
✅ {{ record.feature_3 }}
26 |
27 |
28 |
29 | {{ record|excerpt(100, wrap=true) }}
30 |
31 | {{ record.price|default('unknown')}}
32 | per month
33 |
34 |
35 |
38 |
39 |
40 |
41 | {% else %}
42 |
43 |
44 |
{{ record|title }}
45 |
46 |
✅ {{ record.feature_1 }}
47 |
✅ {{ record.feature_2 }}
48 |
✅ {{ record.feature_3 }}
49 |
50 |
51 |
52 | {{ record|excerpt(100, wrap=true) }}
53 |
54 | {{ record.price|default('unknown')}}
55 | per month
56 |
57 |
58 |
61 |
62 |
63 |
64 | {% endif %}
65 | {% endfor %}
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/base-2021/partials/_index_team.twig:
--------------------------------------------------------------------------------
1 | {% from 'macros.twig' import edit as edit %}
2 |
3 | {# The name of the `content` is passed in from the index, i.e. "blocks/people" #}
4 | {% setcontent block = (content) returnsingle %}
5 |
6 | {# The name of `contenttype` is passed in from the index, i.e. "people" #}
7 | {% setcontent records = (contenttype) limit 4 random returnmultiple %}
8 |
9 |
10 |
11 |
12 | {% include 'partials/_block_header.twig' %}
13 |
14 |
48 |
49 |
--------------------------------------------------------------------------------
/base-2021/partials/_index_vertical_block.twig:
--------------------------------------------------------------------------------
1 | {% from 'macros.twig' import edit as edit %}
2 |
3 | {# The name of the `content` is passed in from the index, i.e. "blocks/introduction" #}
4 | {% setcontent block = (content) returnsingle %}
5 |
6 | {# The name of `contenttype` is passed in from the index, i.e. "pages" #}
7 | {% setcontent records = (contenttype) limit 4 %}
8 |
9 |
10 |
11 |
12 | {% include 'partials/_block_header.twig' %}
13 |
14 | {% for record in records %}
15 |
16 | {% if loop.index is odd and record|image %}
17 |
8 |
9 | {# Remove this block if you don't need it anymore. #}
10 | {{ include('partials/_fresh_install.twig') }}
11 |
12 | {# Output the `introduction` field. If it doesn't exist, 'default' to
13 | the full excerpt of the current Record #}
14 | {{ record.introduction|default(record|excerpt) }}
15 |
16 | {% include 'partials/_image.twig' with ({'image': record|image}) %}
17 |
18 | {{ record.content }}
19 |
20 | {{ include('partials/_recordfooter.twig', { 'record': record }) }}
21 |
22 | {% endif %}
23 |
24 | {% endblock main %}
25 |
26 | {% block aside %}
27 |
28 | {{ include('partials/_aside.twig') }}
29 |
30 | {% endblock aside %}
31 |
--------------------------------------------------------------------------------
/skeleton/listing.twig:
--------------------------------------------------------------------------------
1 | {% extends 'partials/_master.twig' %}
2 |
3 | {% block main %}
4 |
5 | {# This template is used for 'listings': Generic pages that list a number of
6 | records from a certain content type. These records are available as an array
7 | called 'records'. In the for-loop below, we iterate over the records that
8 | are on this page. It can be used for overview pages like 'all entries', or
9 | 'all records tagged with kittens'. #}
10 |
11 | {# If used for listing a taxonomy, we add a heading #}
12 | {% if taxonomy is defined %}
13 |
9 | Note: Only currently logged-on users will see this. This piece of content is hidden from regular visitors.
10 |
11 | {% endif %}
12 |
--------------------------------------------------------------------------------
/skeleton/partials/_header.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 | {# the values in the 'config' object are taken directly from the file app/config/config.yml #}
4 |
14 | {{ __('general.phrase.permalink') }} -
15 | {# include the 'default' links to taxonomies. Check the documentation for ways to modify and customize
16 | what is output to the browser: https://docs.bolt.cm/contenttypes/taxonomies#displaying-taxonomies-in-templates #}
17 | {{ include('partials/_sub_taxonomylinks.twig', { record: record }) }}
18 |
19 |
20 | {% set previous = previous_record(record, byColumn='id') %}
21 | {% set next = next_record(record, byColumn='id') %}
22 |
23 | {% if previous or next %}
24 |
25 | {% if previous %}
26 | « {{ previous|title }}
27 | {% endif %}
28 | {% if previous and next %}
29 | -
30 | {% endif %}
31 | {% if next %}
32 | {{ next|title }} »
33 | {% endif %}
34 |
35 | {% endif %}
36 |
37 | {% set related_content_types = record|related_by_type %}
38 |
39 | {% if related_content_types is not empty %}
40 |
{{ __('general.phrase.related-content') }}
41 | {% for content_type, related_records in related_content_types %}
42 |
Related {{ config.get('contenttypes/' ~ content_type ~ '/name') }}
43 |
44 | {% for related_record in related_records %}
45 |
48 | {% endfor %}
49 | {% endif %}
50 |
51 | {% endif %}
52 |
--------------------------------------------------------------------------------
/skeleton/partials/_sub_menu.twig:
--------------------------------------------------------------------------------
1 | {# This file might seem a little complex, because of the high density of tags.
2 | It uses Twig macros and ternary selectors. Read up on them, if required:
3 | macros: http://twig.sensiolabs.org/doc/templates.html#macros
4 | ternary operators: http://twig.sensiolabs.org/doc/templates.html#other-operators
5 | #}
6 |
7 | {# The 'recursive' macro, for inserting one menu item. If it has a submenu, it
8 | invokes itself to insert the items of the submenus. #}
9 | {% macro display_menu_item(item, loop, withsubmenus) %}
10 | {% from _self import display_menu_item %}
11 | {% apply spaceless %}
12 | {% set with_submenu = withsubmenus and item.submenu is not empty %}
13 |
31 | {% endapply %}
32 | {% endmacro %}
33 |
34 | {# Make the macro available for use #}
35 | {% from _self import display_menu_item %}
36 |
37 | {# The main menu loop: Iterates over the items, calling `display_menu_item` #}
38 |
39 | {% for item in menu %}
40 | {% if item.label is defined %}
41 | {{ display_menu_item(item, loop, withsubmenus) }}
42 | {% endif %}
43 | {% endfor %}
44 |
45 |
46 |
--------------------------------------------------------------------------------
/skeleton/partials/_sub_menu_header.twig:
--------------------------------------------------------------------------------
1 | {# This file might seem a little complex, because of the high density of tags.
2 | It uses Twig macros and ternary selectors. Read up on them, if required:
3 | macros: http://twig.sensiolabs.org/doc/templates.html#macros
4 | ternary operators: http://twig.sensiolabs.org/doc/templates.html#other-operators
5 | #}
6 |
7 | {# The 'recursive' macro, for inserting one menu item. If it has a submenu, it
8 | invokes itself to insert the items of the submenus. #}
9 | {% macro display_menu_item(item, loop, withsubmenus) %}
10 | {% from _self import display_menu_item %}
11 | {% apply spaceless %}
12 |
15 | {{- item.label -}}
16 |
17 | {% endapply %}
18 | {% endmacro %}
19 |
20 | {# Make the macro available for use #}
21 | {% from _self import display_menu_item %}
22 |
23 | {# The main menu loop: Iterates over the items, calling `display_menu_item` #}
24 |
32 |
33 |
--------------------------------------------------------------------------------
/skeleton/partials/_sub_taxonomylinks.twig:
--------------------------------------------------------------------------------
1 | {% for type, taxonomies in record|taxonomies %}
2 |
3 | {% if taxonomies|length == 1 %}
4 | {{ config.get('taxonomies')[type].singular_name }}:
5 | {% elseif taxonomies|length > 1 %}
6 | {{ config.get('taxonomies')[type].name }}:
7 | {% endif %}
8 |
9 | {% for taxonomy in taxonomies %}
10 | {{ taxonomy.name }}{% if not loop.last %}, {% endif %}
11 | {% else %}
12 | {{ __('general.phrase.none') }}
13 | {% endfor %}
14 | {% if not loop.last %} - {% endif %}
15 | {% endfor %}
16 |
--------------------------------------------------------------------------------
/skeleton/record.twig:
--------------------------------------------------------------------------------
1 | {% extends 'partials/_master.twig' %}
2 |
3 | {% block main %}
4 |
5 |
{{ record|title }}
6 |
7 | {% include 'partials/_image.twig' with ({'image': record|image}) %}
8 |
9 | {# Output all fields, in the order as defined in the content type.
10 | To change the generated html and configure the options, see:
11 | https://docs.bolt.cm/templating #}
12 | {% with { 'record': record, 'exclude': [record|image.fieldname|default()] } %}
13 | {{ block('sub_fields', 'helpers/_fields.twig') }}
14 | {% endwith %}
15 |
16 | {# Uncomment this if you wish to dump the entire record to the client, for debugging purposes.
17 | {{ dump(record) }}
18 | #}
19 |
20 |
21 | {% include 'partials/_recordfooter.twig' with { 'record': record, 'extended': true } %}
22 |
23 | {% endblock main %}
24 |
--------------------------------------------------------------------------------
/skeleton/search.twig:
--------------------------------------------------------------------------------
1 | {% extends 'partials/_master.twig' %}
2 |
3 | {% block main %}
4 |
5 | {# This template is used for search results. If 'search' is defined,
6 | we display an appropriate title. The 'records' array contains all of the
7 | records matching the current query. If there are no results, the
8 | code in the 'else' part of the for-loop is used. #}
9 |
16 |
17 | {# Perhaps we post a small teaser, stored in the 'block' named 'Search teaser' #}
18 | {% setcontent block = "block/search-teaser" %}
19 |
20 | {# check if we have 'content'. If so, we know we have have a teaser to display. #}
21 | {% if block and block.content %}
22 | {{ block.content }}
23 | {% endif %}
24 |
25 |
29 |
30 | {% for record in records %}
31 |
32 |
33 |
59 |
60 | {% endfor %}
61 |
62 | {# If there are more records than will fit on one page, the pager is shown. #}
63 | {{ pager(records, template = 'helpers/_pager_basic.html.twig') }}
64 |
65 | {% endblock main %}
66 |
--------------------------------------------------------------------------------
/skeleton/theme.yaml:
--------------------------------------------------------------------------------
1 | # Optional config file for the theme.
2 |
3 | # Variables that are in this file, can be used in your twig template like {{ theme.foo }}
4 |
5 | # Template filenames. If you 're creating a theme for distribution, you can specify
6 | # the filenames of the templates here. The templates you will set in this config
7 | # file will override the ones in the global app/config/config.yml, so beware!
8 | # maintenance_template: maintenance_default.twig
9 | # homepage_template: index.twig
10 | # record_template: record.twig
11 | # listing_template: listing.twig
12 | # search_results_template: search.twig
13 | # notfound: notfound.twig
14 |
--------------------------------------------------------------------------------