├── .babelrc
├── .editorconfig
├── .env.example
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .nvmrc
├── .postcssrc.js
├── .tern-project
├── README.md
├── _redirects
├── app.json
├── bucket.json
├── build
├── build.js
├── check-versions.js
├── dev-client.js
├── dev-server.js
├── utils.js
├── vue-loader.conf.js
├── webpack.base.conf.js
├── webpack.dev.conf.js
└── webpack.prod.conf.js
├── config
├── dev.env.js
├── index.js
└── prod.env.js
├── index.html
├── netlify.toml
├── package-lock.json
├── package.json
├── server.js
├── src
├── App.vue
├── assets
│ ├── ApplicationHomePage.png
│ ├── add-bucket.png
│ ├── credentials.png
│ ├── deploy-button.svg
│ ├── env.png
│ ├── install_app.png
│ ├── redeploy.png
│ ├── search_apps.png
│ └── vue-snip.svg
├── components
│ ├── Blog.vue
│ ├── BlogFeed.vue
│ ├── BlogFooter.vue
│ ├── BlogNav.vue
│ ├── BlogPost.vue
│ ├── BlogTitle.vue
│ └── index.js
├── config
│ └── index.js
├── helpers.js
├── main.js
├── plugins
│ ├── device-queries
│ │ ├── index.js
│ │ └── match-media.js
│ └── resource
│ │ ├── cache.js
│ │ └── index.js
├── resources
│ ├── Blog.js
│ ├── BlogFeed.js
│ ├── BlogPost.js
│ └── index.js
├── router
│ └── index.js
├── sass
│ ├── _app.scss
│ ├── _tools.scss
│ ├── base
│ │ ├── _body.scss
│ │ ├── _reset.scss
│ │ └── _text.scss
│ ├── blocks
│ │ ├── _blog.scss
│ │ ├── _footer.scss
│ │ ├── _nav.scss
│ │ ├── _pace.scss
│ │ ├── _post.scss
│ │ ├── _preview.scss
│ │ ├── _rte.scss
│ │ └── _v-transitions.scss
│ └── tools
│ │ ├── _colors.scss
│ │ ├── _easings.scss
│ │ ├── _functions.scss
│ │ ├── _mediaqueries.scss
│ │ └── _mixins.scss
└── startup.js
└── static
├── .gitkeep
├── api
├── blog.json
├── feed.json
└── post
│ ├── consequat-ut-nulla.json
│ ├── curabitur-gravida-nisi.json
│ ├── dolor-quis.json
│ ├── lacinia-eget-tincidunt.json
│ ├── neque-libero-convallis-eget.json
│ ├── nunc-commodo-placerat.json
│ ├── posuere-cubilia.json
│ ├── potenti-cras-in-purus.json
│ ├── pretium-nisl.json
│ ├── sapien-ut-nunc.json
│ ├── sit-amet-diam-in.json
│ ├── sit-amet-erat.json
│ ├── ultrices-mattis-odio.json
│ ├── ut-massa-quis-augue.json
│ └── vivamus-tortor-duis-mattis.json
└── icons
├── android-chrome-192x192.png
├── android-chrome-512x512.png
├── apple-touch-icon.png
├── browserconfig.xml
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon.ico
├── manifest.json
├── mstile-150x150.png
└── safari-pinned-tab.svg
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false,
5 | "targets": {
6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
7 | }
8 | }],
9 | "stage-2"
10 | ],
11 | "plugins": ["transform-runtime"],
12 | "env": {
13 | "test": {
14 | "presets": ["env", "stage-2"],
15 | "plugins": ["istanbul"]
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | COSMIC_BUCKET=
2 | COSMIC_READ_KEY=
3 | COSMIC_WRITE_KEY=
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | build/*.js
2 | config/*.js
3 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // http://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parser: 'babel-eslint',
6 | parserOptions: {
7 | sourceType: 'module'
8 | },
9 | env: {
10 | browser: true,
11 | },
12 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
13 | extends: 'standard',
14 | // required to lint *.vue files
15 | plugins: [
16 | 'html'
17 | ],
18 | // add your custom rules here
19 | 'rules': {
20 | // allow paren-less arrow functions
21 | 'arrow-parens': 0,
22 | // allow async-await
23 | 'generator-star-spacing': 0,
24 | // allow debugger during development
25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
26 | // custom
27 | 'space-before-function-paren': 0,
28 | 'object-property-newline': 0,
29 | 'new-cap': 0,
30 | 'no-eval': 0,
31 | 'semi': 0
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | .env
8 |
9 | # Editor directories and files
10 | .idea
11 | .vscode
12 | .tern-project
13 | *.suo
14 | *.ntvs*
15 | *.njsproj
16 | *.sln
17 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v8.11.3
2 |
--------------------------------------------------------------------------------
/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | "postcss-custom-media": {},
6 | // to edit target browsers: use "browserlist" field in package.json
7 | "autoprefixer": {}
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/.tern-project:
--------------------------------------------------------------------------------
1 | {
2 | "ecmaVersion": 6,
3 | "libs": [
4 | "browser"
5 | ],
6 | "loadEagerly": [],
7 | "dontLoad": [
8 | "node_modules/**"
9 | ],
10 | "plugins": {
11 | "doc_comment": true,
12 | "complete_strings": {
13 | "maxLength": 15
14 | },
15 | "node_resolve": {},
16 | "modules": {
17 | "dontLoad": "",
18 | "load": "",
19 | "modules": ""
20 | },
21 | "es_modules": {}
22 | }
23 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Vue.js Blog Template Powered by Cosmic
2 |
3 | A simple Vue.js template for creating a fast, beautiful blog on Netlify powerd by the [Cosmic Headless CMS](https://cosmicjs.com) for content editing.
4 |
5 | This template provides blog, blog posts, authors and elegant modern design ready to deploy on [Netlify](http://netlify.com/) in one click!
6 |
7 | 
8 |
9 | ### [View live demo](https://cosmicjs.com/apps/simple-vue-blog)
10 |
11 | ## Getting Started
12 |
13 | Below are steps to deploy your application to Netlify and integrate with Cosmic for content editing.
14 |
15 | ### 1. Deploy to Netlify
16 |
17 | Click the button below to deploy this application to Netlify. By default, it will be connected to a Bucket with demo content.
18 |
19 | [](https://app.netlify.com/start/deploy?repository=https://github.com/cosmicjs/vue-blog-netlify-template)
20 |
21 | ### 2. Create Cosmic Bucket
22 |
23 | [Install the Simple Vue Blog](https://cosmicjs.com/apps/simple-vue-blog) by clicking `Install Free` on the app page.
24 |
25 | 
26 |
27 | ### 3. Generate Credentials
28 |
29 | Click on `Settings` and then `Basic Settings` in your Bucket dashboard. There you can generate `API Read Access Key` & `API Write Access Key` and save them. This step is optional but recommended for security purposes.
30 |
31 | 
32 |
33 | ### 4. Add Environment Variable - Netlify
34 |
35 | Now go to Netlify Site Settings and then go to the `Build and Deploy` page. Scroll down and you will see `Build environment variables` section where you will enter Cosmic Bucket credentials.
36 |
37 | ```javascript
38 | {
39 | COSMIC_BUCKET: "", /* Default: 'simple-vue-blog' */
40 | COSMIC_READ_KEY: "", /* Default: ' */
41 | COSMIC_WRITE_KEY: "", /* Default: '' */
42 | BLOG_TITLE: "", /* Default: 'Vue Blog Cosmic' */
43 | }
44 | ```
45 |
46 | 
47 |
48 | ### 5. Redeploy
49 |
50 | At last, go to Netlify `Deploys` page and Trigger Deploy. Congratulation, your application is deployed and connected to Cosmic Bucket.
51 |
52 | 
53 |
--------------------------------------------------------------------------------
/_redirects:
--------------------------------------------------------------------------------
1 | # Netlify redirect rules - https://www.netlify.com/docs/redirects/
2 | # SPA setup - redirect all to index
3 | /* /index.html 200
4 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Vue Blog",
3 | "description": "A Vue Blog app using Cosmic JS",
4 | "repository": "https://github.com/cosmicjs/vue-blog-cosmicjs",
5 | "logo": "https://cosmicjs.com/images/logo.svg",
6 | "keywords": ["vue", "blog"]
7 | }
8 |
--------------------------------------------------------------------------------
/bucket.json:
--------------------------------------------------------------------------------
1 | {
2 | "bucket": {
3 | "_id": "5a3cf965339183383f00013a",
4 | "slug": "vue-blog-cosmicjs",
5 | "title": "Vue Blog",
6 | "object_types": [
7 | {
8 | "title": "Authors",
9 | "slug": "authors",
10 | "singular": "Author",
11 | "metafields": [],
12 | "options": {
13 | "slug_field": 1,
14 | "content_editor": 0
15 | },
16 | "preview_link": "",
17 | "priority_locale": null
18 | },
19 | {
20 | "title": "Posts",
21 | "slug": "posts",
22 | "singular": "Post",
23 | "metafields": [
24 | {
25 | "required": true,
26 | "value": "",
27 | "key": "image",
28 | "title": "Image",
29 | "type": "file",
30 | "children": null
31 | },
32 | {
33 | "required": true,
34 | "value": "",
35 | "key": "description",
36 | "title": "Description",
37 | "type": "text",
38 | "children": null
39 | },
40 | {
41 | "object_type": "authors",
42 | "value": "",
43 | "key": "author",
44 | "title": "Author",
45 | "type": "object",
46 | "children": null
47 | }
48 | ],
49 | "options": {
50 | "slug_field": 1,
51 | "content_editor": 1
52 | },
53 | "preview_link": "",
54 | "priority_locale": null,
55 | "localization": false,
56 | "locales": null
57 | }
58 | ],
59 | "objects": [
60 | {
61 | "_id": "5a3cfa0d339183383f000156",
62 | "order": 0,
63 | "slug": "waqas-arshad",
64 | "title": "Waqas Arshad",
65 | "content": "",
66 | "metafields": [],
67 | "bucket": "5a3cf965339183383f00013a",
68 | "type_slug": "authors",
69 | "created_at": "2017-12-22T12:26:53.371Z",
70 | "created_by": "597f4130c4102a386100055c",
71 | "created": "2017-12-22T12:26:53.371Z",
72 | "user_id": "597f4130c4102a386100055c",
73 | "options": {
74 | "content_editor": 0,
75 | "slug_field": 0
76 | },
77 | "status": "published"
78 | },
79 | {
80 | "_id": "5a44e616016e2aed0200017a",
81 | "order": 0,
82 | "slug": "15-brilliant-ways-to-advertise-new-year",
83 | "title": "15 Brilliant Ways To Advertise New Year.",
84 | "content": "
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean in nulla nunc. Duis augue est, rutrum at cursus id, scelerisque nec est. Suspendisse potenti. Vestibulum porttitor erat porttitor libero lacinia rhoncus. Integer fermentum pulvinar ex a ultrices. Cras gravida a velit at blandit. Proin euismod vel nisl sit amet tincidunt. Fusce vitae neque tincidunt, posuere erat rhoncus, mattis sapien. Proin sollicitudin ut mi a efficitur. Phasellus fermentum aliquam ex. Fusce ultricies, odio vel interdum efficitur, neque mi dictum eros, eget elementum nibh mauris eget tellus. Vestibulum interdum felis nec bibendum rutrum. Morbi interdum urna sem, et porttitor sem ullamcorper non.
Donec ac sem mi. Cras viverra est magna, feugiat euismod nibh hendrerit ac. Sed in tempus nunc, sed sodales libero. Morbi aliquet nibh eget nisi pulvinar, eu malesuada urna pulvinar. Quisque laoreet hendrerit libero, vel imperdiet erat rhoncus non. Nullam arcu tortor, pulvinar non lacus eu, molestie faucibus metus. Aliquam tempus felis et enim faucibus, in posuere velit dignissim. Aliquam id tempus justo. Vestibulum fermentum massa vel felis dignissim, vel dignissim sem convallis. Phasellus rhoncus nisi sit amet tristique faucibus. Aenean a arcu quam. Pellentesque sed nunc laoreet, molestie orci dapibus, vehicula mauris. Aliquam nec efficitur lorem, vel varius quam. Aenean risus diam, egestas a luctus ac, rutrum vel elit. Praesent consequat urna augue. Vestibulum euismod, velit id elementum molestie, massa risus semper felis, in lobortis massa eros interdum eros.
Donec vitae pretium nibh, elementum aliquam metus. Suspendisse quis elit volutpat, pulvinar ligula et, posuere lacus. Nullam sit amet risus ac mi varius consectetur. Aliquam lectus mi, semper nec dui ac, semper lacinia velit. Aliquam elementum vestibulum vulputate. Nullam iaculis ipsum et urna iaculis, sed efficitur sapien condimentum. Pellentesque suscipit accumsan arcu, non pretium libero placerat at. Proin non tortor quis sapien sagittis consectetur. Duis nec pellentesque nisl. Aenean mi eros, fermentum sit amet ultrices non, rhoncus sed justo. Proin eu ornare odio. Cras rhoncus sapien ac vulputate imperdiet. Suspendisse interdum purus magna. Praesent euismod quam id massa scelerisque aliquam. Vivamus id libero at tortor porta tincidunt id et risus.
Ut vehicula accumsan erat, ut condimentum libero vulputate nec. Sed id lacus dolor. Vivamus eu lacus vel tortor lobortis euismod. Aenean in venenatis orci. Nunc in nisi et metus gravida porta auctor id nisi. Vestibulum lobortis efficitur enim vel pharetra. Aenean arcu nibh, maximus a elit quis, posuere convallis mi. Donec sed ornare lectus. Etiam porta consectetur congue.
",
85 | "metafields": [
86 | {
87 | "required": true,
88 | "value": "26220930-ebcc-11e7-9942-d12ac3348247-pexels-photo-714703.jpeg",
89 | "key": "image",
90 | "title": "Image",
91 | "type": "file",
92 | "children": null
93 | },
94 | {
95 | "required": true,
96 | "value": "Apathy is the glove into which evil slips its hand.",
97 | "key": "description",
98 | "title": "Description",
99 | "type": "text",
100 | "children": null
101 | },
102 | {
103 | "object_type": "authors",
104 | "value": "5a3cf9fb339183383f000147",
105 | "key": "author",
106 | "title": "Author",
107 | "type": "object",
108 | "children": null
109 | }
110 | ],
111 | "bucket": "5a3cf965339183383f00013a",
112 | "type_slug": "posts",
113 | "created_at": "2017-12-28T12:39:50.867Z",
114 | "created_by": "597f4130c4102a386100055c",
115 | "created": "2017-12-28T12:39:50.867Z",
116 | "user_id": "597f4130c4102a386100055c",
117 | "options": {
118 | "content_editor": 1,
119 | "slug_field": 1
120 | },
121 | "status": "published"
122 | },
123 | {
124 | "_id": "5a3cf9fb339183383f000147",
125 | "order": 1,
126 | "slug": "jazib-sawar",
127 | "title": "Jazib Sawar",
128 | "content": "",
129 | "metafields": [],
130 | "bucket": "5a3cf965339183383f00013a",
131 | "type_slug": "authors",
132 | "created_at": "2017-12-22T12:26:35.402Z",
133 | "created_by": "597f4130c4102a386100055c",
134 | "created": "2017-12-22T12:26:35.402Z",
135 | "user_id": "597f4130c4102a386100055c",
136 | "options": {
137 | "content_editor": 0,
138 | "slug_field": 0
139 | },
140 | "status": "published"
141 | },
142 | {
143 | "_id": "5a44e5b8016e2aed02000175",
144 | "order": 1,
145 | "slug": "the-ultimate-revelation-of-success",
146 | "title": "The Ultimate Revelation Of Success.",
147 | "content": "Donec ac sem mi. Cras viverra est magna, feugiat euismod nibh hendrerit ac. Sed in tempus nunc, sed sodales libero. Morbi aliquet nibh eget nisi pulvinar, eu malesuada urna pulvinar. Quisque laoreet hendrerit libero, vel imperdiet erat rhoncus non. Nullam arcu tortor, pulvinar non lacus eu, molestie faucibus metus. Aliquam tempus felis et enim faucibus, in posuere velit dignissim. Aliquam id tempus justo. Vestibulum fermentum massa vel felis dignissim, vel dignissim sem convallis. Phasellus rhoncus nisi sit amet tristique faucibus. Aenean a arcu quam. Pellentesque sed nunc laoreet, molestie orci dapibus, vehicula mauris. Aliquam nec efficitur lorem, vel varius quam. Aenean risus diam, egestas a luctus ac, rutrum vel elit. Praesent consequat urna augue. Vestibulum euismod, velit id elementum molestie, massa risus semper felis, in lobortis massa eros interdum eros.
Donec vitae pretium nibh, elementum aliquam metus. Suspendisse quis elit volutpat, pulvinar ligula et, posuere lacus. Nullam sit amet risus ac mi varius consectetur. Aliquam lectus mi, semper nec dui ac, semper lacinia velit. Aliquam elementum vestibulum vulputate. Nullam iaculis ipsum et urna iaculis, sed efficitur sapien condimentum. Pellentesque suscipit accumsan arcu, non pretium libero placerat at. Proin non tortor quis sapien sagittis consectetur. Duis nec pellentesque nisl. Aenean mi eros, fermentum sit amet ultrices non, rhoncus sed justo. Proin eu ornare odio. Cras rhoncus sapien ac vulputate imperdiet. Suspendisse interdum purus magna. Praesent euismod quam id massa scelerisque aliquam. Vivamus id libero at tortor porta tincidunt id et risus.
Ut vehicula accumsan erat, ut condimentum libero vulputate nec. Sed id lacus dolor. Vivamus eu lacus vel tortor lobortis euismod. Aenean in venenatis orci. Nunc in nisi et metus gravida porta auctor id nisi. Vestibulum lobortis efficitur enim vel pharetra. Aenean arcu nibh, maximus a elit quis, posuere convallis mi. Donec sed ornare lectus. Etiam porta consectetur congue.
",
148 | "metafields": [
149 | {
150 | "required": true,
151 | "value": "f1597670-ebcb-11e7-9942-d12ac3348247-pexels-photo-747079.jpeg",
152 | "key": "image",
153 | "title": "Image",
154 | "type": "file",
155 | "children": null
156 | },
157 | {
158 | "required": true,
159 | "value": "Men are so constituted that every one undertakes what he sees another successful in, whether he has aptitude for it or not.",
160 | "key": "description",
161 | "title": "Description",
162 | "type": "text",
163 | "children": null
164 | },
165 | {
166 | "object_type": "authors",
167 | "value": "5a3cf9fb339183383f000147",
168 | "key": "author",
169 | "title": "Author",
170 | "type": "object",
171 | "children": null
172 | }
173 | ],
174 | "bucket": "5a3cf965339183383f00013a",
175 | "type_slug": "posts",
176 | "created_at": "2017-12-28T12:38:16.540Z",
177 | "created_by": "597f4130c4102a386100055c",
178 | "created": "2017-12-28T12:38:16.540Z",
179 | "user_id": "597f4130c4102a386100055c",
180 | "options": {
181 | "content_editor": 1,
182 | "slug_field": 1
183 | },
184 | "status": "published"
185 | },
186 | {
187 | "_id": "5a44e57000d6d07e020000f8",
188 | "order": 2,
189 | "slug": "this-is-why-nature-is-so-famous",
190 | "title": "This Is Why Nature Is So Famous!",
191 | "content": "Donec ac sem mi. Cras viverra est magna, feugiat euismod nibh hendrerit ac. Sed in tempus nunc, sed sodales libero. Morbi aliquet nibh eget nisi pulvinar, eu malesuada urna pulvinar. Quisque laoreet hendrerit libero, vel imperdiet erat rhoncus non. Nullam arcu tortor, pulvinar non lacus eu, molestie faucibus metus. Aliquam tempus felis et enim faucibus, in posuere velit dignissim. Aliquam id tempus justo. Vestibulum fermentum massa vel felis dignissim, vel dignissim sem convallis. Phasellus rhoncus nisi sit amet tristique faucibus. Aenean a arcu quam. Pellentesque sed nunc laoreet, molestie orci dapibus, vehicula mauris. Aliquam nec efficitur lorem, vel varius quam. Aenean risus diam, egestas a luctus ac, rutrum vel elit. Praesent consequat urna augue. Vestibulum euismod, velit id elementum molestie, massa risus semper felis, in lobortis massa eros interdum eros.
Donec vitae pretium nibh, elementum aliquam metus. Suspendisse quis elit volutpat, pulvinar ligula et, posuere lacus. Nullam sit amet risus ac mi varius consectetur. Aliquam lectus mi, semper nec dui ac, semper lacinia velit. Aliquam elementum vestibulum vulputate. Nullam iaculis ipsum et urna iaculis, sed efficitur sapien condimentum. Pellentesque suscipit accumsan arcu, non pretium libero placerat at. Proin non tortor quis sapien sagittis consectetur. Duis nec pellentesque nisl. Aenean mi eros, fermentum sit amet ultrices non, rhoncus sed justo. Proin eu ornare odio. Cras rhoncus sapien ac vulputate imperdiet. Suspendisse interdum purus magna. Praesent euismod quam id massa scelerisque aliquam. Vivamus id libero at tortor porta tincidunt id et risus.
",
192 | "metafields": [
193 | {
194 | "required": true,
195 | "value": "c660ca90-ebcb-11e7-a759-f9eda9745d97-pexels-photo-747964.jpeg",
196 | "key": "image",
197 | "title": "Image",
198 | "type": "file",
199 | "children": null
200 | },
201 | {
202 | "required": true,
203 | "value": "That which we do not believe, we cannot adequately say; even though we may repeat the words ever so often.",
204 | "key": "description",
205 | "title": "Description",
206 | "type": "text",
207 | "children": null
208 | },
209 | {
210 | "object_type": "authors",
211 | "value": "5a3cf9fb339183383f000147",
212 | "key": "author",
213 | "title": "Author",
214 | "type": "object",
215 | "children": null
216 | }
217 | ],
218 | "bucket": "5a3cf965339183383f00013a",
219 | "type_slug": "posts",
220 | "created_at": "2017-12-28T12:37:04.704Z",
221 | "created_by": "597f4130c4102a386100055c",
222 | "created": "2017-12-28T12:37:04.705Z",
223 | "user_id": "597f4130c4102a386100055c",
224 | "options": {
225 | "content_editor": 1,
226 | "slug_field": 1
227 | },
228 | "status": "published"
229 | },
230 | {
231 | "_id": "5a44e501016e2aed02000170",
232 | "order": 3,
233 | "slug": "cool-working-environment",
234 | "title": "Cool Working Environment",
235 | "content": "Donec vitae pretium nibh, elementum aliquam metus. Suspendisse quis elit volutpat, pulvinar ligula et, posuere lacus. Nullam sit amet risus ac mi varius consectetur. Aliquam lectus mi, semper nec dui ac, semper lacinia velit. Aliquam elementum vestibulum vulputate. Nullam iaculis ipsum et urna iaculis, sed efficitur sapien condimentum. Pellentesque suscipit accumsan arcu, non pretium libero placerat at. Proin non tortor quis sapien sagittis consectetur. Duis nec pellentesque nisl. Aenean mi eros, fermentum sit amet ultrices non, rhoncus sed justo. Proin eu ornare odio. Cras rhoncus sapien ac vulputate imperdiet. Suspendisse interdum purus magna. Praesent euismod quam id massa scelerisque aliquam. Vivamus id libero at tortor porta tincidunt id et risus.
Ut vehicula accumsan erat, ut condimentum libero vulputate nec. Sed id lacus dolor. Vivamus eu lacus vel tortor lobortis euismod. Aenean in venenatis orci. Nunc in nisi et metus gravida porta auctor id nisi. Vestibulum lobortis efficitur enim vel pharetra. Aenean arcu nibh, maximus a elit quis, posuere convallis mi. Donec sed ornare lectus. Etiam porta consectetur congue.
Aliquam hendrerit nisl non blandit pulvinar. Sed gravida finibus viverra. Aliquam dolor tortor, condimentum sed egestas sit amet, gravida at dui. Cras laoreet ex justo, interdum porta nibh vulputate sit amet. Cras gravida mauris vel vestibulum ultrices. Nulla facilisi. Proin lobortis est bibendum sapien malesuada, in commodo mauris dictum. Curabitur efficitur turpis nunc, semper semper nisl pellentesque in. Mauris ut lorem sed libero tristique elementum varius id urna. Mauris varius viverra suscipit. Suspendisse dictum lorem eget ante tempus lacinia. Nam facilisis fringilla hendrerit. Etiam in ex magna. Quisque eget urna dictum, bibendum metus in, gravida sem.
",
236 | "metafields": [
237 | {
238 | "required": true,
239 | "value": "7f787a60-ebcb-11e7-a759-f9eda9745d97-pexels-photo-748777.jpeg",
240 | "key": "image",
241 | "title": "Image",
242 | "type": "file",
243 | "children": null
244 | },
245 | {
246 | "required": true,
247 | "value": "The critics who love are the severe ones ... we know our relationship must be based on honesty.",
248 | "key": "description",
249 | "title": "Description",
250 | "type": "text",
251 | "children": null
252 | },
253 | {
254 | "object_type": "authors",
255 | "value": "5a3cfa0d339183383f000156",
256 | "key": "author",
257 | "title": "Author",
258 | "type": "object",
259 | "children": null
260 | }
261 | ],
262 | "bucket": "5a3cf965339183383f00013a",
263 | "type_slug": "posts",
264 | "created_at": "2017-12-28T12:35:13.090Z",
265 | "created_by": "597f4130c4102a386100055c",
266 | "created": "2017-12-28T12:35:13.090Z",
267 | "user_id": "597f4130c4102a386100055c",
268 | "options": {
269 | "content_editor": 1,
270 | "slug_field": 1
271 | },
272 | "status": "published",
273 | "modified_at": "2017-12-28T12:52:10.742Z",
274 | "modified_by": "597f4130c4102a386100055c",
275 | "publish_at": null
276 | },
277 | {
278 | "_id": "5a44dd5b00d6d07e020000e2",
279 | "order": 4,
280 | "slug": "heres-what-people-are-saying-about-coding",
281 | "title": "Here's What People Are Saying About Coding",
282 | "content": "Donec vitae pretium nibh, elementum aliquam metus. Suspendisse quis elit volutpat, pulvinar ligula et, posuere lacus. Nullam sit amet risus ac mi varius consectetur. Aliquam lectus mi, semper nec dui ac, semper lacinia velit. Aliquam elementum vestibulum vulputate. Nullam iaculis ipsum et urna iaculis, sed efficitur sapien condimentum. Pellentesque suscipit accumsan arcu, non pretium libero placerat at. Proin non tortor quis sapien sagittis consectetur. Duis nec pellentesque nisl. Aenean mi eros, fermentum sit amet ultrices non, rhoncus sed justo. Proin eu ornare odio. Cras rhoncus sapien ac vulputate imperdiet. Suspendisse interdum purus magna. Praesent euismod quam id massa scelerisque aliquam. Vivamus id libero at tortor porta tincidunt id et risus.
Ut vehicula accumsan erat, ut condimentum libero vulputate nec. Sed id lacus dolor. Vivamus eu lacus vel tortor lobortis euismod. Aenean in venenatis orci. Nunc in nisi et metus gravida porta auctor id nisi. Vestibulum lobortis efficitur enim vel pharetra. Aenean arcu nibh, maximus a elit quis, posuere convallis mi. Donec sed ornare lectus. Etiam porta consectetur congue.
Aliquam hendrerit nisl non blandit pulvinar. Sed gravida finibus viverra. Aliquam dolor tortor, condimentum sed egestas sit amet, gravida at dui. Cras laoreet ex justo, interdum porta nibh vulputate sit amet. Cras gravida mauris vel vestibulum ultrices. Nulla facilisi. Proin lobortis est bibendum sapien malesuada, in commodo mauris dictum. Curabitur efficitur turpis nunc, semper semper nisl pellentesque in. Mauris ut lorem sed libero tristique elementum varius id urna. Mauris varius viverra suscipit. Suspendisse dictum lorem eget ante tempus lacinia. Nam facilisis fringilla hendrerit. Etiam in ex magna. Quisque eget urna dictum, bibendum metus in, gravida sem.
",
283 | "metafields": [
284 | {
285 | "required": true,
286 | "value": "f456a320-ebc6-11e7-84a7-7367c605d42b-pexels-photo-577585.jpeg",
287 | "key": "image",
288 | "title": "Image",
289 | "type": "file",
290 | "children": null
291 | },
292 | {
293 | "required": true,
294 | "value": "The essence of Government is power; and power, lodged as it must be in human hands, will ever be liable to abuse",
295 | "key": "description",
296 | "title": "Description",
297 | "type": "text",
298 | "children": null
299 | },
300 | {
301 | "object_type": "authors",
302 | "value": "5a3cfa0d339183383f000156",
303 | "key": "author",
304 | "title": "Author",
305 | "type": "object",
306 | "children": null
307 | }
308 | ],
309 | "bucket": "5a3cf965339183383f00013a",
310 | "type_slug": "posts",
311 | "created_at": "2017-12-28T12:02:35.262Z",
312 | "created_by": "597f4130c4102a386100055c",
313 | "created": "2017-12-28T12:02:35.262Z",
314 | "user_id": "597f4130c4102a386100055c",
315 | "options": {
316 | "content_editor": 1,
317 | "slug_field": 1
318 | },
319 | "status": "published",
320 | "modified_at": "2017-12-28T12:52:05.616Z",
321 | "modified_by": "597f4130c4102a386100055c",
322 | "publish_at": null
323 | },
324 | {
325 | "_id": "5a44dcf453d863d87f000116",
326 | "order": 5,
327 | "slug": "this-year-will-be-the-year-of-creativity",
328 | "title": "This Year Will Be The Year of Creativity.",
329 | "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean in nulla nunc. Duis augue est, rutrum at cursus id, scelerisque nec est. Suspendisse potenti. Vestibulum porttitor erat porttitor libero lacinia rhoncus. Integer fermentum pulvinar ex a ultrices. Cras gravida a velit at blandit. Proin euismod vel nisl sit amet tincidunt. Fusce vitae neque tincidunt, posuere erat rhoncus, mattis sapien. Proin sollicitudin ut mi a efficitur. Phasellus fermentum aliquam ex. Fusce ultricies, odio vel interdum efficitur, neque mi dictum eros, eget elementum nibh mauris eget tellus. Vestibulum interdum felis nec bibendum rutrum. Morbi interdum urna sem, et porttitor sem ullamcorper non.
Donec ac sem mi. Cras viverra est magna, feugiat euismod nibh hendrerit ac. Sed in tempus nunc, sed sodales libero. Morbi aliquet nibh eget nisi pulvinar, eu malesuada urna pulvinar. Quisque laoreet hendrerit libero, vel imperdiet erat rhoncus non. Nullam arcu tortor, pulvinar non lacus eu, molestie faucibus metus. Aliquam tempus felis et enim faucibus, in posuere velit dignissim. Aliquam id tempus justo. Vestibulum fermentum massa vel felis dignissim, vel dignissim sem convallis. Phasellus rhoncus nisi sit amet tristique faucibus. Aenean a arcu quam. Pellentesque sed nunc laoreet, molestie orci dapibus, vehicula mauris. Aliquam nec efficitur lorem, vel varius quam. Aenean risus diam, egestas a luctus ac, rutrum vel elit. Praesent consequat urna augue. Vestibulum euismod, velit id elementum molestie, massa risus semper felis, in lobortis massa eros interdum eros.
Donec vitae pretium nibh, elementum aliquam metus. Suspendisse quis elit volutpat, pulvinar ligula et, posuere lacus. Nullam sit amet risus ac mi varius consectetur. Aliquam lectus mi, semper nec dui ac, semper lacinia velit. Aliquam elementum vestibulum vulputate. Nullam iaculis ipsum et urna iaculis, sed efficitur sapien condimentum. Pellentesque suscipit accumsan arcu, non pretium libero placerat at. Proin non tortor quis sapien sagittis consectetur. Duis nec pellentesque nisl. Aenean mi eros, fermentum sit amet ultrices non, rhoncus sed justo. Proin eu ornare odio. Cras rhoncus sapien ac vulputate imperdiet. Suspendisse interdum purus magna. Praesent euismod quam id massa scelerisque aliquam. Vivamus id libero at tortor porta tincidunt id et risus.
",
330 | "metafields": [
331 | {
332 | "required": true,
333 | "value": "8457d490-ebc6-11e7-a759-f9eda9745d97-pexels-photo-262297.jpeg",
334 | "key": "image",
335 | "title": "Image",
336 | "type": "file",
337 | "children": null
338 | },
339 | {
340 | "required": true,
341 | "value": "Fortunate indeed, is the man who takes exactely the right measure of himself, and holds a just balance between what he can acquire and what he can use.",
342 | "key": "description",
343 | "title": "Description",
344 | "type": "text",
345 | "children": null
346 | },
347 | {
348 | "object_type": "authors",
349 | "value": "5a3cf9fb339183383f000147",
350 | "key": "author",
351 | "title": "Author",
352 | "type": "object",
353 | "children": null
354 | }
355 | ],
356 | "bucket": "5a3cf965339183383f00013a",
357 | "type_slug": "posts",
358 | "created_at": "2017-12-28T12:00:52.936Z",
359 | "created_by": "597f4130c4102a386100055c",
360 | "created": "2017-12-28T12:00:52.936Z",
361 | "user_id": "597f4130c4102a386100055c",
362 | "options": {
363 | "content_editor": 1,
364 | "slug_field": 1
365 | },
366 | "status": "published"
367 | }
368 | ],
369 | "media": [
370 | {
371 | "_id": "5a3cfa57339183383f00015a",
372 | "name": "90625dd0-e713-11e7-b3b1-5f98a6272afd-mona-eendra.jpg",
373 | "original_name": "mona-eendra.jpg",
374 | "size": 170326,
375 | "type": "image/jpeg",
376 | "bucket": "5a3cf965339183383f00013a",
377 | "created": "2017-12-22T12:28:07.281Z",
378 | "location": "https://s3-us-west-2.amazonaws.com/cosmicjs",
379 | "folder": null
380 | },
381 | {
382 | "_id": "5a44e602016e2aed02000178",
383 | "name": "26220930-ebcc-11e7-9942-d12ac3348247-pexels-photo-714703.jpeg",
384 | "original_name": "pexels-photo-714703.jpeg",
385 | "size": 613936,
386 | "type": "image/jpeg",
387 | "bucket": "5a3cf965339183383f00013a",
388 | "created": "2017-12-28T12:39:30.465Z",
389 | "location": "https://s3-us-west-2.amazonaws.com/cosmicjs",
390 | "folder": null
391 | },
392 | {
393 | "_id": "5a44e5aa016e2aed02000174",
394 | "name": "f1597670-ebcb-11e7-9942-d12ac3348247-pexels-photo-747079.jpeg",
395 | "original_name": "pexels-photo-747079.jpeg",
396 | "size": 1093366,
397 | "type": "image/jpeg",
398 | "bucket": "5a3cf965339183383f00013a",
399 | "created": "2017-12-28T12:38:02.100Z",
400 | "location": "https://s3-us-west-2.amazonaws.com/cosmicjs",
401 | "folder": null
402 | },
403 | {
404 | "_id": "5a44e56100d6d07e020000f7",
405 | "name": "c660ca90-ebcb-11e7-a759-f9eda9745d97-pexels-photo-747964.jpeg",
406 | "original_name": "pexels-photo-747964.jpeg",
407 | "size": 1840090,
408 | "type": "image/jpeg",
409 | "bucket": "5a3cf965339183383f00013a",
410 | "created": "2017-12-28T12:36:49.936Z",
411 | "location": "https://s3-us-west-2.amazonaws.com/cosmicjs",
412 | "folder": null
413 | },
414 | {
415 | "_id": "5a44e4eb00d6d07e020000f6",
416 | "name": "7f787a60-ebcb-11e7-a759-f9eda9745d97-pexels-photo-748777.jpeg",
417 | "original_name": "pexels-photo-748777.jpeg",
418 | "size": 1906525,
419 | "type": "image/jpeg",
420 | "bucket": "5a3cf965339183383f00013a",
421 | "created": "2017-12-28T12:34:51.340Z",
422 | "location": "https://s3-us-west-2.amazonaws.com/cosmicjs",
423 | "folder": null
424 | },
425 | {
426 | "_id": "5a44dd4b53d863d87f000117",
427 | "name": "f456a320-ebc6-11e7-84a7-7367c605d42b-pexels-photo-577585.jpeg",
428 | "original_name": "pexels-photo-577585.jpeg",
429 | "size": 541610,
430 | "type": "image/jpeg",
431 | "bucket": "5a3cf965339183383f00013a",
432 | "created": "2017-12-28T12:02:19.533Z",
433 | "location": "https://s3-us-west-2.amazonaws.com/cosmicjs",
434 | "folder": null
435 | },
436 | {
437 | "_id": "5a44dc8f00d6d07e020000e0",
438 | "name": "8457d490-ebc6-11e7-a759-f9eda9745d97-pexels-photo-262297.jpeg",
439 | "original_name": "pexels-photo-262297.jpeg",
440 | "size": 395558,
441 | "type": "image/jpeg",
442 | "bucket": "5a3cf965339183383f00013a",
443 | "created": "2017-12-28T11:59:11.578Z",
444 | "location": "https://s3-us-west-2.amazonaws.com/cosmicjs",
445 | "folder": null
446 | },
447 | {
448 | "_id": "5a4e25829019dd07240000e2",
449 | "name": "4a1044a0-f14f-11e7-be6f-e3df94a9edf5-1.docx",
450 | "original_name": "1.docx",
451 | "size": 12132,
452 | "type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
453 | "bucket": "5a3cf965339183383f00013a",
454 | "created": "2018-01-04T13:00:50.675Z",
455 | "location": "https://s3-us-west-2.amazonaws.com/cosmicjs",
456 | "folder": null
457 | }
458 | ]
459 | }
460 | }
--------------------------------------------------------------------------------
/build/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | require('./check-versions')()
3 |
4 | process.env.NODE_ENV = 'production'
5 |
6 | const ora = require('ora')
7 | const rm = require('rimraf')
8 | const path = require('path')
9 | const chalk = require('chalk')
10 | const shell = require('shelljs')
11 | const webpack = require('webpack')
12 | const config = require('../config')
13 | const copyFiles = config.build.copyFiles
14 | const assetsRoot = config.build.assetsRoot
15 | const webpackConfig = require('./webpack.prod.conf')
16 |
17 | const spinner = ora('building for production...')
18 | spinner.start()
19 |
20 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
21 | if (err) throw err
22 | webpack(webpackConfig, function (err, stats) {
23 | spinner.stop()
24 | if (err) throw err
25 | process.stdout.write(stats.toString({
26 | colors: true,
27 | modules: false,
28 | children: false,
29 | chunks: false,
30 | chunkModules: false
31 | }) + '\n\n')
32 |
33 | if (stats.hasErrors()) {
34 | console.log(chalk.red(' Build failed with errors.\n'))
35 | process.exit(1)
36 | }
37 |
38 | shell.config.silent = true
39 |
40 | Object.keys(copyFiles)
41 | .forEach(src => shell.cp(
42 | path.resolve(__dirname, src),
43 | path.resolve(assetsRoot, copyFiles[src])
44 | ))
45 |
46 | shell.config.silent = false
47 |
48 | console.log(chalk.cyan(' Build complete.\n'))
49 | console.log(chalk.yellow(
50 | ' Tip: built files are meant to be served over an HTTP server.\n' +
51 | ' Opening index.html over file:// won\'t work.\n'
52 | ))
53 | })
54 | })
55 |
--------------------------------------------------------------------------------
/build/check-versions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const chalk = require('chalk')
3 | const semver = require('semver')
4 | const packageConfig = require('../package.json')
5 | const shell = require('shelljs')
6 | function exec (cmd) {
7 | return require('child_process').execSync(cmd).toString().trim()
8 | }
9 |
10 | const versionRequirements = [
11 | {
12 | name: 'node',
13 | currentVersion: semver.clean(process.version),
14 | versionRequirement: packageConfig.engines.node
15 | }
16 | ]
17 |
18 | if (shell.which('npm')) {
19 | versionRequirements.push({
20 | name: 'npm',
21 | currentVersion: exec('npm --version'),
22 | versionRequirement: packageConfig.engines.npm
23 | })
24 | }
25 |
26 | module.exports = function () {
27 | const warnings = []
28 | for (let i = 0; i < versionRequirements.length; i++) {
29 | const mod = versionRequirements[i]
30 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
31 | warnings.push(mod.name + ': ' +
32 | chalk.red(mod.currentVersion) + ' should be ' +
33 | chalk.green(mod.versionRequirement)
34 | )
35 | }
36 | }
37 |
38 | if (warnings.length) {
39 | console.log('')
40 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
41 | console.log()
42 | for (let i = 0; i < warnings.length; i++) {
43 | const warning = warnings[i]
44 | console.log(' ' + warning)
45 | }
46 | console.log()
47 | process.exit(1)
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/build/dev-client.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | 'use strict'
3 | require('eventsource-polyfill')
4 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
5 |
6 | hotClient.subscribe(function (event) {
7 | if (event.action === 'reload') {
8 | window.location.reload()
9 | }
10 | })
11 |
--------------------------------------------------------------------------------
/build/dev-server.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | require('./check-versions')()
3 |
4 | const config = require('../config')
5 | if (!process.env.NODE_ENV) {
6 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
7 | }
8 |
9 | const opn = require('opn')
10 | const path = require('path')
11 | const express = require('express')
12 | const webpack = require('webpack')
13 | const proxyMiddleware = require('http-proxy-middleware')
14 | const webpackConfig = require('./webpack.dev.conf')
15 |
16 | // default port where dev server listens for incoming traffic
17 | const port = process.env.PORT || config.dev.port
18 | // automatically open browser, if not set will be false
19 | const autoOpenBrowser = !!config.dev.autoOpenBrowser
20 | // Define HTTP proxies to your custom API backend
21 | // https://github.com/chimurai/http-proxy-middleware
22 | const proxyTable = config.dev.proxyTable
23 |
24 | const app = express()
25 | const compiler = webpack(webpackConfig)
26 |
27 | const devMiddleware = require('webpack-dev-middleware')(compiler, {
28 | publicPath: webpackConfig.output.publicPath,
29 | quiet: true
30 | })
31 |
32 | const hotMiddleware = require('webpack-hot-middleware')(compiler, {
33 | log: false,
34 | heartbeat: 2000
35 | })
36 | // force page reload when html-webpack-plugin template changes
37 | // currently disabled until this is resolved:
38 | // https://github.com/jantimon/html-webpack-plugin/issues/680
39 | // compiler.plugin('compilation', function (compilation) {
40 | // compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
41 | // hotMiddleware.publish({ action: 'reload' })
42 | // cb()
43 | // })
44 | // })
45 |
46 | // enable hot-reload and state-preserving
47 | // compilation error display
48 | app.use(hotMiddleware)
49 |
50 | // proxy api requests
51 | Object.keys(proxyTable).forEach(function (context) {
52 | let options = proxyTable[context]
53 | if (typeof options === 'string') {
54 | options = { target: options }
55 | }
56 | app.use(proxyMiddleware(options.filter || context, options))
57 | })
58 |
59 | // handle fallback for HTML5 history API
60 | app.use(require('connect-history-api-fallback')())
61 |
62 | // serve webpack bundle output
63 | app.use(devMiddleware)
64 |
65 | // serve pure static assets
66 | const staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
67 | app.use(staticPath, express.static('./static'))
68 |
69 | const uri = 'http://localhost:' + port
70 |
71 | var _resolve
72 | var _reject
73 | var readyPromise = new Promise((resolve, reject) => {
74 | _resolve = resolve
75 | _reject = reject
76 | })
77 |
78 | var server
79 | var portfinder = require('portfinder')
80 | portfinder.basePort = port
81 |
82 | console.log('> Starting dev server...')
83 | devMiddleware.waitUntilValid(() => {
84 | portfinder.getPort((err, port) => {
85 | if (err) {
86 | _reject(err)
87 | }
88 | process.env.PORT = port
89 | var uri = 'http://localhost:' + port
90 | console.log('> Listening at ' + uri + '\n')
91 | // when env is testing, don't need open it
92 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
93 | opn(uri)
94 | }
95 | server = app.listen(port)
96 | _resolve()
97 | })
98 | })
99 |
100 | module.exports = {
101 | ready: readyPromise,
102 | close: () => {
103 | server.close()
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/build/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const config = require('../config')
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
5 |
6 | exports.assetsPath = function (_path) {
7 | const assetsSubDirectory = process.env.NODE_ENV === 'production'
8 | ? config.build.assetsSubDirectory
9 | : config.dev.assetsSubDirectory
10 | return path.posix.join(assetsSubDirectory, _path)
11 | }
12 |
13 | exports.cssLoaders = function (options) {
14 | options = options || {}
15 |
16 | const cssLoader = {
17 | loader: 'css-loader',
18 | options: {
19 | minimize: process.env.NODE_ENV === 'production',
20 | sourceMap: options.sourceMap
21 | }
22 | }
23 |
24 | // generate loader string to be used with extract text plugin
25 | function generateLoaders (loader, loaderOptions) {
26 | const loaders = [cssLoader]
27 | if (loader) {
28 | loaders.push({
29 | loader: loader + '-loader',
30 | options: Object.assign({}, loaderOptions, {
31 | sourceMap: options.sourceMap
32 | })
33 | })
34 | }
35 |
36 | // Extract CSS when that option is specified
37 | // (which is the case during production build)
38 | if (options.extract) {
39 | return ExtractTextPlugin.extract({
40 | use: loaders,
41 | fallback: 'vue-style-loader'
42 | })
43 | } else {
44 | return ['vue-style-loader'].concat(loaders)
45 | }
46 | }
47 |
48 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
49 | return {
50 | css: generateLoaders(),
51 | postcss: generateLoaders(),
52 | less: generateLoaders('less'),
53 | sass: generateLoaders('sass', { indentedSyntax: true }),
54 | scss: generateLoaders('sass'),
55 | stylus: generateLoaders('stylus'),
56 | styl: generateLoaders('stylus')
57 | }
58 | }
59 |
60 | // Generate loaders for standalone style files (outside of .vue)
61 | exports.styleLoaders = function (options) {
62 | const output = []
63 | const loaders = exports.cssLoaders(options)
64 | for (const extension in loaders) {
65 | const loader = loaders[extension]
66 | output.push({
67 | test: new RegExp('\\.' + extension + '$'),
68 | use: loader
69 | })
70 | }
71 | return output
72 | }
73 |
--------------------------------------------------------------------------------
/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const config = require('../config')
4 | const isProduction = process.env.NODE_ENV === 'production'
5 |
6 | module.exports = {
7 | loaders: utils.cssLoaders({
8 | sourceMap: isProduction
9 | ? config.build.productionSourceMap
10 | : config.dev.cssSourceMap,
11 | extract: isProduction
12 | }),
13 | transformToRequire: {
14 | video: 'src',
15 | source: 'src',
16 | img: 'src',
17 | image: 'xlink:href'
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const config = require('../config')
5 | const vueLoaderConfig = require('./vue-loader.conf')
6 |
7 | function resolve (dir) {
8 | return path.join(__dirname, '..', dir)
9 | }
10 |
11 | module.exports = {
12 | entry: {
13 | app: './src/main.js'
14 | },
15 | output: {
16 | path: config.build.assetsRoot,
17 | filename: '[name].js',
18 | publicPath: process.env.NODE_ENV === 'production'
19 | ? config.build.assetsPublicPath
20 | : config.dev.assetsPublicPath
21 | },
22 | resolve: {
23 | extensions: ['.js', '.vue', '.json'],
24 | alias: {
25 | 'vue$': 'vue/dist/vue.esm.js',
26 | '@': resolve('src'),
27 | }
28 | },
29 | module: {
30 | rules: [
31 | {
32 | test: /\.(js|vue)$/,
33 | loader: 'eslint-loader',
34 | enforce: 'pre',
35 | include: [resolve('src'), resolve('test')],
36 | options: {
37 | formatter: require('eslint-friendly-formatter')
38 | }
39 | },
40 | {
41 | test: /\.vue$/,
42 | loader: 'vue-loader',
43 | options: vueLoaderConfig
44 | },
45 | {
46 | test: /\.js$/,
47 | loader: 'babel-loader',
48 | include: [resolve('src'), resolve('test')]
49 | },
50 | {
51 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
52 | loader: 'url-loader',
53 | options: {
54 | limit: 10000,
55 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
56 | }
57 | },
58 | {
59 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
60 | loader: 'url-loader',
61 | options: {
62 | limit: 10000,
63 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
64 | }
65 | },
66 | {
67 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
68 | loader: 'url-loader',
69 | options: {
70 | limit: 10000,
71 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
72 | }
73 | }
74 | ]
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const webpack = require('webpack')
4 | const config = require('../config')
5 | const merge = require('webpack-merge')
6 | const baseWebpackConfig = require('./webpack.base.conf')
7 | const HtmlWebpackPlugin = require('html-webpack-plugin')
8 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
9 |
10 | // add hot-reload related code to entry chunks
11 | Object.keys(baseWebpackConfig.entry).forEach(function (name) {
12 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
13 | })
14 |
15 | module.exports = merge(baseWebpackConfig, {
16 | module: {
17 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
18 | },
19 | // cheap-module-eval-source-map is faster for development
20 | devtool: '#cheap-module-eval-source-map',
21 | plugins: [
22 | new webpack.DefinePlugin({
23 | 'process.env': config.dev.env
24 | }),
25 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
26 | new webpack.HotModuleReplacementPlugin(),
27 | new webpack.NoEmitOnErrorsPlugin(),
28 | // https://github.com/ampedandwired/html-webpack-plugin
29 | new HtmlWebpackPlugin({
30 | filename: 'index.html',
31 | template: 'index.html',
32 | inject: true
33 | }),
34 | new FriendlyErrorsPlugin()
35 | ]
36 | })
37 |
--------------------------------------------------------------------------------
/build/webpack.prod.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const webpack = require('webpack')
5 | const config = require('../config')
6 | const merge = require('webpack-merge')
7 | const baseWebpackConfig = require('./webpack.base.conf')
8 | const CopyWebpackPlugin = require('copy-webpack-plugin')
9 | const HtmlWebpackPlugin = require('html-webpack-plugin')
10 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
12 |
13 | const env = config.build.env
14 |
15 | const webpackConfig = merge(baseWebpackConfig, {
16 | module: {
17 | rules: utils.styleLoaders({
18 | sourceMap: config.build.productionSourceMap,
19 | extract: true
20 | })
21 | },
22 | devtool: config.build.productionSourceMap ? '#source-map' : false,
23 | output: {
24 | path: config.build.assetsRoot,
25 | filename: utils.assetsPath('js/[name].[chunkhash].js'),
26 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
27 | },
28 | plugins: [
29 | // http://vuejs.github.io/vue-loader/en/workflow/production.html
30 | new webpack.DefinePlugin({
31 | 'process.env': env
32 | }),
33 | // UglifyJs do not support ES6+, you can also use babel-minify for better treeshaking: https://github.com/babel/minify
34 | new webpack.optimize.UglifyJsPlugin({
35 | compress: {
36 | warnings: false
37 | },
38 | sourceMap: true
39 | }),
40 | // extract css into its own file
41 | new ExtractTextPlugin({
42 | filename: utils.assetsPath('css/[name].[contenthash].css')
43 | }),
44 | // Compress extracted CSS. We are using this plugin so that possible
45 | // duplicated CSS from different components can be deduped.
46 | new OptimizeCSSPlugin({
47 | cssProcessorOptions: {
48 | safe: true
49 | }
50 | }),
51 | // generate dist index.html with correct asset hash for caching.
52 | // you can customize output by editing /index.html
53 | // see https://github.com/ampedandwired/html-webpack-plugin
54 | new HtmlWebpackPlugin({
55 | filename: config.build.index,
56 | template: 'index.html',
57 | inject: true,
58 | minify: {
59 | removeComments: true,
60 | collapseWhitespace: true,
61 | removeAttributeQuotes: true
62 | // more options:
63 | // https://github.com/kangax/html-minifier#options-quick-reference
64 | },
65 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin
66 | chunksSortMode: 'dependency'
67 | }),
68 | // keep module.id stable when vender modules does not change
69 | new webpack.HashedModuleIdsPlugin(),
70 | // split vendor js into its own file
71 | new webpack.optimize.CommonsChunkPlugin({
72 | name: 'vendor',
73 | minChunks: function (module) {
74 | // any required modules inside node_modules are extracted to vendor
75 | return (
76 | module.resource &&
77 | /\.js$/.test(module.resource) &&
78 | module.resource.indexOf(
79 | path.join(__dirname, '../node_modules')
80 | ) === 0
81 | )
82 | }
83 | }),
84 | // extract webpack runtime and module manifest to its own file in order to
85 | // prevent vendor hash from being updated whenever app bundle is updated
86 | new webpack.optimize.CommonsChunkPlugin({
87 | name: 'manifest',
88 | chunks: ['vendor']
89 | }),
90 | // copy custom static assets
91 | new CopyWebpackPlugin([
92 | {
93 | from: path.resolve(__dirname, '../static'),
94 | to: config.build.assetsSubDirectory,
95 | ignore: ['.*']
96 | }
97 | ])
98 | ]
99 | })
100 |
101 | if (config.build.productionGzip) {
102 | const CompressionWebpackPlugin = require('compression-webpack-plugin')
103 |
104 | webpackConfig.plugins.push(
105 | new CompressionWebpackPlugin({
106 | asset: '[path].gz[query]',
107 | algorithm: 'gzip',
108 | test: new RegExp(
109 | '\\.(' +
110 | config.build.productionGzipExtensions.join('|') +
111 | ')$'
112 | ),
113 | threshold: 10240,
114 | minRatio: 0.8
115 | })
116 | )
117 | }
118 |
119 | if (config.build.bundleAnalyzerReport) {
120 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
121 | webpackConfig.plugins.push(new BundleAnalyzerPlugin())
122 | }
123 |
124 | module.exports = webpackConfig
125 |
--------------------------------------------------------------------------------
/config/dev.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const merge = require('webpack-merge')
3 | const prodEnv = require('./prod.env')
4 |
5 | module.exports = merge(prodEnv, {
6 | NODE_ENV: '"development"'
7 | })
8 |
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 |
2 | 'use strict'
3 | // Template version: 1.1.3
4 | // see http://vuejs-templates.github.io/webpack for documentation.
5 |
6 | const path = require('path')
7 | require('dotenv').config()
8 |
9 | module.exports = {
10 | build: {
11 | env: require('./prod.env'),
12 | index: path.resolve(__dirname, '../dist/index.html'),
13 | assetsRoot: path.resolve(__dirname, '../dist'),
14 | assetsSubDirectory: 'static',
15 | assetsPublicPath: '/',
16 | productionSourceMap: true,
17 | copyFiles: { '../_redirects': './' },
18 | // Gzip off by default as many popular static hosts such as
19 | // Surge or Netlify already gzip all static assets for you.
20 | // Before setting to `true`, make sure to:
21 | // npm install --save-dev compression-webpack-plugin
22 | productionGzip: false,
23 | productionGzipExtensions: ['js', 'css'],
24 | // Run the build command with an extra argument to
25 | // View the bundle analyzer report after build finishes:
26 | // `npm run build --report`
27 | // Set to `true` or `false` to always turn it on or off
28 | bundleAnalyzerReport: process.env.npm_config_report
29 | },
30 | dev: {
31 | env: require('./dev.env'),
32 | port: process.env.PORT || 8080,
33 | autoOpenBrowser: true,
34 | assetsSubDirectory: 'static',
35 | assetsPublicPath: '/',
36 | proxyTable: {},
37 | // CSS Sourcemaps off by default because relative paths are "buggy"
38 | // with this option, according to the CSS-Loader README
39 | // (https://github.com/webpack/css-loader#sourcemaps)
40 | // In our experience, they generally work as expected,
41 | // just be aware of this issue when enabling this option.
42 | cssSourceMap: false
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/config/prod.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | module.exports = {
3 | NODE_ENV: '"production"',
4 | COSMIC_BUCKET: `"${process.env.COSMIC_BUCKET || 'simple-vue-blog'}"`,
5 | COSMIC_READ_KEY: `"${process.env.COSMIC_READ_KEY}"`,
6 | COSMIC_WRITE_KEY: `"${process.env.COSMIC_WRITE_KEY}"`,
7 | BLOG_TITLE: `"${process.env.BLOG_TITLE || 'Vue Blog Cosmic JS'}"`,
8 | }
9 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vue Blog Cosmic JS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | command = "npm run build"
3 | publish = "dist"
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-blog-cosmicjs",
3 | "version": "1.0.1",
4 | "description": "A simple blog app built using Vue & Vuex. It connects to the Cosmic JS CMS via API. You can manage your content from your Cosmic JS Dashboard.",
5 | "author": "Jazib Sawar ",
6 | "private": true,
7 | "scripts": {
8 | "dev": "node build/dev-server.js",
9 | "start": "node server.js",
10 | "build": "node build/build.js",
11 | "heroku-postbuild": "npm run build",
12 | "lint": "eslint --ext .js,.vue src"
13 | },
14 | "dependencies": {
15 | "capitalize": "^1.0.0",
16 | "connect-history-api-fallback": "^1.5.0",
17 | "express": "^4.16.2",
18 | "lodash.map": "^4.6.0",
19 | "lodash.merge": "^4.6.0",
20 | "scrollto-with-animation": "^4.5.2",
21 | "vue": "^2.5.2",
22 | "vue-disqus": "^2.0.3",
23 | "vue-router": "^3.0.1",
24 | "autoprefixer": "^7.1.2",
25 | "babel-core": "^6.22.1",
26 | "babel-eslint": "^7.1.1",
27 | "babel-loader": "^7.1.1",
28 | "babel-plugin-transform-runtime": "^6.22.0",
29 | "babel-polyfill": "^6.23.0",
30 | "babel-preset-env": "^1.3.2",
31 | "babel-preset-stage-2": "^6.22.0",
32 | "babel-register": "^6.22.0",
33 | "chalk": "^2.0.1",
34 | "copy-webpack-plugin": "^4.0.1",
35 | "css-loader": "^0.28.0",
36 | "dotenv": "^4.0.0",
37 | "eslint": "^3.19.0",
38 | "eslint-config-standard": "^10.2.1",
39 | "eslint-friendly-formatter": "^3.0.0",
40 | "eslint-loader": "^1.7.1",
41 | "eslint-plugin-html": "^3.0.0",
42 | "eslint-plugin-import": "^2.7.0",
43 | "eslint-plugin-node": "^5.2.0",
44 | "eslint-plugin-promise": "^3.4.0",
45 | "eslint-plugin-standard": "^3.0.1",
46 | "eventsource-polyfill": "^0.9.6",
47 | "extract-text-webpack-plugin": "^3.0.0",
48 | "file-loader": "^1.1.4",
49 | "friendly-errors-webpack-plugin": "^1.6.1",
50 | "html-webpack-plugin": "^2.30.1",
51 | "http-proxy-middleware": "^0.17.3",
52 | "node-sass": "4.9.0",
53 | "opn": "^5.1.0",
54 | "optimize-css-assets-webpack-plugin": "^3.2.0",
55 | "ora": "^1.2.0",
56 | "pace": "0.0.4",
57 | "pace-progress": "^1.0.2",
58 | "portfinder": "^1.0.13",
59 | "postcss-custom-media": "^6.0.0",
60 | "rimraf": "^2.6.0",
61 | "sass-loader": "^6.0.6",
62 | "semver": "^5.3.0",
63 | "shelljs": "^0.7.6",
64 | "url-loader": "^0.5.8",
65 | "vue-loader": "^13.3.0",
66 | "vue-style-loader": "^3.0.1",
67 | "vue-template-compiler": "^2.5.2",
68 | "webpack": "^3.6.0",
69 | "webpack-bundle-analyzer": "^2.9.0",
70 | "webpack-dev-middleware": "^1.12.0",
71 | "webpack-hot-middleware": "^2.18.2",
72 | "webpack-merge": "^4.1.0"
73 | },
74 | "engines": {
75 | "node": ">= 8.11.3",
76 | "npm": ">= 5.0.0"
77 | },
78 | "browserslist": [
79 | "last 2 versions",
80 | "not ie <= 9"
81 | ]
82 | }
83 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const path = require('path');
3 | const serveStatic = require('serve-static');
4 | const history = require('connect-history-api-fallback');
5 |
6 | app = express();
7 | app.use(history());
8 | app.use(serveStatic(__dirname + "/dist"));
9 |
10 | const port = process.env.PORT || 5000;
11 |
12 | app.listen(port);
13 |
14 | console.log(`Server started on port ${port}`);
15 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/src/assets/ApplicationHomePage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/src/assets/ApplicationHomePage.png
--------------------------------------------------------------------------------
/src/assets/add-bucket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/src/assets/add-bucket.png
--------------------------------------------------------------------------------
/src/assets/credentials.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/src/assets/credentials.png
--------------------------------------------------------------------------------
/src/assets/deploy-button.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/assets/env.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/src/assets/env.png
--------------------------------------------------------------------------------
/src/assets/install_app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/src/assets/install_app.png
--------------------------------------------------------------------------------
/src/assets/redeploy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/src/assets/redeploy.png
--------------------------------------------------------------------------------
/src/assets/search_apps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/src/assets/search_apps.png
--------------------------------------------------------------------------------
/src/assets/vue-snip.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/Blog.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
63 |
--------------------------------------------------------------------------------
/src/components/BlogFeed.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 | {{ post.title }}
11 |
12 |
13 |
14 |
15 | {{ prettyDate(post.published) }}
16 |
17 |
18 |
21 | {{ post.author }}
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
109 |
--------------------------------------------------------------------------------
/src/components/BlogFooter.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
14 |
--------------------------------------------------------------------------------
/src/components/BlogNav.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ content.title }}
5 |
6 |
7 |
13 |
14 |
15 |
16 |
43 |
--------------------------------------------------------------------------------
/src/components/BlogPost.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
16 |
17 |
18 |
22 |
23 |
24 |
25 |
26 |
74 |
--------------------------------------------------------------------------------
/src/components/BlogTitle.vue:
--------------------------------------------------------------------------------
1 |
52 |
--------------------------------------------------------------------------------
/src/components/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './Blog'
2 |
--------------------------------------------------------------------------------
/src/config/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | COSMIC_BUCKET: process.env.COSMIC_BUCKET,
3 | COSMIC_READ_KEY: process.env.COSMIC_READ_KEY,
4 | COSMIC_WRITE_KEY: process.env.COSMIC_WRITE_KEY,
5 | BLOG_TITLE: process.env.BLOG_TITLE
6 | }
7 |
--------------------------------------------------------------------------------
/src/helpers.js:
--------------------------------------------------------------------------------
1 | import animateScroll from 'scrollto-with-animation'
2 | import capitalize from 'capitalize'
3 |
4 | export const scrollTo = (pos, duration = 600, delay = 0) => new Promise(resolve => {
5 | setTimeout(() => {
6 | animateScroll(document.documentElement, 'scrollTop', pos, duration, 'easeInOutSine', resolve)
7 | }, delay)
8 | })
9 |
10 | export const kebabify = (words) =>
11 | words
12 | .toLowerCase()
13 | .replace(' ', '-')
14 |
15 | export const unkebabify = (str) => capitalize.words(str.replace(/-/g, ' '))
16 |
17 | export const prettyDate = (date) =>
18 | new Date(date)
19 | .toString()
20 | .split(' ')
21 | .slice(0, 4)
22 | .join(' ')
23 | .replace(/( \d+)$/, ',$1')
24 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import './startup'
2 |
3 | import Vue from 'vue'
4 | import App from './App'
5 | import router from './router'
6 | import * as resources from './resources'
7 | import resource from './plugins/resource'
8 | import deviceQueries from './plugins/device-queries'
9 | import config from './config'
10 |
11 | Vue.config.productionTip = false
12 |
13 | Vue.use(resource, {
14 | resources,
15 | endpoint: 'https://api.cosmicjs.com/v1/' + config.COSMIC_BUCKET
16 | })
17 |
18 | Vue.use(deviceQueries, {
19 | phone: 'max-width: 567px',
20 | tablet: 'min-width: 568px',
21 | mobile: 'max-width: 1024px',
22 | laptop: 'min-width: 1025px',
23 | desktop: 'min-width: 1280px',
24 | monitor: 'min-width: 1448px'
25 | })
26 |
27 | new Vue({
28 | router,
29 | render: h => h(App)
30 | }).$mount('#app')
31 |
--------------------------------------------------------------------------------
/src/plugins/device-queries/index.js:
--------------------------------------------------------------------------------
1 | import matchMedia from './match-media'
2 |
3 | export default {
4 | install(Vue, queries) {
5 | const DeviceVM = new Vue({
6 | data() {
7 | return {
8 | devices: {}
9 | }
10 | },
11 |
12 | methods: {
13 | addDevice(name, active) {
14 | this.$set(this.devices, name, active)
15 |
16 | return ({ matches }) => {
17 | this.devices[name] = matches
18 | }
19 | }
20 | }
21 | })
22 |
23 | Object.keys(queries).forEach(name => {
24 | let query = matchMedia(`(${queries[name]})`)
25 | let update = DeviceVM.addDevice(name, query.matches)
26 | query.addListener(update)
27 | })
28 |
29 | Vue.prototype.$device = DeviceVM.devices
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/plugins/device-queries/match-media.js:
--------------------------------------------------------------------------------
1 | const matchMediaFallback = () => {
2 | let listeners = []
3 | let idle = true
4 |
5 | const device = (() => {
6 | let node = document.createElement('div')
7 | let style = document.createElement('style')
8 |
9 | node.id = 'match-media-node'
10 | style.innerHTML = `#match-media-node {
11 | width: 100%;
12 | height: 100%;
13 | position: absolute;
14 | bottom: 100%;
15 | overflow: scroll;
16 | }`
17 |
18 | document.head.appendChild(style)
19 | document.body.insertBefore(node, document.body.children[0])
20 |
21 | return {
22 | get width() {
23 | return node.clientWidth
24 | },
25 | get height() {
26 | return node.clientHeight
27 | },
28 | get orientation() {
29 | return (node.clientHeight > node.clientWidth)
30 | ? 'portrait'
31 | : 'landscape'
32 | },
33 | get fontSize() {
34 | return window
35 | .getComputedStyle(document.documentElement)
36 | .getPropertyValue('font-size')
37 | }
38 | }
39 | })()
40 |
41 | const createHandler = (feature, value) => {
42 | if (feature === 'orientation') {
43 | return () => value === device.orientation
44 | }
45 |
46 | let [prop, limit] = feature
47 | .split('-')
48 | .reverse()
49 |
50 | const operand = (!limit) ? '=='
51 | : (limit === 'min') ? '<'
52 | : '>'
53 |
54 | const parseValue = (() => {
55 | return (~value.indexOf('em'))
56 | ? () => parseFloat(value) * device.fontSize
57 | : () => parseFloat(value)
58 | })()
59 |
60 | const handlers = {
61 | 'width': () => eval(parseValue() + operand + device.width),
62 | 'height': () => eval(parseValue() + operand + device.height)
63 | }
64 |
65 | return handlers[prop]
66 | }
67 |
68 | const parseQuery = (queryString) => {
69 | let [feature, value] = queryString.replace(/[()\s]/g, '').split(':')
70 | return createHandler(feature, value)
71 | }
72 |
73 | window.addEventListener('resize', () => {
74 | if (!idle) return;
75 | idle = false
76 |
77 | let width = device.width
78 | let height = device.height
79 |
80 | let timer = setInterval(() => {
81 | if (width !== device.width || height !== device.height) {
82 | width = device.width
83 | height = device.height
84 | } else {
85 | clearTimeout(timer)
86 | listeners.forEach(handler => handler())
87 | idle = true
88 | }
89 | }, 100)
90 | })
91 |
92 | return (queryString) => {
93 | const query = parseQuery(queryString)
94 | const matcher = {
95 | get matches() {
96 | return query()
97 | }
98 | }
99 |
100 | return {
101 | ...matcher,
102 | addListener(cb) {
103 | const handler = () => cb(matcher)
104 | listeners.push(handler)
105 | }
106 | }
107 | }
108 | }
109 |
110 | const matchMedia = window.matchMedia || matchMediaFallback()
111 |
112 | export { matchMedia as default }
113 |
--------------------------------------------------------------------------------
/src/plugins/resource/cache.js:
--------------------------------------------------------------------------------
1 | export default (() => {
2 | let store = {}
3 |
4 | return {
5 | has: uri => !!store[uri],
6 | get: uri => JSON.parse(store[uri]),
7 | set: (uri, data) => {
8 | store[uri] = JSON.stringify(data)
9 | return Promise.resolve(data)
10 | }
11 | }
12 | })()
13 |
--------------------------------------------------------------------------------
/src/plugins/resource/index.js:
--------------------------------------------------------------------------------
1 | import cache from './cache'
2 | import _merge from 'lodash.merge'
3 | import config from '../../config'
4 |
5 | // install $resource as a Vue plugin
6 | export default {
7 | install(Vue, { endpoint = '', resources = {} }) {
8 | Vue.prototype.$getResource = function(method, options) {
9 | let name = this.$options.resource
10 | if (!name || !resources[name] || !resources[name][method]) return;
11 |
12 | // get fetch path and response resolver/mapper
13 | let { path, resolve } = resources[name][method](options)
14 | let uri = '';
15 | if (method === 'blog') {
16 | uri = '/static/api' + path
17 | } else {
18 | uri = endpoint + path + '?hide_metafields=true&read_key=' + config.COSMIC_READ_KEY
19 | }
20 |
21 | // methods return promise to allow chaining
22 | const mappers = {
23 | // only return promise without modifying instance $data
24 | pipe: dataSet => Promise.resolve(dataSet),
25 |
26 | // deep merge object with instance $data
27 | merge: dataSet => {
28 | _merge(this.$data, dataSet)
29 | return Promise.resolve(dataSet)
30 | },
31 |
32 | // set individual props on instance $data
33 | set: dataSet => {
34 | Object.keys(dataSet).forEach(prop => {
35 | this.$set(this.$data, prop, dataSet[prop])
36 | })
37 |
38 | return Promise.resolve(dataSet)
39 | }
40 | }
41 |
42 | // check to see if the resource has been cached already
43 | if (cache.has(uri)) return resolve(cache.get(uri), mappers)
44 |
45 | // fetch, parse and cache resource then pass to resolver
46 | return fetch(uri)
47 | .then(response => response.json())
48 | .then(response => cache.set(uri, response))
49 | .then(response => resolve(response, mappers))
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/resources/Blog.js:
--------------------------------------------------------------------------------
1 | import config from '../config'
2 |
3 | export default {
4 | blog() {
5 | return {
6 | path: '/blog.json',
7 | resolve: (response, mappers) => {
8 | let blog = response.results[0]
9 | return mappers.merge({
10 | title: config.BLOG_TITLE || blog.title,
11 | labels: {
12 | post: blog.post_label,
13 | author: blog.author_label
14 | }
15 | })
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/resources/BlogFeed.js:
--------------------------------------------------------------------------------
1 | import _map from 'lodash.map'
2 |
3 | export default {
4 | feed() {
5 | return {
6 | path: '/object-type/posts',
7 | resolve: (response, mappers) => {
8 | let _posts = _map(response.objects, function(i) {
9 | let temp = {
10 | title: i.title,
11 | image: i.metadata.image.imgix_url,
12 | published: i.created_at,
13 | author: i.metadata.author.title,
14 | id: i.slug
15 | };
16 | return temp;
17 | })
18 | return mappers.pipe(_posts)
19 | }
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/resources/BlogPost.js:
--------------------------------------------------------------------------------
1 | export default {
2 | post(id) {
3 | return {
4 | path: `/object/${id}`,
5 | resolve: (response, mappers) => {
6 | let { title, content, created_at, metadata } = response.object
7 | let meta = {
8 | description: metadata.description,
9 | published: created_at,
10 | author: metadata.author.title
11 | }
12 | return mappers.merge({ title, content, ...meta })
13 | }
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/resources/index.js:
--------------------------------------------------------------------------------
1 | export { default as Blog } from './Blog'
2 | export { default as BlogFeed } from './BlogFeed'
3 | export { default as BlogPost } from './BlogPost'
4 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import Blog from '../components'
4 |
5 | Vue.use(Router)
6 |
7 | export default new Router({
8 | mode: 'history',
9 | linkActiveClass: 'active',
10 | routes: [{
11 | path: '/',
12 | name: 'feed',
13 | component: Blog
14 | }, {
15 | path: '/by/:author',
16 | name: 'author',
17 | props: true,
18 | component: Blog
19 | }, {
20 | path: '/read/:post',
21 | name: 'post',
22 | props: true,
23 | component: Blog
24 | }]
25 | })
26 |
--------------------------------------------------------------------------------
/src/sass/_app.scss:
--------------------------------------------------------------------------------
1 | @import
2 | // tools */
3 | './tools',
4 | './tools/mediaqueries',
5 | // base */
6 | './base/reset',
7 | './base/text',
8 | './base/body',
9 | // blocks */
10 | './blocks/pace',
11 | './blocks/rte',
12 | './blocks/nav',
13 | './blocks/blog',
14 | './blocks/preview',
15 | './blocks/post',
16 | './blocks/footer',
17 | './blocks/v-transitions'
18 |
--------------------------------------------------------------------------------
/src/sass/_tools.scss:
--------------------------------------------------------------------------------
1 | // tools */
2 | @import
3 | './tools/mixins',
4 | './tools/colors',
5 | './tools/easings',
6 | './tools/functions'
7 |
--------------------------------------------------------------------------------
/src/sass/base/_body.scss:
--------------------------------------------------------------------------------
1 | body {
2 | @extend %txt--body;
3 | position: relative;
4 | color: cc(txt);
5 | background-color: cc(bg);
6 |
7 | ::selection {
8 | background-color: cc(selection);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/sass/base/_reset.scss:
--------------------------------------------------------------------------------
1 | /* reset */
2 | * {
3 | box-sizing: inherit;
4 | margin: 0;
5 | padding: 0;
6 | border-radius: 0;
7 | border: none;
8 | outline: none;
9 | background: none;
10 | -webkit-margin-before: 0;
11 | -webkit-margin-after: 0;
12 | -webkit-margin-start: 0;
13 | -webkit-margin-end: 0;
14 | -webkit-padding-before: 0;
15 | -webkit-padding-start: 0;
16 | -webkit-padding-end: 0;
17 | -webkit-padding-after: 0;
18 | }
19 |
20 | *::before,
21 | *::after {
22 | box-sizing: inherit;
23 | }
24 |
25 | *:active,
26 | *:hover {
27 | outline: 0;
28 | }
29 |
30 | html {
31 | box-sizing: border-box;
32 | font-size: 100%;
33 | height: 100%;
34 | }
35 |
36 | body {
37 | position: relative;
38 | line-height: 1;
39 | -webkit-font-smoothing: antialiased;
40 | -moz-osx-font-smoothing: grayscale;
41 | }
42 |
43 | b, i, em, strong,
44 | h1, h2, h3, h4, h5, h6,
45 | th, td, pre, ins, del, address,
46 | input, select, button, textarea {
47 | text-transform: inherit;
48 | font-family: inherit;
49 | font-size: inherit;
50 | font-weight: inherit;
51 | font-style: normal;
52 | letter-spacing: inherit;
53 | }
54 |
55 | textarea,
56 | input {
57 | appearance: none;
58 | background-clip: padding-box;
59 | }
60 |
61 | a, ins, del, button {
62 | color: inherit;
63 | text-decoration: none;
64 | }
65 |
66 | ul, ol,
67 | menu {
68 | list-style: none;
69 | }
70 |
71 | table {
72 | width: 100%;
73 | border-collapse: separate;
74 | border-spacing: 0;
75 | }
76 |
77 | pre,
78 | textarea {
79 | overflow: auto;
80 | max-width: 100%;
81 | }
82 |
83 | img {
84 | display: block;
85 | width: 100%;
86 | height: auto;
87 | }
88 |
89 | svg:not(:root) {
90 | overflow: hidden;
91 | }
92 |
93 | form {
94 | width: 100%;
95 | }
96 |
97 | button {
98 | cursor: pointer;
99 | overflow: visible;
100 | }
101 |
102 | textarea {
103 | resize: none;
104 | }
105 |
106 | ::moz-focus-inner {
107 | padding: 0;
108 | border: none;
109 | }
110 |
--------------------------------------------------------------------------------
/src/sass/base/_text.scss:
--------------------------------------------------------------------------------
1 | // font stack
2 | @mixin font-stack($ff, $weight: normal) {
3 | font-family: #{$ff}, Helvetica, Arial, sans-serif;
4 | font-weight: $weight;
5 | }
6 |
7 | // font families
8 | %ff--200 { @include font-stack('Prompt', 200) }
9 | %ff--300 { @include font-stack('Prompt', 300) }
10 | %ff--500 { @include font-stack('Prompt', 500) }
11 | %ff--700 { @include font-stack('Prompt', 700) }
12 |
13 | // extend placeholders
14 | %txt--body {
15 | @extend %ff--300;
16 | font-size: 1rem;
17 | }
18 |
19 | %txt--rte {
20 | @extend %txt--body;
21 | line-height: 1.5;
22 | }
23 |
24 | %txt--banner {
25 | @extend %ff--700;
26 | line-height: 1;
27 | font-size: 2.4rem;
28 | letter-spacing: -.005em;
29 |
30 | @media (--tablet) {
31 | font-size: 2.6rem;
32 | }
33 | }
34 |
35 | %txt--preview {
36 | @extend %ff--500;
37 | font-size: 3rem;
38 | text-transform: capitalize;
39 |
40 | @media (--laptop) {
41 | font-size: 2.7rem;
42 | }
43 |
44 | @media (--desktop) {
45 | font-size: 3.2rem;
46 | }
47 | }
48 |
49 | %txt--title {
50 | @extend %ff--200;
51 | font-size: 3rem;
52 | line-height: 1.2;
53 | text-transform: capitalize;
54 |
55 | @media (--laptop) {
56 | font-size: 3.2rem;
57 | }
58 | }
59 |
60 | %txt--subtitle {
61 | @extend %ff--500;
62 | font-size: 1.25rem;
63 | line-height: 1.5;
64 | }
65 |
66 | %txt--heading {
67 | @extend %ff--700;
68 | font-size: 1.15rem;
69 | line-height: 1.5;
70 | }
71 |
--------------------------------------------------------------------------------
/src/sass/blocks/_blog.scss:
--------------------------------------------------------------------------------
1 | .blog {
2 | position: relative;
3 | min-height: 100vh;
4 | max-width: 90rem;
5 | margin: 0 auto;
6 | padding-top: 6.25rem;
7 | overflow-x: hidden;
8 |
9 | @media (--tablet) {
10 | padding: 7.5rem 0;
11 | }
12 |
13 | @media (--desktop) {
14 | padding: 7.5rem 2.5rem 6.5vw;
15 |
16 | &--reading {
17 | padding-bottom: 0;
18 | }
19 | }
20 |
21 | @media (--monitor) {
22 | padding: 7.5rem 0 6.5vw;
23 |
24 | &--reading {
25 | padding-bottom: 0;
26 | }
27 | }
28 |
29 | &__feed {
30 | position: relative;
31 | padding: 0 .625rem;
32 |
33 | @media (--tablet) {
34 | display: flex;
35 | align-items: flex-start;
36 | flex-wrap: wrap;
37 | padding: 0 1.25rem;
38 | }
39 |
40 | @media (--monitor) {
41 | padding: 0;
42 | }
43 | }
44 |
45 | &__footer {
46 | width: 100%;
47 | height: 5rem;
48 | display: flex;
49 | justify-content: center;
50 | align-items: center;
51 | padding: 0 2.5rem;
52 |
53 | @media (--tablet) {
54 | position: absolute;
55 | bottom: 0;
56 | left: 0;
57 | }
58 |
59 | @media (--laptop) {
60 | justify-content: flex-start;
61 | }
62 |
63 | @media (--desktop) {
64 | padding: 0 6.25rem;
65 | }
66 |
67 | @media (--monitor) {
68 | padding: 0 2.5rem;
69 | }
70 |
71 | .signature {
72 | display: inline-block;
73 | width: 15rem;
74 | text-align: center;
75 |
76 | @media (--tablet) {
77 | width: 18rem;
78 | }
79 | }
80 | .cosmicjs {
81 | color: #ADB6C0;
82 | text-transform: capitalize;
83 | a {
84 | color: #2A3744;
85 | font-weight: 400;
86 | }
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/sass/blocks/_footer.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/src/sass/blocks/_footer.scss
--------------------------------------------------------------------------------
/src/sass/blocks/_nav.scss:
--------------------------------------------------------------------------------
1 | .nav {
2 | position: fixed;
3 | top: 0;
4 | left: 50%;
5 | width: calc(100% - 2.5rem);
6 | max-width: 90rem;
7 | padding: 1.25rem .625rem .625rem;
8 | border-bottom: 1px solid cc(border);
9 | background-color: cc(bg, .975);
10 | box-shadow: 0 -50vw 0 50vw cc(bg, .975);
11 | display: flex;
12 | justify-content: space-between;
13 | align-items: flex-end;
14 | transform: translate(-50%);
15 | z-index: 1;
16 |
17 | @media (--tablet) {
18 | padding: 1.75rem 1.25rem 1.25rem;
19 | }
20 |
21 | @media (--desktop) {
22 | width: calc(100% - 10rem);
23 | }
24 |
25 | @media (--monitor) {
26 | padding: 1.75rem 2.5rem 1.25rem;
27 | }
28 |
29 | &__title {
30 | @extend %txt--banner;
31 | color: cc(txt, alt);
32 | }
33 |
34 | &__menu {
35 | position: relative;
36 |
37 | @media (--phone) {
38 | height: 1.75rem;
39 | }
40 | }
41 |
42 | &__item {
43 | cursor: pointer;
44 | display: inline-block;
45 | position: relative;
46 | margin-left: .75rem;
47 | padding-left: .25rem;
48 | user-select: none;
49 | white-space: nowrap;
50 | z-index: 0;
51 | transition: all 250ms cb() 300ms;
52 |
53 | @media (--phone) {
54 | width: 1.75rem;
55 | height: 1.75rem;
56 | }
57 |
58 | &-enter,
59 | &-leave-to {
60 | opacity: 0;
61 | transition-delay: 0ms;
62 | transform: translate3d(-2.5rem, 0, 0);
63 | }
64 |
65 | &-leave-active {
66 | position: absolute;
67 | bottom: 0;
68 | right: 0;
69 | }
70 |
71 | &--icon {
72 | display: block;
73 | position: absolute;
74 | top: 50%;
75 | right: 100%;
76 | transform: translate3d(-25%, -50%, 0);
77 | font-size: 1.25rem;
78 | width: 1em;
79 | height: 1em;
80 | box-shadow: inset 0 0 0 0 cc(primary);
81 | border-radius: 100%;
82 | overflow: hidden;
83 | transition: box-shadow 175ms cb() 25ms;
84 |
85 | &::before,
86 | &::after {
87 | content: '';
88 | position: absolute;
89 | top: 50%;
90 | left: 50%;
91 | width: 10%;
92 | height: 70%;
93 | background-color: cc(bg);
94 | transition: transform 225ms cb();
95 | }
96 |
97 | &::before { transform: translate3d(-50%, -50%, 0) rotate(-45deg) scaleY(0) }
98 | &::after { transform: translate3d(-50%, -50%, 0) rotate(45deg) scaleY(0) }
99 |
100 | @media (--phone) {
101 | right: 0;
102 | box-shadow: none;
103 | background-color: cc(primary);
104 |
105 | &::before,
106 | &::after {
107 | height: 35%;
108 | }
109 |
110 | &::before {
111 | transform: translate3d(0, -50%, 0) rotate(-45deg) scaleY(1);
112 | transform-origin: 100% 100%;
113 | }
114 |
115 | &::after {
116 | transform: translate3d(0, -50%, 0) rotate(45deg) scaleY(1);
117 | transform-origin: 100% 0%;
118 | }
119 | }
120 | }
121 |
122 | &:hover &--icon {
123 | box-shadow: inset 0 0 0 1.1em cc(primary);
124 | &::before { transform: translate3d(-50%, -50%, 0) rotate(-45deg) scaleY(1) }
125 | &::after { transform: translate3d(-50%, -50%, 0) rotate(45deg) scaleY(1) }
126 | }
127 |
128 | &--label {
129 | @media (--phone) {
130 | display: none;
131 | }
132 | }
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/sass/blocks/_pace.scss:
--------------------------------------------------------------------------------
1 | .pace {
2 | pointer-events: none;
3 | user-select: none;
4 |
5 | &-inactive {
6 | display: none;
7 | }
8 |
9 | .pace-progress {
10 | background: cc(primary);
11 | position: fixed;
12 | z-index: 2000;
13 | top: 0;
14 | right: 100%;
15 | width: 100%;
16 | height: 3px;
17 | }
18 | }
19 |
20 | .pace-inactive {
21 | display: none;
22 | }
23 |
--------------------------------------------------------------------------------
/src/sass/blocks/_post.scss:
--------------------------------------------------------------------------------
1 | .post {
2 | padding: 0 1.25rem 0;
3 | background-color: cc(bg);
4 | transform: translate3d(0, 0, 0);
5 |
6 | &-enter-active { transition: all 375ms cb(out) 225ms }
7 | &-leave-active { transition: all 300ms cb(in) }
8 |
9 | &-enter,
10 | &-leave-to {
11 | opacity: 0;
12 | transform: translate3d(100%, 0, 0);
13 | }
14 |
15 | @media (--laptop) {
16 | position: fixed;
17 | top: 0;
18 | left: calc(100% / 3 + 3.25rem);
19 | width: calc(100% / 1.5 - 3.25rem);
20 | height: 100%;
21 | padding: 10rem 5rem 5rem 0;
22 | overflow-y: scroll;
23 |
24 | &-enter-active { transition: all 525ms cb(out) 225ms }
25 | &-leave-active { transition: all 350ms cb(in) }
26 |
27 | &-enter,
28 | &-leave-to {
29 | opacity: 0;
30 | transform: translate3d(100%, 0, 0);
31 | }
32 | }
33 |
34 | @media (--monitor) {
35 | width: 62rem;
36 | left: calc(50% - 12rem);
37 | }
38 |
39 | &__header {
40 | @media (--tablet) {
41 | position: absolute;
42 | bottom: 100%;
43 | right: 0;
44 | width: 50vw;
45 | height: calc(70vw - 2.5rem);
46 | display: flex;
47 | flex-direction: column;
48 | padding-right: 2.5rem;
49 | padding-bottom: 2.5rem;
50 | }
51 |
52 | @media (--laptop) {
53 | position: static;
54 | width: auto;
55 | height: auto;
56 | display: block;
57 | margin-bottom: 1.25rem;
58 | padding-bottom: 0;
59 | }
60 | }
61 |
62 | &__title {
63 | @extend %txt--title;
64 | display: none;
65 |
66 | @media (--tablet) {
67 | display: block;
68 | color: cc(txt, alt);
69 | margin-bottom: .75rem;
70 | padding-left: 1.25rem;
71 | }
72 | }
73 |
74 | &__meta {
75 | display: none;
76 |
77 | @media (--tablet) {
78 | display: block;
79 | margin-bottom: 1.25rem;
80 | padding-left: 1.25rem;
81 | padding-bottom: 1.25rem;
82 | }
83 |
84 | @media (--laptop) {
85 | border-bottom: 1px solid cc(border);
86 | }
87 | }
88 |
89 | &__author {
90 | @extend %ff--500;
91 | text-decoration: underline;
92 | }
93 |
94 | &__sep {
95 | display: block;
96 | height: .625rem;
97 |
98 | @media (--laptop) {
99 | display: inline-block;
100 | margin: 0 .5rem;
101 |
102 | &::before {
103 | content: '—';
104 | }
105 | }
106 | }
107 |
108 | &__subtitle {
109 | @extend %txt--subtitle;
110 | flex-grow: 1;
111 | display: flex;
112 | flex-direction: column;
113 | justify-content: center;
114 | padding: 0 2.5rem 1.25rem 2.5rem;
115 |
116 | @media (--tablet) {
117 | padding-top: 1.25rem;
118 | }
119 |
120 | @media (--laptop) {
121 | padding-right: 7.5rem;
122 | }
123 | }
124 |
125 | &__body {
126 | padding: 1.25rem 1.25rem 3.75rem;
127 | border-bottom: 1px solid cc(border);
128 |
129 | @media (--laptop) {
130 | padding: 0 1.25rem 2.5rem;
131 | }
132 | }
133 |
134 | &__footer {
135 | margin-top: 3.75rem;
136 | padding: 0 1.25rem;
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/src/sass/blocks/_preview.scss:
--------------------------------------------------------------------------------
1 | .preview {
2 | position: relative;
3 | margin: 1.25rem 1.25rem 5rem;
4 | z-index: 0;
5 | @include imagePlaceholder;
6 |
7 | @media (--tablet) {
8 | width: calc(50% - 2.5rem);
9 | margin: 1.25rem 1.25rem 2.5rem;
10 | }
11 |
12 | @media (--laptop) {
13 | width: calc(100% / 3 - 2.5rem);
14 | }
15 |
16 | @media (--desktop) {
17 | width: calc(100% / 3 - 5rem);
18 | margin: 1rem;
19 | }
20 |
21 | &-move { transition: all 550ms cb() }
22 | &-enter-active { transition: all 325ms cb(out) 175ms }
23 | &-appear-enter-active { transition: all 275ms cb(out) 200ms }
24 |
25 | &-leave-active {
26 | transition: all 225ms cb(in);
27 | position: absolute;
28 | z-index: -1;
29 | }
30 |
31 | &-enter,
32 | &-leave-to,
33 | &-appear-enter {
34 | opacity: 0;
35 | transform: translate3d(0, -2.5rem, 0);
36 | }
37 |
38 | &__figure {
39 | position: relative;
40 | padding-top: 140%;
41 | transition: padding-top 275ms cb(out);
42 | @include bgCover;
43 |
44 | &::before {
45 | content: '';
46 | position: absolute;
47 | top: 0;
48 | left: 0;
49 | width: 100%;
50 | height: 33%;
51 | background-image: linear-gradient(to bottom, cc(shadow, .33), transparent);
52 | }
53 |
54 | &--mobile {
55 | padding-top: 90%;
56 | }
57 | }
58 |
59 | &__details {
60 | position: absolute;
61 | top: 0;
62 | left: 0;
63 | width: 100%;
64 | height: 100%;
65 | }
66 |
67 | &__title {
68 | @extend %txt--preview;
69 | display: block;
70 | height: 100%;
71 | padding: .75rem;
72 | color: cc(txt, inv);
73 | background-color: cc(shadow, 0);
74 | transition: background-color 225ms cb();
75 |
76 | .preview__figure--mobile &,
77 | &:hover {
78 | background-color: cc(shadow, .65);
79 | }
80 |
81 | @media (--monitor) {
82 | padding-right: 1.5rem;
83 | }
84 | }
85 |
86 | &__meta {
87 | position: absolute;
88 | top: 100%;
89 | left: 0;
90 | padding: .5rem 0;
91 | font-size: .9rem;
92 |
93 | @media (--tablet) {
94 | white-space: nowrap;
95 | }
96 | }
97 |
98 | &__published::after {
99 | content: 'by';
100 | padding: 0 .25rem;
101 | }
102 |
103 | &__author {
104 | @extend %ff--500;
105 | text-decoration: underline;
106 | white-space: nowrap;
107 | font-size: .9rem;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/sass/blocks/_rte.scss:
--------------------------------------------------------------------------------
1 | .rte {
2 | @extend %txt--rte;
3 |
4 | p + p {
5 | margin-top: 1em;
6 | }
7 |
8 | a:hover,
9 | a:hover * {
10 | text-decoration: underline;
11 | }
12 |
13 | h3,
14 | h4 {
15 | margin: 1.25em 0 .75em;
16 | }
17 |
18 | em {
19 | font-style: italic;
20 | }
21 |
22 | strong {
23 | @extend %ff--500;
24 | }
25 |
26 | em strong,
27 | strong em {
28 | @extend %ff--500;
29 | font-style: italic;
30 | }
31 |
32 | ul {
33 | margin-top: 1.5em;
34 | margin-bottom: .75em;
35 |
36 | li {
37 | position: relative;
38 | padding-left: 1.5em;
39 |
40 | &::before {
41 | content: '';
42 | display: inline-block;
43 | position: absolute;
44 | top: .4em;
45 | left: 0;
46 | width: .2em;
47 | height: .2em;
48 | border-radius: 100%;
49 | bacground-color: cc(accent);
50 | }
51 |
52 | & + li {
53 | margin-top: .5em;
54 | }
55 | }
56 | }
57 |
58 | figure {
59 | text-align: center;
60 | margin: 2.25em 0;
61 | }
62 |
63 | figcaption {
64 | font-size: 14px;
65 | text-align: center;
66 | font-style: italic;
67 | }
68 |
69 | img {
70 | display: inline-block;
71 | max-width: 100%;
72 | }
73 |
74 | iframe {
75 | max-width: 100%;
76 | }
77 |
78 | address {
79 | display: inline-block;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/sass/blocks/_v-transitions.scss:
--------------------------------------------------------------------------------
1 | .v {
2 | &--fade {
3 | &-enter-active,
4 | &-leave-active { transition: all 275ms cb() }
5 |
6 | &-enter,
7 | &-leave-to { opacity: 0 }
8 |
9 | &-leave,
10 | &-enter-to { opacity: 1 }
11 | }
12 |
13 | &--mask {
14 | &-enter-active,
15 | &-leave-active { transition: all 150ms cb() 500ms }
16 |
17 | &-enter,
18 | &-leave-to { opacity: 0 }
19 |
20 | &-leave,
21 | &-enter-to { opacity: 1 }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/sass/tools/_colors.scss:
--------------------------------------------------------------------------------
1 | // colors
2 | $ghost-white: #fcfdff;
3 | $mystic: #dae4eb;
4 | $gunmetal: #2a3744;
5 | $smoky-black: #0a0908;
6 |
7 | // cc map
8 | $colors:(
9 | default:(
10 | bg: $ghost-white,
11 | txt: $smoky-black,
12 | primary: $gunmetal,
13 | border: $mystic,
14 | shadow: $smoky-black,
15 | overlay: $gunmetal,
16 | selection: rgba($gunmetal, .33)
17 | ),
18 |
19 | alt:(
20 | txt: $gunmetal,
21 | bg: $mystic,
22 | border: $gunmetal
23 | ),
24 |
25 | inv:(
26 | txt: $ghost-white
27 | )
28 | );
29 |
--------------------------------------------------------------------------------
/src/sass/tools/_easings.scss:
--------------------------------------------------------------------------------
1 | $easings:(
2 | default: cubic-bezier(.4, .25, .3, 1),
3 | in: cubic-bezier(.6, .1, .8, .7),
4 | out: cubic-bezier(.2, .3, .4, .9),
5 | in-out: cubic-bezier(.5, .15, .4, 1),
6 | bounce: cubic-bezier(.4, .25, .3, 1.4)
7 | );
8 |
--------------------------------------------------------------------------------
/src/sass/tools/_functions.scss:
--------------------------------------------------------------------------------
1 | // cubic-bezier
2 | @function cb($fn: default) {
3 | @return map-get($easings, $fn);
4 | }
5 |
6 | // em
7 | @function em($pixels, $context: 16) {
8 | @return #{$pixels/$context}em;
9 | }
10 |
11 | // color-control
12 | @function cc($color, $option: false, $alpha: false) {
13 | $opacity: null;
14 | $palette: null;
15 |
16 | @if ($alpha) {$opacity: $alpha;}
17 | @else {$opacity: if(type-of($option) == 'number', $option, false);}
18 |
19 | @if ($option) {$palette: if(type-of($option) == 'number', default, $option);}
20 | @else {$palette: default;}
21 |
22 | $getPalette: map-get($colors, $palette);
23 |
24 | @return if($opacity, rgba(map-get($getPalette, $color), $opacity), map-get($getPalette, $color));
25 | }
26 |
--------------------------------------------------------------------------------
/src/sass/tools/_mediaqueries.scss:
--------------------------------------------------------------------------------
1 | @custom-media --phone only screen and (max-width: #{em(567)});
2 | @custom-media --tablet only screen and (min-width: #{em(568)});
3 | @custom-media --mobile only screen and (max-width: #{em(1024)});
4 | @custom-media --laptop only screen and (min-width: #{em(1025)});
5 | @custom-media --desktop only screen and (min-width: #{em(1280)});
6 | @custom-media --monitor only screen and (min-width: #{em(1448)});
7 |
--------------------------------------------------------------------------------
/src/sass/tools/_mixins.scss:
--------------------------------------------------------------------------------
1 | @mixin imagePlaceholder() {
2 | background-image: linear-gradient(
3 | to bottom,
4 | rgba(#162229, .75),
5 | rgba(#064362, .75),
6 | rgba(#6f868c, .75),
7 | rgba(#673c28, .75)
8 | );
9 | }
10 |
11 | @mixin bgCover($_pos:center) {
12 | background-size: cover;
13 | background-repeat: no-repeat;
14 | background-position: $_pos;
15 | }
16 |
--------------------------------------------------------------------------------
/src/startup.js:
--------------------------------------------------------------------------------
1 | import Pace from 'pace-progress'
2 |
3 | // pace progress bar
4 | Pace.start()
5 |
6 | // use pace hook to know when rendering is ready
7 | Pace.once('hide', () => {
8 | window.prerenderReady = true
9 | })
10 |
11 | // Spektrum Media console message
12 | console.info('%c', 'line-height:48px;padding:18px 150px;background:url(\'https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/vue-snip.svg\') center / contain no-repeat;')
13 |
--------------------------------------------------------------------------------
/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/static/.gitkeep
--------------------------------------------------------------------------------
/static/api/blog.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "title": "Vue Blog Cosmic JS",
4 | "post_label": "Exit reading mode",
5 | "author_label": "View all Posts"
6 | }]
7 | }
8 |
--------------------------------------------------------------------------------
/static/api/feed.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "title": "neque libero convallis eget",
4 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/karl-magnuson.jpg",
5 | "published": "2017-09-14T18:17:00Z",
6 | "author": "Michelle Blackford",
7 | "id": "neque-libero-convallis-eget"
8 | }, {
9 | "title": "sit amet erat",
10 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/etienne-bosiger.jpg",
11 | "published": "2017-09-09T22:11:56Z",
12 | "author": "Nathan Greave",
13 | "id": "sit-amet-erat"
14 | }, {
15 | "title": "posuere cubilia",
16 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/saksham-gangwar.jpg",
17 | "published": "2017-09-05T00:55:44Z",
18 | "author": "Hugo Curness",
19 | "id": "posuere-cubilia"
20 | }, {
21 | "title": "consequat ut nulla",
22 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/mona-eendra.jpg",
23 | "published": "2017-07-28T18:31:01Z",
24 | "author": "Derrik Yerrington",
25 | "id": "consequat-ut-nulla"
26 | }, {
27 | "title": "curabitur gravida nisi",
28 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/adam-krowitz.jpg",
29 | "published": "2017-06-12T10:01:51Z",
30 | "author": "Michelle Blackford",
31 | "id": "curabitur-gravida-nisi"
32 | }, {
33 | "title": "pretium nisl",
34 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/steven-pahel.jpg",
35 | "published": "2017-06-02T03:22:11Z",
36 | "author": "Nathan Greave",
37 | "id": "pretium-nisl"
38 | }, {
39 | "title": "vivamus tortor duis mattis",
40 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/simone-hutsch.jpg",
41 | "published": "2017-05-27T00:05:26Z",
42 | "author": "Tommi Filipson",
43 | "id": "vivamus-tortor-duis-mattis"
44 | }, {
45 | "title": "potenti cras in purus",
46 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/casey-horner.jpg",
47 | "published": "2017-05-25T13:12:39Z",
48 | "author": "Nathan Greave",
49 | "id": "potenti-cras-in-purus"
50 | }, {
51 | "title": "ultrices mattis odio",
52 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/nate-rayfield.jpg",
53 | "published": "2017-05-10T13:57:35Z",
54 | "author": "Nathan Greave",
55 | "id": "ultrices-mattis-odio"
56 | }, {
57 | "title": "nunc commodo placerat",
58 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/kimon-maritz.jpg",
59 | "published": "2017-04-12T09:43:53Z",
60 | "author": "Nathan Greave",
61 | "id": "nunc-commodo-placerat"
62 | }, {
63 | "title": "sit amet diam in",
64 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/shalom-mwenesi.jpg",
65 | "published": "2017-04-03T22:21:22Z",
66 | "author": "Derrik Yerrington",
67 | "id": "sit-amet-diam-in"
68 | }, {
69 | "title": "sapien ut nunc",
70 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/robson-hatsukami-morgan.jpg",
71 | "published": "2017-03-10T21:11:06Z",
72 | "author": "Derrik Yerrington",
73 | "id": "sapien-ut-nunc"
74 | }, {
75 | "title": "ut massa quis augue",
76 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/tom-barrett.jpg",
77 | "published": "2016-12-15T23:29:56Z",
78 | "author": "Nathan Greave",
79 | "id": "ut-massa-quis-augue"
80 | }, {
81 | "title": "lacinia eget tincidunt",
82 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/joshua-hibbert.jpg",
83 | "published": "2016-11-02T02:21:18Z",
84 | "author": "Martha Bonde",
85 | "id": "lacinia-eget-tincidunt"
86 | }, {
87 | "title": "dolor quis",
88 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/maarten-van-den-heuvel.jpg",
89 | "published": "2016-10-27T09:42:32Z",
90 | "author": "Tommi Filipson",
91 | "id": "dolor-quis"
92 | }]
93 | }
94 |
--------------------------------------------------------------------------------
/static/api/post/consequat-ut-nulla.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "consequat-ut-nulla",
4 | "title": "consequat ut nulla",
5 | "content": "Etiam vel augue. Vestibulum rutrum rutrum neque. Aenean auctor gravida sem.\n\nPraesent id massa id nisl venenatis lacinia. Aenean sit amet justo. Morbi ut odio.\n\nCras mi pede, malesuada in, imperdiet et, commodo vulputate, justo. In blandit ultrices enim. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.\n\nProin interdum mauris non ligula pellentesque ultrices. Phasellus id sapien in sapien iaculis congue. Vivamus metus arcu, adipiscing molestie, hendrerit at, vulputate vitae, nisl.\n\nAenean lectus. Pellentesque eget nunc. Donec quis orci eget orci vehicula condimentum.\n\nCurabitur in libero ut massa volutpat convallis. Morbi odio odio, elementum eu, interdum eu, tincidunt in, leo. Maecenas pulvinar lobortis est.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/mona-eendra.jpg",
7 | "meta": {
8 | "description": "Fusce posuere felis sed lacus. Morbi sem mauris, laoreet ut, rhoncus aliquet, pulvinar sed, nisl. Nunc rhoncus dui vel sem.",
9 | "published": "2017-07-28T18:31:01Z",
10 | "author": "Derrik Yerrington"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/api/post/curabitur-gravida-nisi.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "curabitur-gravida-nisi",
4 | "title": "curabitur gravida nisi",
5 | "content": "Sed ante. Vivamus tortor. Duis mattis egestas metus.\n\nAenean fermentum. Donec ut mauris eget massa tempor convallis. Nulla neque libero, convallis eget, eleifend luctus, ultricies eu, nibh.\n\nQuisque id justo sit amet sapien dignissim vestibulum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla dapibus dolor vel est. Donec odio justo, sollicitudin ut, suscipit a, feugiat et, eros.\n\nVestibulum ac est lacinia nisi venenatis tristique. Fusce congue, diam id ornare imperdiet, sapien urna pretium nisl, ut volutpat sapien arcu sed augue. Aliquam erat volutpat.\n\nIn congue. Etiam justo. Etiam pretium iaculis justo.\n\nIn hac habitasse platea dictumst. Etiam faucibus cursus urna. Ut tellus.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/adam-krowitz.jpg",
7 | "meta": {
8 | "description": "Proin at turpis a pede posuere nonummy. Integer non velit. Donec diam neque, vestibulum eget, vulputate ut, ultrices vel, augue.",
9 | "published": "2017-06-12T10:01:51Z",
10 | "author": "Michelle Blackford"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/api/post/dolor-quis.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "dolor-quis",
4 | "title": "dolor quis",
5 | "content": "Morbi porttitor lorem id ligula. Suspendisse ornare consequat lectus. In est risus, auctor sed, tristique in, tempus sit amet, sem.\n\nFusce consequat. Nulla nisl. Nunc nisl.\n\nDuis bibendum, felis sed interdum venenatis, turpis enim blandit mi, in porttitor pede justo eu massa. Donec dapibus. Duis at velit eu est congue elementum.\n\nIn hac habitasse platea dictumst. Morbi vestibulum, velit id pretium iaculis, diam erat fermentum justo, nec condimentum neque sapien placerat ante. Nulla justo.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/kimon-maritz.jpg",
7 | "meta": {
8 | "description": "Nunc nisl. Duis bibendum, felis sed interdum venenatis, turpis enim blandit mi, in porttitor pede justo eu massa. Donec dapibus.",
9 | "published": "2017-04-12T09:43:53Z",
10 | "author": "Nathan Greave"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/api/post/lacinia-eget-tincidunt.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "lacinia-eget-tincidunt",
4 | "title": "lacinia eget tincidunt",
5 | "content": "Aliquam quis turpis eget elit sodales scelerisque. Mauris sit amet eros. Suspendisse accumsan tortor quis turpis.\n\nSed ante. Vivamus tortor. Duis mattis egestas metus.\n\nAenean fermentum. Donec ut mauris eget massa tempor convallis. Nulla neque libero, convallis eget, eleifend luctus, ultricies eu, nibh.\n\nQuisque id justo sit amet sapien dignissim vestibulum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla dapibus dolor vel est. Donec odio justo, sollicitudin ut, suscipit a, feugiat et, eros.\n\nVestibulum ac est lacinia nisi venenatis tristique. Fusce congue, diam id ornare imperdiet, sapien urna pretium nisl, ut volutpat sapien arcu sed augue. Aliquam erat volutpat.\n\nIn congue. Etiam justo. Etiam pretium iaculis justo.\n\nIn hac habitasse platea dictumst. Etiam faucibus cursus urna. Ut tellus.\n\nNulla ut erat id mauris vulputate elementum. Nullam varius. Nulla facilisi.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/joshua-hibbert.jpg",
7 | "meta": {
8 | "description": "Nam dui. Proin leo odio, porttitor id, consequat in, consequat ut, nulla.",
9 | "published": "2016-11-02T02:21:18Z",
10 | "author": "Martha Bonde"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/api/post/neque-libero-convallis-eget.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "neque-libero-convallis-eget",
4 | "title": "neque libero convallis eget",
5 | "content": "In hac habitasse platea dictumst. Morbi vestibulum, velit id pretium iaculis, diam erat fermentum justo, nec condimentum neque sapien placerat ante. Nulla justo.\n\nAliquam quis turpis eget elit sodales scelerisque. Mauris sit amet eros. Suspendisse accumsan tortor quis turpis.\n\nSed ante. Vivamus tortor. Duis mattis egestas metus.\n\nAenean fermentum. Donec ut mauris eget massa tempor convallis. Nulla neque libero, convallis eget, eleifend luctus, ultricies eu, nibh.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/karl-magnuson.jpg",
7 | "meta": {
8 | "description": "Morbi sem mauris, laoreet ut, rhoncus aliquet, pulvinar sed, nisl. Nunc rhoncus dui vel sem.",
9 | "published": "2017-09-14T18:17:00Z",
10 | "author": "Michelle Blackford"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/api/post/nunc-commodo-placerat.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "nunc-commodo-placerat",
4 | "title": "nunc commodo placerat",
5 | "content": "In sagittis dui vel nisl. Duis ac nibh. Fusce lacus purus, aliquet at, feugiat non, pretium quis, lectus.\n\nSuspendisse potenti. In eleifend quam a odio. In hac habitasse platea dictumst.\n\nMaecenas ut massa quis augue luctus tincidunt. Nulla mollis molestie lorem. Quisque ut erat.\n\nCurabitur gravida nisi at nibh. In hac habitasse platea dictumst. Aliquam augue quam, sollicitudin vitae, consectetuer eget, rutrum at, lorem.\n\nInteger tincidunt ante vel ipsum. Praesent blandit lacinia erat. Vestibulum sed magna at nunc commodo placerat.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/robson-hatsukami-morgan.jpg",
7 | "meta": {
8 | "description": "Morbi non quam nec dui luctus rutrum. Nulla tellus. In sagittis dui vel nisl.",
9 | "published": "2017-03-10T21:11:06Z",
10 | "author": "Derrik Yerrington"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/api/post/posuere-cubilia.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "posuere-cubilia",
4 | "title": "posuere cubilia",
5 | "content": "Sed sagittis. Nam congue, risus semper porta volutpat, quam pede lobortis ligula, sit amet eleifend pede libero quis orci. Nullam molestie nibh in lectus.\n\nPellentesque at nulla. Suspendisse potenti. Cras in purus eu magna vulputate luctus.\n\nCum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus vestibulum sagittis sapien. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.\n\nEtiam vel augue. Vestibulum rutrum rutrum neque. Aenean auctor gravida sem.\n\nPraesent id massa id nisl venenatis lacinia. Aenean sit amet justo. Morbi ut odio.\n\nCras mi pede, malesuada in, imperdiet et, commodo vulputate, justo. In blandit ultrices enim. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/saksham-gangwar.jpg",
7 | "meta": {
8 | "description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin risus.",
9 | "published": "2017-09-05T00:55:44Z",
10 | "author": "Hugo Curness"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/api/post/potenti-cras-in-purus.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "potenti-cras-in-purus",
4 | "title": "potenti cras in purus",
5 | "content": "Sed ante. Vivamus tortor. Duis mattis egestas metus.\n\nAenean fermentum. Donec ut mauris eget massa tempor convallis. Nulla neque libero, convallis eget, eleifend luctus, ultricies eu, nibh.\n\nQuisque id justo sit amet sapien dignissim vestibulum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla dapibus dolor vel est. Donec odio justo, sollicitudin ut, suscipit a, feugiat et, eros.\n\nVestibulum ac est lacinia nisi venenatis tristique. Fusce congue, diam id ornare imperdiet, sapien urna pretium nisl, ut volutpat sapien arcu sed augue. Aliquam erat volutpat.\n\nIn congue. Etiam justo. Etiam pretium iaculis justo.\n\nIn hac habitasse platea dictumst. Etiam faucibus cursus urna. Ut tellus.\n\nNulla ut erat id mauris vulputate elementum. Nullam varius. Nulla facilisi.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/casey-horner.jpg",
7 | "meta": {
8 | "description": "Proin interdum mauris non ligula pellentesque ultrices. Phasellus id sapien in sapien iaculis congue.",
9 | "published": "2017-05-25T13:12:39Z",
10 | "author": "Nathan Greave"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/api/post/pretium-nisl.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "pretium-nisl",
4 | "title": "pretium nisl",
5 | "content": "Nulla ut erat id mauris vulputate elementum. Nullam varius. Nulla facilisi.\n\nCras non velit nec nisi vulputate nonummy. Maecenas tincidunt lacus at velit. Vivamus vel nulla eget eros elementum pellentesque.\n\nQuisque porta volutpat erat. Quisque erat eros, viverra eget, congue eget, semper rutrum, nulla. Nunc purus.\n\nPhasellus in felis. Donec semper sapien a libero. Nam dui.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/steven-pahel.jpg",
7 | "meta": {
8 | "description": "Nullam varius. Nulla facilisi. Cras non velit nec nisi vulputate nonummy.",
9 | "published": "2017-06-02T03:22:11Z",
10 | "author": "Nathan Greave"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/api/post/sapien-ut-nunc.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "sapien-ut-nunc",
4 | "title": "sapien ut nunc",
5 | "content": "Proin interdum mauris non ligula pellentesque ultrices. Phasellus id sapien in sapien iaculis congue. Vivamus metus arcu, adipiscing molestie, hendrerit at, vulputate vitae, nisl.\n\nAenean lectus. Pellentesque eget nunc. Donec quis orci eget orci vehicula condimentum.\n\nCurabitur in libero ut massa volutpat convallis. Morbi odio odio, elementum eu, interdum eu, tincidunt in, leo. Maecenas pulvinar lobortis est.\n\nPhasellus sit amet erat. Nulla tempus. Vivamus in felis eu sapien cursus vestibulum.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/maarten-van-den-heuvel.jpg",
7 | "meta": {
8 | "description": "Morbi vel lectus in quam fringilla rhoncus. Mauris enim leo, rhoncus sed, vestibulum sit amet, cursus id, turpis. Integer aliquet, massa id lobortis convallis.",
9 | "published": "2016-10-27T09:42:32Z",
10 | "author": "Tommi Filipson"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/api/post/sit-amet-diam-in.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "sit-amet-diam-in",
4 | "title": "sit amet diam in",
5 | "content": "Nullam porttitor lacus at turpis. Donec posuere metus vitae ipsum. Aliquam non mauris.\n\nMorbi non lectus. Aliquam sit amet diam in magna bibendum imperdiet. Nullam orci pede, venenatis non, sodales sed, tincidunt eu, felis.\n\nFusce posuere felis sed lacus. Morbi sem mauris, laoreet ut, rhoncus aliquet, pulvinar sed, nisl. Nunc rhoncus dui vel sem.\n\nSed sagittis. Nam congue, risus semper porta volutpat, quam pede lobortis ligula, sit amet eleifend pede libero quis orci. Nullam molestie nibh in lectus.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/shalom-mwenesi.jpg",
7 | "meta": {
8 | "description": "Praesent id massa id nisl venenatis lacinia. Aenean sit amet justo. Morbi ut odio.",
9 | "published": "2017-04-03T22:21:22Z",
10 | "author": "Derrik Yerrington"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/api/post/sit-amet-erat.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "sit-amet-erat",
4 | "title": "sit amet erat",
5 | "content": "Maecenas tristique, est et tempus semper, est quam pharetra magna, ac consequat metus sapien ut nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris viverra diam vitae quam. Suspendisse potenti.\n\nNullam porttitor lacus at turpis. Donec posuere metus vitae ipsum. Aliquam non mauris.\n\nMorbi non lectus. Aliquam sit amet diam in magna bibendum imperdiet. Nullam orci pede, venenatis non, sodales sed, tincidunt eu, felis.\n\nFusce posuere felis sed lacus. Morbi sem mauris, laoreet ut, rhoncus aliquet, pulvinar sed, nisl. Nunc rhoncus dui vel sem.\n\nSed sagittis. Nam congue, risus semper porta volutpat, quam pede lobortis ligula, sit amet eleifend pede libero quis orci. Nullam molestie nibh in lectus.\n\nPellentesque at nulla. Suspendisse potenti. Cras in purus eu magna vulputate luctus.\n\nCum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus vestibulum sagittis sapien. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/etienne-bosiger.jpg",
7 | "meta": {
8 | "description": "Nulla facilisi. Cras non velit nec nisi vulputate nonummy. Maecenas tincidunt lacus at velit.",
9 | "published": "2017-09-09T22:11:56Z",
10 | "author": "Nathan Greave"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/api/post/ultrices-mattis-odio.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "ultrices-mattis-odio",
4 | "title": "ultrices mattis odio",
5 | "content": "Aenean fermentum. Donec ut mauris eget massa tempor convallis. Nulla neque libero, convallis eget, eleifend luctus, ultricies eu, nibh.\n\nQuisque id justo sit amet sapien dignissim vestibulum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla dapibus dolor vel est. Donec odio justo, sollicitudin ut, suscipit a, feugiat et, eros.\n\nVestibulum ac est lacinia nisi venenatis tristique. Fusce congue, diam id ornare imperdiet, sapien urna pretium nisl, ut volutpat sapien arcu sed augue. Aliquam erat volutpat.\n\nIn congue. Etiam justo. Etiam pretium iaculis justo.\n\nIn hac habitasse platea dictumst. Etiam faucibus cursus urna. Ut tellus.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/nate-rayfield.jpg",
7 | "meta": {
8 | "description": "Proin at turpis a pede posuere nonummy. Integer non velit.",
9 | "published": "2017-05-10T13:57:35Z",
10 | "author": "Nathan Greave"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/api/post/ut-massa-quis-augue.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "ut-massa-quis-augue",
4 | "title": "ut massa quis augue",
5 | "content": "Praesent id massa id nisl venenatis lacinia. Aenean sit amet justo. Morbi ut odio.\n\nCras mi pede, malesuada in, imperdiet et, commodo vulputate, justo. In blandit ultrices enim. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.\n\nProin interdum mauris non ligula pellentesque ultrices. Phasellus id sapien in sapien iaculis congue. Vivamus metus arcu, adipiscing molestie, hendrerit at, vulputate vitae, nisl.\n\nAenean lectus. Pellentesque eget nunc. Donec quis orci eget orci vehicula condimentum.\n\nCurabitur in libero ut massa volutpat convallis. Morbi odio odio, elementum eu, interdum eu, tincidunt in, leo. Maecenas pulvinar lobortis est.\n\nPhasellus sit amet erat. Nulla tempus. Vivamus in felis eu sapien cursus vestibulum.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/tom-barrett.jpg",
7 | "meta": {
8 | "description": "Praesent blandit lacinia erat. Vestibulum sed magna at nunc commodo placerat. Praesent blandit.",
9 | "published": "2016-12-15T23:29:56Z",
10 | "author": "Nathan Greave"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/api/post/vivamus-tortor-duis-mattis.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [{
3 | "id": "vivamus-tortor-duis-mattis",
4 | "title": "vivamus tortor duis mattis",
5 | "content": "Sed ante. Vivamus tortor. Duis mattis egestas metus.\n\nAenean fermentum. Donec ut mauris eget massa tempor convallis. Nulla neque libero, convallis eget, eleifend luctus, ultricies eu, nibh.\n\nQuisque id justo sit amet sapien dignissim vestibulum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla dapibus dolor vel est. Donec odio justo, sollicitudin ut, suscipit a, feugiat et, eros.\n\nVestibulum ac est lacinia nisi venenatis tristique. Fusce congue, diam id ornare imperdiet, sapien urna pretium nisl, ut volutpat sapien arcu sed augue. Aliquam erat volutpat.\n\nIn congue. Etiam justo. Etiam pretium iaculis justo.\n\nIn hac habitasse platea dictumst. Etiam faucibus cursus urna. Ut tellus.\n\nNulla ut erat id mauris vulputate elementum. Nullam varius. Nulla facilisi.",
6 | "image": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/450744/simone-hutsch.jpg",
7 | "meta": {
8 | "description": "Vivamus vestibulum sagittis sapien. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.",
9 | "published": "2017-05-27T00:05:26Z",
10 | "author": "Tommi Filipson"
11 | }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/static/icons/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/static/icons/android-chrome-192x192.png
--------------------------------------------------------------------------------
/static/icons/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/static/icons/android-chrome-512x512.png
--------------------------------------------------------------------------------
/static/icons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/static/icons/apple-touch-icon.png
--------------------------------------------------------------------------------
/static/icons/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #408c71
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/static/icons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/static/icons/favicon-16x16.png
--------------------------------------------------------------------------------
/static/icons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/static/icons/favicon-32x32.png
--------------------------------------------------------------------------------
/static/icons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/static/icons/favicon.ico
--------------------------------------------------------------------------------
/static/icons/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Vue Proto",
3 | "icons": [
4 | {
5 | "src": "/static/icons/android-chrome-192x192.png",
6 | "sizes": "192x192",
7 | "type": "image/png"
8 | },
9 | {
10 | "src": "/static/icons/android-chrome-512x512.png",
11 | "sizes": "512x512",
12 | "type": "image/png"
13 | }
14 | ],
15 | "theme_color": "#408c71",
16 | "background_color": "#408c71",
17 | "display": "standalone"
18 | }
--------------------------------------------------------------------------------
/static/icons/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmicjs/vue-blog-netlify-template/ac6baef822974cfe2f88e54b16e7b653077965d3/static/icons/mstile-150x150.png
--------------------------------------------------------------------------------
/static/icons/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 | Created by potrace 1.11, written by Peter Selinger 2001-2013
9 |
10 |
12 |
82 |
83 |
84 |
--------------------------------------------------------------------------------