3 |
4 |
5 |
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/layouts/README.md:
--------------------------------------------------------------------------------
1 | # LAYOUTS
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your Application Layouts.
6 |
7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts).
8 |
--------------------------------------------------------------------------------
/static/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 | #ffffff
--------------------------------------------------------------------------------
/assets/README.md:
--------------------------------------------------------------------------------
1 | # ASSETS
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your un-compiled assets such as LESS, SASS, or JavaScript.
6 |
7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked).
8 |
--------------------------------------------------------------------------------
/plugins/README.md:
--------------------------------------------------------------------------------
1 | # PLUGINS
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains Javascript plugins that you want to run before mounting the root Vue.js application.
6 |
7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins).
8 |
--------------------------------------------------------------------------------
/pages/howto.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
21 |
--------------------------------------------------------------------------------
/middleware/README.md:
--------------------------------------------------------------------------------
1 | # MIDDLEWARE
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your application middleware.
6 | Middleware let you define custom functions that can be run before rendering either a page or a group of pages.
7 |
8 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware).
9 |
--------------------------------------------------------------------------------
/pages/store.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Store
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/store/README.md:
--------------------------------------------------------------------------------
1 | # STORE
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your Vuex Store files.
6 | Vuex Store option is implemented in the Nuxt.js framework.
7 |
8 | Creating a file in this directory automatically activates the option in the framework.
9 |
10 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store).
11 |
--------------------------------------------------------------------------------
/static/README.md:
--------------------------------------------------------------------------------
1 | # STATIC
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your static files.
6 | Each file inside this directory is mapped to `/`.
7 | Thus you'd want to delete this README.md before deploying to production.
8 |
9 | Example: `/static/robots.txt` is mapped as `/robots.txt`.
10 |
11 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static).
12 |
--------------------------------------------------------------------------------
/components/core/heading/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
16 | I created Theme4Nuxt in order to have a fast way to prototype and create themes for nuxtjs.
17 | I usually create apps from scratch, and after trying different UI tools for Vue or Nuxt like Vuetify, Bootstrap, etc.
18 | Also all the components that you get are really difficult to customize for your needs. I think that they are really good frameworks, but trying to use them to adapt to real customer needs comes a hard job.
19 | Many times I had to rewrite my own components, so I decide to go with another strategy.
20 |
21 |
22 | I found that all of them are opinionated frameworks, that don't give you the real possibility to create you own custom design. Using them all your products will look the same.
23 |
24 |
25 | Looking around for some tools and solution I found "tailwind" a css framework that is not a framework.
26 |
27 |
I think it's what a developer needs to create custom design feeling free to add your own components and fit them with the general UI/UX design.
28 | I mean, if you are a real developer usually you need to create custom components for different projects.
29 | I know this very well because when you think you found a good component, then a customer needs something like that but ... but with some changes or improvements.
30 |
31 |
32 | So I started creating basic components, but I always had the same problem: the design.
33 |
34 |
35 | Adapting the component to different custom design is a difficult job (it was) mostly on CSS. Tailwind solved my problem. With the easy way to implement real custom design using semantic classes it solves many of developer problems.
36 |
37 |
38 | Then working on nuxt project I started creating my layout templates in order to prototype different themes/design.
39 | Since I always think that a good theme/design has to follow the semantic rules (header,section,aside,footer), I started to think to a solution that starting from a configuration file (a js/json file) create a layout template dinamically.
40 | My goals where:
41 |
42 |
43 |
use configuration file to create a theme
44 |
fast switching theme with no code rewriting on vue files
45 |
follow semantic rules for generated pages (ssr rendering)
',
283 | action: '/howto'
284 | }
285 | */
286 | }
287 |
288 | export default layout
--------------------------------------------------------------------------------
/pages/README.md:
--------------------------------------------------------------------------------
1 | # theme4nuxt
2 |
3 |
4 | Theme4Nuxt is a basic theming solution for Nuxtjs. I decided to develop it in order to have an easy way to prototype layouts/themes for Nuxt using a configuration file.
5 |
6 | Based only on `tailwind.css` framework is developed to give the possibility to create your custom design without any opinionated framework.
7 |
8 | # Features
9 |
10 | - custom design based on CSS only
11 | - fast theme/layout prototype
12 | - create html semantic elements (header,section,aside,footer)
13 | - easy full responsive design implementation
14 | - easy integration with existing
15 | - components
16 | - api
17 | - markdown pages
18 | - easy theme switching
19 | - homepage design
20 | - extra basic components included (used in this demo)
21 | - responsive navigation
22 | - progress bars
23 | - cards
24 | - features/services info box
25 | - call for action
26 |
27 |
28 | # How it works
29 |
30 | **Requirements** : tailwind.css
31 |
32 |
33 | Theme4Nuxt is based on the following:
34 | - a **theme** js file (./themes/index.js)
35 | - a **single vue** file to deploy the theme to be used as layout template (./layout/theme.vue)
36 | - a Vue **component wrapper** in order to integrate any component dynamically (./components/theme/ComponentWrapper.vue)
37 | - a Vue **navigation component** in order to create a navigation system (./components/theme/nav/index.vue)
38 | - a **theme4nuxt** plugin in order to preload data server side (./plugins/theme4nuxt.js)
39 |
40 |
41 |
42 | ## Theme file
43 |
44 | Create a `themes` folder in your project root.
45 |
46 | Create an `index.js` in the themes folder
47 |
48 | #### Structure of the theme
49 |
50 | Each theme configuration file has the following structure:
51 |
52 |
53 | - theme general info (name, author, version, license)
54 | - a **root** property with css classes. This is the main container of your theme
55 | - a **homepage** property with the path for the homepage
56 | - a **initData** array of objects representing the initial data to load at startup. Data can be **API** or **Array**
57 | - a **navigation** array of objects. You can define different navigations and then use in your templates.
58 | - a **template** the main object of your theme.
59 |
60 |
61 | ```
62 | const theme = {
63 | name : 'Corporate Business',
64 | author : 'A. Nardone',
65 | version : '0.2.0',
66 | license : 'MIT'
67 | root : 'w-full flex flex-wrap min-h-screen',
68 | homepage : '/',
69 | ...
70 | }
71 |
72 | export default theme
73 | ```
74 | ### initData Section ###
75 | The **initData** is where you can define which data has to be preloaded.
76 |
77 | They can be **API** or **arrays** of data, depends on your rendering functions/components.
78 |
79 | *The current theme is using some WordPress API to simulate the preloading feature*
80 |
81 | ```
82 | initData : [
83 | { type: 'api' , name: 'posts' , api : 'https://www.techcrunch.com/wp-json/wp/v2/posts' } ,
84 | { type: 'array' , name: 'services' , value : [
85 | {"type":"services",
86 | "title":"CSS Only",
87 | "abstract":"Theme4Nuxt is developed using only CSS with the Tailwind framework",
88 | "path":"css-only",
89 | "_id":"0tSvdJebN4cKmKa6",
90 | "icon":"style"},
91 | {"type":"services",
92 | "title":"Custom Design",
93 | "abstract":"Create your custom theme without any opinionated framework",
94 | "icon":"chrome_reader_mode",
95 | "path":"theme-builder",
96 | "_id":"MSOXCaCn4AfNz57w"},
97 | {"type":"services",
98 | "title":"Integration",
99 | "abstract":"Feel free to use your own components, API and data",
100 | "path":"api-data",
101 | "_id":"ueN9BbEdxvKoZWNi"
102 | ,"icon":"compare_arrows"}
103 | ] },
104 | { type: 'array' , name: 'skills' , value : [{name:'CREATIVITY' , value: "90%"} , { name: 'ORGANIZATION' , value: "85%"} , { name: 'TEAM WORK' , value: "75%"} , { name: 'COMMUNICATION' , value: "70%"}]
105 | }
106 | ],
107 | ```
108 |
109 | In case of API **axios** library will be used to fetch data (asyncronously) server side.
110 |
111 | **Data preloading is implemented using `nuxtServerInit` directly from the store.**
112 |
113 | file: ./store/index.js
114 |
115 | ```
116 | ...
117 | async nuxtServerInit({commit}, context ){
118 | //read theme configuration using $theme4nuxt() injected by ./plugins/index.js
119 | let init = context.app.$theme4nuxt().initData
120 | let data = {}
121 | //iterate thru all initial data to be loaded
122 | for ( var n=0 ; n < init.length ; n++ ){
123 | if ( init[n].type === 'api' ) {
124 | let qry = await context.app.$axios.get(init[n].api);
125 | data[init[n].name] = qry.data
126 | }
127 | if ( init[n].type === 'array' ){
128 | data[init[n].name] = init[n].value
129 | }
130 | }
131 | //save data to store
132 | commit ('init_data', data )
133 | if ( !context.app.store.state.theme ){
134 | commit ('theme',context.app.$theme4nuxt() )
135 | }
136 | },
137 | ...
138 | ```
139 |
140 | **Preload theme and injext function to read initData configuration**
141 |
142 | file: ./plugins/index.js
143 |
144 | ```
145 | import theme from '~/themes'
146 |
147 | export default ({ app }, inject) => {
148 | inject('theme4nuxt', () => theme)
149 | }
150 | ```
151 | # The Theme #
152 |
153 | We analyze the current theme that has been used for this website.
154 |
155 | ### navigation Section ###
156 |
157 | The navigation section is required if you want to use the built-in navigation system as showed in the demo. This component create a responsive main navigation icon that open a menu with the options defined.
158 |
159 | The navigation section is also used in the template in order to render a normal navigation menu.
160 | In this version child menus are not supported. If you need this option you can use your component or navigation system.
161 |
162 | ```
163 | ...
164 | navigation : [{
165 | css : "items-start w-full pt-16 px-4 pb-20 bg-black opacity-75 h-screen",
166 | button : "m-1 bg-white p-2 border-black border-2 rounded-full",
167 | line : "hover:text-black hover:bg-white text-grey-lightest" ,
168 | link : 'text-white hover:text-black hover:bg-white hover:text-bold py-10 px-4 no-underline',
169 | left : false,
170 | transition: 'slideright',
171 | orientation: 'horizontal' ,
172 | items: [ { name : 'Home' , path: '/' } , { name: 'Blog' , path: '/blog' } , { name: 'About' , path: '/about' } , { name: 'How to' , path: '/howto' } ]
173 | }],
174 | ...
175 | ```
176 |
177 | ### template Section ###
178 |
179 | The **template** section is the core of the theming system and has 2 main objects
180 | - **main**
181 | - **areas**
182 |
183 |
184 |
185 |
186 | The ***main*** object
187 |
188 | The main object is where is defined the class of the main container and will generate a semantic **<main>** html element.
189 | ```
190 | ...
191 | template: {
192 | main : {
193 | css : "w-full",
194 |
195 | },
196 | ...
197 | ```
198 |
199 |
200 |
201 | The **areas** object
202 |
203 | With the areas object you define all the elements of your template.
204 |
205 | First you can define the order of the area to be rendered as semantic html blocks. Available areas are:
206 | - header
207 | - aside
208 | - content (will be rendered as section)
209 | - footer
210 |
211 | **order is important in order to render elements correctly**
212 |
213 |
214 | ```
215 | ...
216 | template: {
217 | ...
218 | areas: {
219 | order : ['header','content','footer'],
220 | ...
221 | ```
222 |
223 | Our example will create a **header**, a **section** area and a **footer**.
224 |
225 |
226 | ### Creating the header ###
227 |
228 | ```
229 | ...
230 | template: {
231 | ...
232 | areas: {
233 | areas: {
234 | order : ['header','content','footer'],
235 | header : {
236 | root: 'w-full flex flex-wrap',
237 | blocks : [
238 | {
239 | css: 'w-1/2 flex items-center h-12 bg-black text-grey text-xs pl-4 mobile',
240 | elements: [
241 | { type: 'html' , content: '\
242 | theme4nuxt@moodgiver.com\
243 | '}
244 | ]
245 | },
246 | {
247 | css: 'w-1/2 flex items-center justify-end h-12 bg-black text-grey text-xs pr-16 mobile',
248 | elements: [
249 | { type: 'html' , content: '\
250 | +1 123 456 7890\
251 | '}
252 | ]
253 | },
254 | {
255 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 h-24 opacity-75 justify-end flex items-center col bg-black' ,
256 | elements : [
257 | { type: 'html' , content: '
Theme4Nuxt
' , homepage: false }
258 | ],
259 | homepage: false
260 | },
261 | {
262 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 border-l opacity-75 h-24 col z-30 justify-left items-center flex text-right pr-12 col-nav bg-black mobile' ,
263 | elements : [
264 | { type: 'menu' , navigation: 0, homepage: false}
265 | ]
266 | },
267 | {
268 | css: 'w-full bg-green-light h-128 -mt-24 bg-header-8',
269 | elements: [
270 | { type: 'html' , content: ''}
271 | ],
272 | homepage: true
273 | }
274 |
275 | ]
276 | },
277 | ...
278 | ```
279 | In order to create a semantic html **<header>** element we create a header object. Following structure will be used for each defined area.
280 |
281 | For each section (header, aside, content, footer) we have :
282 |
283 | - **root** element container (css)
284 | - **blocks** array of objects
285 |
286 | In our theme we wanted to create:
287 | - a top bar with email and phone ref,
288 | - a header with a logo/title centered,
289 | - a centered menu right to the title
290 | - an image as heading
291 |
292 |
293 |
294 | The top bar block.
295 | ```
296 | ...
297 |
298 | header : {
299 | root: 'w-full flex flex-wrap',
300 | blocks : [
301 | {
302 | css: 'w-1/2 flex items-center h-12 bg-black text-grey text-xs pl-4 mobile',
303 | elements: [
304 | { type: 'html' , content: '\
305 | theme4nuxt@moodgiver.com\
306 | '}
307 | ],
308 | homepage: false
309 | },
310 | {
311 | css: 'w-1/2 flex items-center justify-end h-12 bg-black text-grey text-xs pr-16 mobile',
312 | elements: [
313 | { type: 'html' , content: '\
314 | +1 123 456 7890\
315 | '}
316 | ],
317 | homepage: false
318 | },
319 | ...
320 | }
321 | }
322 | ```
323 |
324 | For each block we have to define
325 |
326 | - **css** : tailwind css classes for the block
327 | - **elements** : array of elements we want to render
328 | - **homepage** : set to true in order to display only in the homepage
329 |
330 | **elements** is an array of object that will be rendered following the order in which they are created.
331 |
332 | ### elements types ##
333 | Each element has the following properties to be set
334 |
335 | - **type**
336 |
337 | the system manage the following types of elements:
338 | - **html**
339 | - **component**
340 | - **menu**
341 | - **css**
342 |
343 |
344 | ### The *html* element ###
345 |
346 | So far for our title we create a css full-width element with other css properties (height, color, items alignment, etc. etc.) as a container.
347 |
348 | Then we created a **html** element type.
349 |
350 | For the **html** element type we must provide the content thru the **content** value. In this case we will assign directly HTML code to inject and render. In this way you can assign css to your html content and it will be rendered correctly.
351 |
352 | ### The *menu* element ###
353 |
354 | In order to render our menu we create a new row (block object) with his proper css.
355 |
356 | In order to render the right menu we have to assign which item in the navigation array we will use. Assign the navigation value representing the posisition in the navigation array (in our case we have only one navigation menu so we assign a value of 0).
357 |
358 | ```
359 | ...
360 |
361 | header : {
362 | root: 'w-full flex flex-wrap',
363 | blocks : [
364 | ...
365 | {
366 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 border-l opacity-75 h-24 col z-30 justify-left items-center flex text-right pr-12 col-nav bg-black mobile' ,
367 | elements : [
368 | { type: 'menu' , navigation: 0, homepage: false}
369 | ],
370 | homepage: false
371 | },
372 | ...
373 | }
374 | ...
375 | ```
376 | ### Creating the content ###
377 |
378 | In order to create the content, that will be rendered as a semantic HTML **<section>** we follow the same structure.
379 |
380 | We will analyze only how to integrate a component in the theme.
381 |
382 | **Component theme integration**
383 |
384 | ```
385 | ...
386 |
387 | content : {
388 |
389 | root: 'w-full flex flex-wrap',
390 | blocks : [
391 | {
392 | css: 'w-full bg-transparent text-grey mx-4 -mt-20 py-6',
393 | elements: [
394 | { type: 'component' , component: 'core/services' , options: { data: 'services' , title: 'Features' } },
395 | ],
396 | homepage: true
397 | },
398 | ...
399 | ]
400 | }
401 | ...
402 | ```
403 |
404 | To load a custom component we have to define as element the following data:
405 | - **type** : "component",
406 | - **component** : the path of our component (if you are using a vue component with a different name from index.vue you need to define ex. /mycomponent/mycomponent.vue will load the mycomponent.vue in the folder mycomponent of the components folder)
407 | - **options** : an object of options that you need to pass to your components (props)
408 |
409 |
410 | Theme4Nuxt loads components dynamically using a component wrapper.
411 |
412 | Theme4Nuxt component wrapper (components/theme/ComponentWrapper.vue)
413 |
414 | ```html
415 |
416 |
417 |
418 |
419 |
420 |
421 |
434 | ```
435 |
436 |
437 |
438 |
439 | ## Nuxt configuration
440 |
441 | In order to work properly you need to update your nuxt.config.js with the following
442 |
443 | file: ./nuxt.config.js
444 |
445 | ```js
446 | css: [
447 | '~/assets/css/tailwind.css' //if you set a nuxt project with tailwind framework you should have this
448 | ],
449 |
450 | plugins: [
451 | '~/plugins/index.js',
452 | '~/components/theme' //load all theme required components
453 | ],
454 |
455 | modules: [
456 | '@nuxtjs/axios',
457 | '@nuxtjs/pwa',
458 | '@nuxtjs/markdownit' //used to integrate markdown files
459 | ],
460 | ...
461 |
462 | ```
463 |
464 |
465 | ## Build Setup
466 |
467 | ``` bash
468 | # install dependencies
469 | $ npm install
470 |
471 | # serve with hot reload at localhost:3000
472 | $ npm run dev
473 |
474 | # build for production and launch server
475 | $ npm run build
476 | $ npm start
477 |
478 | # generate static project
479 | $ npm run generate
480 | ```
481 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # theme4nuxt
2 |
3 |
4 | Theme4Nuxt is a basic theming solution for Nuxtjs. I decided to develop it in order to have an easy way to prototype layouts/themes for Nuxt using a configuration file.
5 |
6 | Based only on `tailwind.css` framework is developed to give the possibility to create your custom design without any opinionated framework.
7 |
8 | # Demo
9 |
10 | (A simple demo)[https://theme4nuxt.firebaseapp.com/]
11 |
12 |
13 | # Features
14 |
15 | - custom design based on CSS only
16 | - fast theme/layout prototype
17 | - create html semantic elements (header,section,aside,footer)
18 | - easy full responsive design implementation
19 | - easy integration with existing
20 | - components
21 | - api
22 | - markdown pages
23 | - easy theme switching
24 | - homepage design
25 | - extra basic components included (used in this demo)
26 | - responsive navigation
27 | - progress bars
28 | - cards
29 | - features/services info box
30 | - call for action
31 |
32 |
33 | # How it works
34 |
35 | **Requirements** : tailwind.css
36 |
37 |
38 | Theme4Nuxt is based on the following:
39 | - a **theme** js file (./themes/index.js)
40 | - a **single vue** file to deploy the theme to be used as layout template (./layout/theme.vue)
41 | - a Vue **component wrapper** in order to integrate any component dynamically (./components/theme/ComponentWrapper.vue)
42 | - a Vue **navigation component** in order to create a navigation system (./components/theme/nav/index.vue)
43 | - a **theme4nuxt** plugin in order to preload data server side (./plugins/theme4nuxt.js)
44 |
45 |
46 |
47 | ## Theme file
48 |
49 | Create a `themes` folder in your project root.
50 |
51 | Create an `index.js` in the themes folder
52 |
53 | #### Structure of the theme
54 |
55 | Each theme configuration file has the following structure:
56 |
57 |
58 | - theme general info (name, author, version, license)
59 | - a **root** property with css classes. This is the main container of your theme
60 | - a **homepage** property with the path for the homepage
61 | - a **initData** array of objects representing the initial data to load at startup. Data can be **API** or **Array**
62 | - a **navigation** array of objects. You can define different navigations and then use in your templates.
63 | - a **template** the main object of your theme.
64 |
65 |
66 | ```
67 | const theme = {
68 | name : 'Corporate Business',
69 | author : 'A. Nardone',
70 | version : '0.2.0',
71 | license : 'MIT'
72 | root : 'w-full flex flex-wrap min-h-screen',
73 | homepage : '/',
74 | ...
75 | }
76 |
77 | export default theme
78 | ```
79 | ### initData Section ###
80 | The **initData** is where you can define which data has to be preloaded.
81 |
82 | They can be **API** or **arrays** of data, depends on your rendering functions/components.
83 |
84 | *The current theme is using some WordPress API to simulate the preloading feature*
85 |
86 | ```
87 | initData : [
88 | { type: 'api' , name: 'posts' , api : 'https://www.techcrunch.com/wp-json/wp/v2/posts' } ,
89 | { type: 'array' , name: 'services' , value : [
90 | {"type":"services",
91 | "title":"CSS Only",
92 | "abstract":"Theme4Nuxt is developed using only CSS with the Tailwind framework",
93 | "path":"css-only",
94 | "_id":"0tSvdJebN4cKmKa6",
95 | "icon":"style"},
96 | {"type":"services",
97 | "title":"Custom Design",
98 | "abstract":"Create your custom theme without any opinionated framework",
99 | "icon":"chrome_reader_mode",
100 | "path":"theme-builder",
101 | "_id":"MSOXCaCn4AfNz57w"},
102 | {"type":"services",
103 | "title":"Integration",
104 | "abstract":"Feel free to use your own components, API and data",
105 | "path":"api-data",
106 | "_id":"ueN9BbEdxvKoZWNi"
107 | ,"icon":"compare_arrows"}
108 | ] },
109 | { type: 'array' , name: 'skills' , value : [{name:'CREATIVITY' , value: "90%"} , { name: 'ORGANIZATION' , value: "85%"} , { name: 'TEAM WORK' , value: "75%"} , { name: 'COMMUNICATION' , value: "70%"}]
110 | }
111 | ],
112 | ```
113 |
114 | In case of API **axios** library will be used to fetch data (asyncronously) server side.
115 |
116 | **Data preloading is implemented using `nuxtServerInit` directly from the store.**
117 |
118 | file: ./store/index.js
119 |
120 | ```
121 | ...
122 | async nuxtServerInit({commit}, context ){
123 | //read theme configuration using $theme4nuxt() injected by ./plugins/index.js
124 | let init = context.app.$theme4nuxt().initData
125 | let data = {}
126 | //iterate thru all initial data to be loaded
127 | for ( var n=0 ; n < init.length ; n++ ){
128 | if ( init[n].type === 'api' ) {
129 | let qry = await context.app.$axios.get(init[n].api);
130 | data[init[n].name] = qry.data
131 | }
132 | if ( init[n].type === 'array' ){
133 | data[init[n].name] = init[n].value
134 | }
135 | }
136 | //save data to store
137 | commit ('init_data', data )
138 | if ( !context.app.store.state.theme ){
139 | commit ('theme',context.app.$theme4nuxt() )
140 | }
141 | },
142 | ...
143 | ```
144 |
145 | **Preload theme and injext function to read initData configuration**
146 |
147 | file: ./plugins/index.js
148 |
149 | ```
150 | import theme from '~/themes'
151 |
152 | export default ({ app }, inject) => {
153 | inject('theme4nuxt', () => theme)
154 | }
155 | ```
156 | # The Theme #
157 |
158 | We analyze the current theme that has been used for this website.
159 |
160 | ### navigation Section ###
161 |
162 | The navigation section is required if you want to use the built-in navigation system as showed in the demo. This component create a responsive main navigation icon that open a menu with the options defined.
163 |
164 | The navigation section is also used in the template in order to render a normal navigation menu.
165 | In this version child menus are not supported. If you need this option you can use your component or navigation system.
166 |
167 | ```
168 | ...
169 | navigation : [{
170 | css : "items-start w-full pt-16 px-4 pb-20 bg-black opacity-75 h-screen",
171 | button : "m-1 bg-white p-2 border-black border-2 rounded-full",
172 | line : "hover:text-black hover:bg-white text-grey-lightest" ,
173 | link : 'text-white hover:text-black hover:bg-white hover:text-bold py-10 px-4 no-underline',
174 | left : false,
175 | transition: 'slideright',
176 | orientation: 'horizontal' ,
177 | items: [ { name : 'Home' , path: '/' } , { name: 'Blog' , path: '/blog' } , { name: 'About' , path: '/about' } , { name: 'How to' , path: '/howto' } ]
178 | }],
179 | ...
180 | ```
181 |
182 | ### template Section ###
183 |
184 | The **template** section is the core of the theming system and has 2 main objects
185 | - **main**
186 | - **areas**
187 |
188 |
189 |
190 |
191 | The ***main*** object
192 |
193 | The main object is where is defined the class of the main container and will generate a semantic **<main>** html element.
194 | ```
195 | ...
196 | template: {
197 | main : {
198 | css : "w-full",
199 |
200 | },
201 | ...
202 | ```
203 |
204 |
205 |
206 | The **areas** object
207 |
208 | With the areas object you define all the elements of your template.
209 |
210 | First you can define the order of the area to be rendered as semantic html blocks. Available areas are:
211 | - header
212 | - aside
213 | - content (will be rendered as section)
214 | - footer
215 |
216 | **order is important in order to render elements correctly**
217 |
218 |
219 | ```
220 | ...
221 | template: {
222 | ...
223 | areas: {
224 | order : ['header','content','footer'],
225 | ...
226 | ```
227 |
228 | Our example will create a **header**, a **section** area and a **footer**.
229 |
230 |
231 | ### Creating the header ###
232 |
233 | ```
234 | ...
235 | template: {
236 | ...
237 | areas: {
238 | areas: {
239 | order : ['header','content','footer'],
240 | header : {
241 | root: 'w-full flex flex-wrap',
242 | blocks : [
243 | {
244 | css: 'w-1/2 flex items-center h-12 bg-black text-grey text-xs pl-4 mobile',
245 | elements: [
246 | { type: 'html' , content: '\
247 | theme4nuxt@moodgiver.com\
248 | '}
249 | ]
250 | },
251 | {
252 | css: 'w-1/2 flex items-center justify-end h-12 bg-black text-grey text-xs pr-16 mobile',
253 | elements: [
254 | { type: 'html' , content: '\
255 | +1 123 456 7890\
256 | '}
257 | ]
258 | },
259 | {
260 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 h-24 opacity-75 justify-end flex items-center col bg-black' ,
261 | elements : [
262 | { type: 'html' , content: '
Theme4Nuxt
' , homepage: false }
263 | ],
264 | homepage: false
265 | },
266 | {
267 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 border-l opacity-75 h-24 col z-30 justify-left items-center flex text-right pr-12 col-nav bg-black mobile' ,
268 | elements : [
269 | { type: 'menu' , navigation: 0, homepage: false}
270 | ]
271 | },
272 | {
273 | css: 'w-full bg-green-light h-128 -mt-24 bg-header-8',
274 | elements: [
275 | { type: 'html' , content: ''}
276 | ],
277 | homepage: true
278 | }
279 |
280 | ]
281 | },
282 | ...
283 | ```
284 | In order to create a semantic html **<header>** element we create a header object. Following structure will be used for each defined area.
285 |
286 | For each section (header, aside, content, footer) we have :
287 |
288 | - **root** element container (css)
289 | - **blocks** array of objects
290 |
291 | In our theme we wanted to create:
292 | - a top bar with email and phone ref,
293 | - a header with a logo/title centered,
294 | - a centered menu right to the title
295 | - an image as heading
296 |
297 |
298 |
299 | The top bar block.
300 | ```
301 | ...
302 |
303 | header : {
304 | root: 'w-full flex flex-wrap',
305 | blocks : [
306 | {
307 | css: 'w-1/2 flex items-center h-12 bg-black text-grey text-xs pl-4 mobile',
308 | elements: [
309 | { type: 'html' , content: '\
310 | theme4nuxt@moodgiver.com\
311 | '}
312 | ],
313 | homepage: false
314 | },
315 | {
316 | css: 'w-1/2 flex items-center justify-end h-12 bg-black text-grey text-xs pr-16 mobile',
317 | elements: [
318 | { type: 'html' , content: '\
319 | +1 123 456 7890\
320 | '}
321 | ],
322 | homepage: false
323 | },
324 | ...
325 | }
326 | }
327 | ```
328 |
329 | For each block we have to define
330 |
331 | - **css** : tailwind css classes for the block
332 | - **elements** : array of elements we want to render
333 | - **homepage** : set to true in order to display only in the homepage
334 |
335 | **elements** is an array of object that will be rendered following the order in which they are created.
336 |
337 | ### elements types ##
338 | Each element has the following properties to be set
339 |
340 | - **type**
341 |
342 | the system manage the following types of elements:
343 | - **html**
344 | - **component**
345 | - **menu**
346 | - **css**
347 |
348 |
349 | ### The *html* element ###
350 |
351 | So far for our title we create a css full-width element with other css properties (height, color, items alignment, etc. etc.) as a container.
352 |
353 | Then we created a **html** element type.
354 |
355 | For the **html** element type we must provide the content thru the **content** value. In this case we will assign directly HTML code to inject and render. In this way you can assign css to your html content and it will be rendered correctly.
356 |
357 | ### The *menu* element ###
358 |
359 | In order to render our menu we create a new row (block object) with his proper css.
360 |
361 | In order to render the right menu we have to assign which item in the navigation array we will use. Assign the navigation value representing the posisition in the navigation array (in our case we have only one navigation menu so we assign a value of 0).
362 |
363 | ```
364 | ...
365 |
366 | header : {
367 | root: 'w-full flex flex-wrap',
368 | blocks : [
369 | ...
370 | {
371 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 border-l opacity-75 h-24 col z-30 justify-left items-center flex text-right pr-12 col-nav bg-black mobile' ,
372 | elements : [
373 | { type: 'menu' , navigation: 0, homepage: false}
374 | ],
375 | homepage: false
376 | },
377 | ...
378 | }
379 | ...
380 | ```
381 | ### Creating the content ###
382 |
383 | In order to create the content, that will be rendered as a semantic HTML **<section>** we follow the same structure.
384 |
385 | We will analyze only how to integrate a component in the theme.
386 |
387 | **Component theme integration**
388 |
389 | ```
390 | ...
391 |
392 | content : {
393 |
394 | root: 'w-full flex flex-wrap',
395 | blocks : [
396 | {
397 | css: 'w-full bg-transparent text-grey mx-4 -mt-20 py-6',
398 | elements: [
399 | { type: 'component' , component: 'core/services' , options: { data: 'services' , title: 'Features' } },
400 | ],
401 | homepage: true
402 | },
403 | ...
404 | ]
405 | }
406 | ...
407 | ```
408 |
409 | To load a custom component we have to define as element the following data:
410 | - **type** : "component",
411 | - **component** : the path of our component (if you are using a vue component with a different name from index.vue you need to define ex. /mycomponent/mycomponent.vue will load the mycomponent.vue in the folder mycomponent of the components folder)
412 | - **options** : an object of options that you need to pass to your components (props)
413 |
414 |
415 | Theme4Nuxt loads components dynamically using a component wrapper.
416 |
417 | Theme4Nuxt component wrapper (components/theme/ComponentWrapper.vue)
418 | ```
419 |
420 |