Skip to content

Commit 910793c

Browse files
committed
Adds helpful comments throughout the app.
1 parent 112ee4b commit 910793c

File tree

8 files changed

+119
-8
lines changed

8 files changed

+119
-8
lines changed

site.config.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,16 @@ module.exports = {
1414
twitterCard: "summary_large_image",
1515
twitterCreator: "@your_twitter_username",
1616

17+
/**
18+
* If you set a `facebook_id` then we will initialize facebook comments and likes
19+
* The `facebook_id` is the App ID you would normally use in the meta tag
20+
* ```html
21+
* <meta property="fb:app_id" content="[[facebook_id]]"/>
22+
* ````
23+
*/
1724
facebook_id: null,
25+
26+
1827
googleAnalyticsId: "",
1928
mailChimpUrl: "",
2029

the-magic/boot/async-data.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* Runs client side only
3+
* Before the component mounts or updates it's route, we want to finish running any requied AJAX requests that the component may depend on to load
4+
*/
5+
16
import Vue from "vue";
27

38
Vue.mixin({

the-magic/boot/entry-server.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/**
22
* Runs on server only
3+
* When our `/the-magic/build/build.js` or `/the-magic/build/server.js` attempt to render our Vue and Markdown files into raw HTML files at `renderer.renderToString()` for better SEO, it critically depends on this file to determine which files to render for a given route, to load all necessary subcomponents for that route and render each, and add any data from our server side AJAX requests that need to be embedded in the raw HTML file. If the store is modified, we also need to deliver a copy of that state to the renderer so the client will initialize it's store in the same condition.
34
*/
45

56
import Vue from "vue";
@@ -12,16 +13,29 @@ import colors from 'colors';
1213
global.fetch = require("node-fetch")
1314

1415
export default context => {
16+
17+
/**
18+
* It's ok to return a promise to the renderer
19+
*/
1520
return new Promise((resolve, reject) => {
1621

1722
let { store, app, router } = require(`./index.js`).default;
1823

24+
/**
25+
* Initialize Vue-Meta
26+
*/
1927
const meta = app.$meta();
2028

2129
Object.assign(store, context);
2230

31+
/**
32+
* The `context` argument provides the url the user is attempting to access in the browser with `context.file.url`. We tell the router to load this route and all it's necessary subcomponents
33+
*/
2334
router.push(context.file.url);
2435

36+
/**
37+
* We wait for the router to finish loading all necessary components to this route
38+
*/
2539
router.onReady(() => {
2640
let matchedComponents = router.getMatchedComponents();
2741

@@ -30,10 +44,16 @@ export default context => {
3044
return reject(colors.red(`${context.file.url}`) + colors.grey(` from `) + colors.red(context.file.path.replace(__dirname, '')) + colors.grey(` is not routed to any vue templates. Match a vue template to this url in the ` + colors.green(`site.config.js`) + ` routes.\n\r`)
3145
);
3246
}
33-
// call `asyncData()` on all matched route components
47+
48+
/**
49+
* For every subcomponent for this route, we check if any of them require AJAX requests to be run and completed before we render. This is helpful in the case that you want to fetch some data at the moment the user or Search Engine Bot load the page and embed the results in the rendered HTML file
50+
* We provide each `asyncData()` function the store and current route in case that information is needed for making the AJAX request
51+
*/
3452
Promise.all(
3553
matchedComponents.map(Component => {
3654
if (Component.options.asyncData) {
55+
56+
// call `asyncData()` on all matched route components
3757
return Component.options.asyncData({
3858
store,
3959
route: router.currentRoute
@@ -42,7 +62,14 @@ export default context => {
4262
})
4363
)
4464
.then(() => {
65+
/**
66+
* AJAX requests or loading the components may have modified our server-side store. It's critical that the server rendering fully matches the client-side rendering on the each's initial render and to have matching pages the store needs to be in the same state on the client and server. Therefore, since our basic store may have been modified by our server-side rendering process, we need to provide the modifications to the context so the client can initialize it's store with the state the server renderer left it in.
67+
*/
4568
context.state = store;
69+
70+
/**
71+
* We also need to provide our meta data rendered by Vue-Meta to our context object so we can inject these tags into our rendered HTML
72+
*/
4673
context.meta = meta;
4774
resolve(app);
4875
})

the-magic/boot/facebook-social.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import Vue from "vue";
22
import config from "config";
33

4+
/**
5+
* We only want to enable facebook comments if we are client-side and we haven't already initialized this script
6+
*/
47
if (!Vue.prototype.$isServer && !window.fbAsyncInit) {
8+
9+
/**
10+
* If you run `enableComments()` in your code it will download the remote facebook script to enable facebook comments and likes on your pages
11+
*/
512
window.enableComments = function() {
613
(function(d, s, id) {
714
var js,
@@ -27,6 +34,9 @@ if (!Vue.prototype.$isServer && !window.fbAsyncInit) {
2734
xfbml: true //Look for social plugins on the page
2835
});
2936

37+
/**
38+
* If Google Analytics is loaded, we want to track if the user is logged in, if they liked/unliked, commented on, or shared a post
39+
*/
3040
if(typeof ga !== 'undefined') {
3141
// //Logged In Users
3242
FB.getLoginStatus(function(response) {

the-magic/boot/index.js

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,36 @@ import meta_tags from './meta-tags.js';
1313

1414
Vue.config.productionTip = false;
1515

16+
/**
17+
* Make our store, router, and site.config.js (`config`) global so it can be used instantly in any of our templates, js files or components
18+
*/
1619
global.store = store
1720
global.router = router
1821
global.config = config
1922

2023
/**
21-
* This is our config.folderStructure.css entry file
24+
* This is our config.folderStructure.css entry file in `/site.config.js`
2225
*/
2326
require(main_css);
2427

2528
/**
26-
* This is our config.folderStructure.vue entry file
29+
* This is our `config.folderStructure.vue` entry file in `/site.config.js`
2730
*/
2831
let Root = require(main_vue).default;
2932

3033
Root = Object.assign({}, {
34+
35+
/**
36+
* We assign our default meta tags in `./meta-tags.js` to our root component
37+
*/
3138
metaInfo() {
3239
return meta_tags
3340
},
3441
}, Root);
3542

43+
/**
44+
* Here we construct the root component and connect the Vue-Stash Store and Vue-Router
45+
*/
3646
global.app = new Vue(
3747
Object.assign(
3848
{
@@ -44,25 +54,45 @@ global.app = new Vue(
4454
);
4555

4656
/**
47-
* This is our config.folderStructure.js entry file
57+
* This is our config.folderStructure.js entry file from `/site.config.js`
4858
*/
4959
require(main_js);
5060

51-
// Check if user is logged in then launch the app unless we are rendering from the server
61+
5262
if (Vue.prototype.$isServer) {
63+
/**
64+
* If we are rendering the component on the server we simply want to mount the root component without loading any server-side scripts
65+
*/
5366
app.$mount("#app");
5467
} else {
68+
69+
/**
70+
* If we are rendering the root component on the client, we want to first complete any ajax requests and include their data in our rendered templates
71+
*/
5572
require("./async-data");
5673

74+
/**
75+
* If the user has set `googleAnalyticsId` in `/site.config.js` and we are rendering client-side we want to load our `./analytics.js` script
76+
*/
5777
if(global.config.googleAnalyticsId) {
5878
require("./analytics.js")
5979
}
6080

81+
/**
82+
* If the user has set a `facebook_id` in `/site.config.js` then we want to initialize facebook comments and likes
83+
* The `facebook_id` is the App ID you would normally use in the meta tag
84+
* ```html
85+
* <meta property="fb:app_id" content="[[facebook_id]]"/>
86+
* ````
87+
*/
6188
if(global.config.facebook_id) {
6289
require("./facebook-social.js")
6390
}
64-
// Don't hydrate site if google bot is visiting because it may take the screen shot during the hydration phase when ajax content isn't present
91+
6592
app.$mount("#app");
6693
}
6794

95+
/**
96+
* It's important that we export the our root component, router, and store
97+
*/
6898
export default { app, router, store };

the-magic/boot/meta-tags.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* To save a lot of typing in the developer's templates, we set the default meta tag configuration for the root object
3+
* These properties can be overridden in subroutes
4+
*/
5+
16
import config from 'config';
27

38
export default {

the-magic/boot/router.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import config from "config";
55
import camelCase from "lodash.camelcase";
66

77
/**
8-
* Make our individual templates and partials available globally
8+
* `the-magic/build/gulpfile.js` will automatically inject `.vue` files located in the specified `components` and `partials` folder paths (See `/site.config.js`) into this `components` constant between the comments:
9+
* // globalize vue components
10+
* and
11+
* // end globalize vue components
12+
* This makes our components available globally under the camelCase version of the file-name (without the extension)
913
*/
1014
const components = {
1115
// globalize vue components
@@ -20,7 +24,7 @@ const components = {
2024
};
2125

2226
/**
23-
* Take routes in /site.config.js and attach the named components to them
27+
* Takes the routes and their matching `string` component names in `/site.config.js`` and replaces with string with the component using the same name
2428
*/
2529
const routes = config.routes
2630
.map(route => {
@@ -45,6 +49,7 @@ const router = new VueRouter({
4549

4650
/**
4751
* Here is where you determine scroll position for the page you navigate to
52+
* We are returning the scroll position to the top of the page between scrolls
4853
*/
4954
resolve({x: 0, y: 0})
5055
})

the-magic/boot/store-reconciliation.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,42 @@ const defaultStore = config.store;
99

1010
let store = defaultStore;
1111

12+
/**
13+
* When our Vue and Markdown files are rendered into HTML, Server-Side Rendering will save the server-side rendered state of the store to the variable `window.__INITIAL_STATE__`
14+
* We want to set our client-side store to initialize with whatever is in this variable, so the server and client store will be in sync
15+
*/
1216
try {
1317
if (typeof window !== "undefined" && window.__INITIAL_STATE__) {
1418
store = window.__INITIAL_STATE__;
1519
}
1620
} catch (err) {}
1721

22+
23+
/**
24+
* Before loading the URL, finding the markdown file matching that URL and set the markdown's rendered HTML and metadata object as the `file` property of the store. If a markdown file cannot be found, then load a 404 page
25+
*/
1826
router.beforeEach((to, from, next) => {
1927
let path = to.path.replace('.html', '').replace('.htm', '');
2028
const found = store.files.find(post => post.url === path);
29+
30+
/**
31+
* Setting `postBodyEl` will enable scroll tracking with Google Analytics on a page.
32+
* Scrolling tracking is how we determine if the article was completely read (the user reaches the bottom of the article content).
33+
* We want to reset this value between pages in case there's a page that we don't want to track
34+
*/
2135
if(typeof postBodyEl !== 'undefined') {
2236
global.postBodyEl = null;
2337
}
38+
2439
if (!found) {
2540
router.replace("/404");
2641
} else {
42+
2743
store.file = found;
44+
45+
/**
46+
* `social_url` is used for matching Facebook Comments and Likes to the current page in the `:data-href="$store.social_url"` attribute
47+
*/
2848
store.social_url = config.site_url + store.file.url;
2949
}
3050
next();

0 commit comments

Comments
 (0)