Implemented loading custom CSS and templates, implemented google analytics
This commit is contained in:
parent
9fb8eada9f
commit
ae5d23bd2c
11 changed files with 159 additions and 13 deletions
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "laine",
|
||||
"version": "0.0.0",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"components-bootstrap": "~3.1.1",
|
||||
|
|
|
@ -38,7 +38,8 @@ var requireJsRuntimeConfig = vm.runInNewContext(fs.readFileSync('src/app/require
|
|||
'components/year-page/year-page',
|
||||
'components/month-page/month-page',
|
||||
'components/post-page/post-page',
|
||||
'components/config-service/config-service'
|
||||
'components/config-service/config-service',
|
||||
'components/template-service/template-service'
|
||||
],
|
||||
insertRequire: ['app/startup'],
|
||||
bundles: {
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
define(["knockout", "crossroads", "hasher", "./routes"], function(ko, crossroads, hasher, routes) {
|
||||
define(
|
||||
[
|
||||
"knockout",
|
||||
"crossroads",
|
||||
"hasher",
|
||||
"./routes",
|
||||
"../components/config-service/config-service",
|
||||
"../components/ga-service/ga-service"
|
||||
], function(ko, crossroads, hasher, routes, configService, gaService) {
|
||||
|
||||
// This module configures crossroads.js, a routing library. If you prefer, you
|
||||
// can use any other routing library (or none at all) as Knockout is designed to
|
||||
|
@ -14,6 +22,8 @@ define(["knockout", "crossroads", "hasher", "./routes"], function(ko, crossroads
|
|||
|
||||
function Router(config) {
|
||||
var currentRoute = this.currentRoute = ko.observable({});
|
||||
this.crossroads = crossroads;
|
||||
this.hasher = hasher;
|
||||
|
||||
ko.utils.arrayForEach(config.routes, function(route) {
|
||||
var addedRoute = crossroads.addRoute(route.url, function(requestParams) {
|
||||
|
@ -29,7 +39,15 @@ define(["knockout", "crossroads", "hasher", "./routes"], function(ko, crossroads
|
|||
}
|
||||
|
||||
function activateCrossroads() {
|
||||
function parseHash(newHash, oldHash) { crossroads.parse(newHash); }
|
||||
function parseHash(newHash, oldHash) {
|
||||
crossroads.parse(newHash);
|
||||
|
||||
// Send google analytics page event if it's enabled
|
||||
if (configService.useGa) {
|
||||
gaService.sendPageEvent();
|
||||
}
|
||||
}
|
||||
|
||||
crossroads.normalizeFn = crossroads.NORM_AS_OBJECT;
|
||||
hasher.prependHash = '!';
|
||||
hasher.initialized.add(parseHash);
|
||||
|
|
|
@ -61,7 +61,3 @@ define([], function() {
|
|||
}
|
||||
];
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -32,6 +32,10 @@ define(['jquery', 'knockout', './router', 'marked', 'bootstrap', 'knockout-proje
|
|||
|
||||
ko.components.register('config-service', { require: 'components/config-service/config-service' });
|
||||
|
||||
ko.components.register('template-service', { require: 'components/template-service/template-service' });
|
||||
|
||||
ko.components.register('ga-service', { require: 'components/ga-service/ga-service' });
|
||||
|
||||
// [Scaffolded component registrations will be inserted here. To retain this feature, don't remove this comment.]
|
||||
|
||||
// Set Markdown parser options
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
define(['knockout', '../../app/routes', '../../app/router', 'hasher'],
|
||||
function(ko, routes, router, hasher) {
|
||||
define(['knockout'],
|
||||
function(ko) {
|
||||
|
||||
function ConfigService() {
|
||||
var self = this;
|
||||
|
@ -9,6 +9,18 @@ define(['knockout', '../../app/routes', '../../app/router', 'hasher'],
|
|||
|
||||
document.title = self.blogName;
|
||||
self.baseTitle = self.blogName;
|
||||
|
||||
// Load custom CSS if specified
|
||||
if (self.customCss) {
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
var link = document.createElement('link');
|
||||
link.id = 'laine-custom-css';
|
||||
link.rel = 'stylesheet';
|
||||
link.type = 'text/css';
|
||||
link.href = self.customCss;
|
||||
link.media = 'all';
|
||||
head.appendChild(link);
|
||||
}
|
||||
}
|
||||
|
||||
// This runs when the component is torn down. Put here any logic necessary to clean up,
|
||||
|
|
34
src/components/ga-service/ga-service.js
Normal file
34
src/components/ga-service/ga-service.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
define(
|
||||
[
|
||||
'knockout',
|
||||
'../config-service/config-service'
|
||||
], function(ko, configService) {
|
||||
|
||||
function GaService() {
|
||||
var self = this;
|
||||
|
||||
// The GA object that can be used in other components
|
||||
self.ga = null;
|
||||
|
||||
if (configService.useGa) {
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', configService.webPropertyID, 'auto');
|
||||
self.ga = ga;
|
||||
}
|
||||
|
||||
self.sendPageEvent = function() {
|
||||
self.ga('send', 'pageview');
|
||||
};
|
||||
}
|
||||
|
||||
// This runs when the component is torn down. Put here any logic necessary to clean up,
|
||||
// for example cancelling setTimeouts or disposing Knockout subscriptions/computeds.
|
||||
GaService.prototype.dispose = function() { };
|
||||
|
||||
return new GaService();
|
||||
|
||||
});
|
|
@ -1,4 +1,10 @@
|
|||
define(['knockout', '../db/db'], function(ko, DB) {
|
||||
define(
|
||||
[
|
||||
'knockout',
|
||||
'../db/db',
|
||||
'../config-service/config-service',
|
||||
'../template-service/template-service'
|
||||
], function(ko, DB, configService, templateService) {
|
||||
|
||||
function GenericRoute() {
|
||||
var self = this;
|
||||
|
@ -14,6 +20,16 @@ define(['knockout', '../db/db'], function(ko, DB) {
|
|||
page(parseInt(route.pageNumber, 10));
|
||||
}
|
||||
}
|
||||
|
||||
self.resolveTemplate = function(originalTemplate, templateName) {
|
||||
if (templateName in configService.customTemplates
|
||||
&& configService.customTemplates[templateName]) {
|
||||
return templateService.loadTemplate(templateName, configService.customTemplates[templateName]);
|
||||
}
|
||||
else {
|
||||
return originalTemplate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This runs when the component is torn down. Put here any logic necessary to clean up,
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
define(['knockout', 'text!./home.html', '../generic-route/generic-route', '../db/db'],
|
||||
define(
|
||||
[
|
||||
'knockout',
|
||||
'text!./home.html',
|
||||
'../generic-route/generic-route',
|
||||
'../db/db'
|
||||
],
|
||||
function(ko, templateMarkup, GR, DB) {
|
||||
|
||||
function HomePage(route) {
|
||||
|
@ -15,6 +21,8 @@ define(['knockout', 'text!./home.html', '../generic-route/generic-route', '../db
|
|||
// for example cancelling setTimeouts or disposing Knockout subscriptions/computeds.
|
||||
HomePage.prototype.dispose = function() {};
|
||||
|
||||
templateMarkup = GR.resolveTemplate(templateMarkup, 'home');
|
||||
|
||||
return { viewModel: HomePage, template: templateMarkup };
|
||||
|
||||
});
|
||||
|
|
32
src/components/template-service/template-service.js
Normal file
32
src/components/template-service/template-service.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
define(['knockout'], function(ko) {
|
||||
|
||||
function TemplateService() {
|
||||
var self = this;
|
||||
|
||||
self.templateStore = {};
|
||||
|
||||
self.loadTemplate = function(templateName, templateUrl) {
|
||||
if (templateName in self.templateStore) {
|
||||
return self.templateStore[templateName];
|
||||
}
|
||||
else {
|
||||
var html = $.ajax(templateUrl, {
|
||||
// We need to set async false to receive the template before rendering
|
||||
// starts
|
||||
async: false,
|
||||
dataType: 'html'
|
||||
}).responseText;
|
||||
|
||||
self.templateStore[templateName] = html;
|
||||
return html;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// This runs when the component is torn down. Put here any logic necessary to clean up,
|
||||
// for example cancelling setTimeouts or disposing Knockout subscriptions/computeds.
|
||||
TemplateService.prototype.dispose = function() { };
|
||||
|
||||
return new TemplateService();
|
||||
|
||||
});
|
|
@ -18,5 +18,30 @@ LAINE_CONFIG = {
|
|||
pageCommenting: false,
|
||||
|
||||
// Posts shown per page
|
||||
postsPerPage: 5
|
||||
postsPerPage: 5,
|
||||
|
||||
|
||||
// GOOGLE ANALYTICS
|
||||
useGa: false, // Set to true to use Google Analytics
|
||||
webPropertyID: '', // Your Google Analytics UA-XXXX-Y code
|
||||
|
||||
|
||||
|
||||
// CUSTOM TEMPLATE AND CSS OVERRIDES
|
||||
|
||||
// To load a custom CSS file, insert the file name below
|
||||
customCss: '',
|
||||
|
||||
// To replace builtin templates with custom teplates, insert the file names
|
||||
// below in the correct places. The paths should be relative to the
|
||||
// index.html path.
|
||||
customTemplates: {
|
||||
navbar: '', // Navigation bar
|
||||
home: '', // Home page
|
||||
post: '', // Single post/page
|
||||
pagination: '', // A list of posts with included pagination
|
||||
year: '', // Year archives
|
||||
month: '', // Month archives
|
||||
tag: '' // Tag archives
|
||||
}
|
||||
};
|
||||
|
|
Reference in a new issue