67 |
68 | 6. Start the API server (in the project's /core/server directory)
69 |
70 |
swagger project start
71 |
72 | 7. View the Swagger UI:
73 |
74 |
http://localhost:10010/docs
75 |
76 | **Note:** Edit the API (/core/server/api/swagger/swagger.yaml):
77 |
78 | swagger project edit
79 |
80 | 
81 |
82 | #### Copyright & License
83 |
84 | Copyright (c) 2015-2017 The Vardyger Foundation - Released under the MIT license.
85 |
--------------------------------------------------------------------------------
/content/README.md:
--------------------------------------------------------------------------------
1 | Place your themes in the themes directory.
--------------------------------------------------------------------------------
/content/assets/swagger-editor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinyo/Vardyger/f04cc2cf1a86296c61e82d4dfb38e8ade9912c13/content/assets/swagger-editor.png
--------------------------------------------------------------------------------
/content/assets/vardyger-admin-ui-content.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinyo/Vardyger/f04cc2cf1a86296c61e82d4dfb38e8ade9912c13/content/assets/vardyger-admin-ui-content.png
--------------------------------------------------------------------------------
/content/assets/vardyger-admin-ui-editor-markdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinyo/Vardyger/f04cc2cf1a86296c61e82d4dfb38e8ade9912c13/content/assets/vardyger-admin-ui-editor-markdown.png
--------------------------------------------------------------------------------
/content/assets/vardyger-admin-ui-editor-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinyo/Vardyger/f04cc2cf1a86296c61e82d4dfb38e8ade9912c13/content/assets/vardyger-admin-ui-editor-preview.png
--------------------------------------------------------------------------------
/content/assets/vardyger-admin-ui-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinyo/Vardyger/f04cc2cf1a86296c61e82d4dfb38e8ade9912c13/content/assets/vardyger-admin-ui-preview.png
--------------------------------------------------------------------------------
/content/assets/vardyger-admin-ui-side-menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinyo/Vardyger/f04cc2cf1a86296c61e82d4dfb38e8ade9912c13/content/assets/vardyger-admin-ui-side-menu.png
--------------------------------------------------------------------------------
/content/assets/vardyger-admin-ui-welcome-de.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinyo/Vardyger/f04cc2cf1a86296c61e82d4dfb38e8ade9912c13/content/assets/vardyger-admin-ui-welcome-de.png
--------------------------------------------------------------------------------
/content/assets/vardyger-admin-ui-welcome-en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinyo/Vardyger/f04cc2cf1a86296c61e82d4dfb38e8ade9912c13/content/assets/vardyger-admin-ui-welcome-en.png
--------------------------------------------------------------------------------
/content/assets/vardyger-api.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinyo/Vardyger/f04cc2cf1a86296c61e82d4dfb38e8ade9912c13/content/assets/vardyger-api.png
--------------------------------------------------------------------------------
/content/assets/vardyger-post.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinyo/Vardyger/f04cc2cf1a86296c61e82d4dfb38e8ade9912c13/content/assets/vardyger-post.png
--------------------------------------------------------------------------------
/content/themes/README.md:
--------------------------------------------------------------------------------
1 | Place your themes in this directory.
--------------------------------------------------------------------------------
/content/themes/casper/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013-2015 Ghost Foundation
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/content/themes/casper/README.md:
--------------------------------------------------------------------------------
1 | # Casper
2 |
3 | The default theme for [Ghost](http://github.com/tryghost/ghost/).
4 |
5 | To download, visit the [releases](https://github.com/TryGhost/Casper/releases) page.
6 |
7 | ## Copyright & License
8 |
9 | Copyright (c) 2013-2015 Ghost Foundation - Released under the MIT License.
10 |
11 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17 |
--------------------------------------------------------------------------------
/content/themes/casper/assets/fonts/casper-icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinyo/Vardyger/f04cc2cf1a86296c61e82d4dfb38e8ade9912c13/content/themes/casper/assets/fonts/casper-icons.eot
--------------------------------------------------------------------------------
/content/themes/casper/assets/fonts/casper-icons.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/content/themes/casper/assets/fonts/casper-icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinyo/Vardyger/f04cc2cf1a86296c61e82d4dfb38e8ade9912c13/content/themes/casper/assets/fonts/casper-icons.ttf
--------------------------------------------------------------------------------
/content/themes/casper/assets/fonts/casper-icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinyo/Vardyger/f04cc2cf1a86296c61e82d4dfb38e8ade9912c13/content/themes/casper/assets/fonts/casper-icons.woff
--------------------------------------------------------------------------------
/content/themes/casper/assets/js/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Main JS file for Casper behaviours
3 | */
4 |
5 | /* globals jQuery, document */
6 | (function ($, undefined) {
7 | "use strict";
8 |
9 | var $document = $(document);
10 |
11 | $document.ready(function () {
12 |
13 | var $postContent = $(".post-content");
14 | $postContent.fitVids();
15 |
16 | $(".scroll-down").arctic_scroll();
17 |
18 | $(".menu-button, .nav-cover, .nav-close").on("click", function(e){
19 | e.preventDefault();
20 | $("body").toggleClass("nav-opened nav-closed");
21 | });
22 |
23 | });
24 |
25 | // Arctic Scroll by Paul Adam Davis
26 | // https://github.com/PaulAdamDavis/Arctic-Scroll
27 | $.fn.arctic_scroll = function (options) {
28 |
29 | var defaults = {
30 | elem: $(this),
31 | speed: 500
32 | },
33 |
34 | allOptions = $.extend(defaults, options);
35 |
36 | allOptions.elem.click(function (event) {
37 | event.preventDefault();
38 | var $this = $(this),
39 | $htmlBody = $('html, body'),
40 | offset = ($this.attr('data-offset')) ? $this.attr('data-offset') : false,
41 | position = ($this.attr('data-position')) ? $this.attr('data-position') : false,
42 | toMove;
43 |
44 | if (offset) {
45 | toMove = parseInt(offset);
46 | $htmlBody.stop(true, false).animate({scrollTop: ($(this.hash).offset().top + toMove) }, allOptions.speed);
47 | } else if (position) {
48 | toMove = parseInt(position);
49 | $htmlBody.stop(true, false).animate({scrollTop: toMove }, allOptions.speed);
50 | } else {
51 | $htmlBody.stop(true, false).animate({scrollTop: ($(this.hash).offset().top) }, allOptions.speed);
52 | }
53 | });
54 |
55 | };
56 | })(jQuery);
57 |
--------------------------------------------------------------------------------
/content/themes/casper/assets/js/jquery.fitvids.js:
--------------------------------------------------------------------------------
1 | /*global jQuery */
2 | /*jshint browser:true */
3 | /*!
4 | * FitVids 1.1
5 | *
6 | * Copyright 2013, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com
7 | * Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/
8 | * Released under the WTFPL license - http://sam.zoy.org/wtfpl/
9 | *
10 | */
11 |
12 | (function( $ ){
13 |
14 | "use strict";
15 |
16 | $.fn.fitVids = function( options ) {
17 | var settings = {
18 | customSelector: null
19 | };
20 |
21 | if(!document.getElementById('fit-vids-style')) {
22 | // appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js
23 | var head = document.head || document.getElementsByTagName('head')[0];
24 | var css = '.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}';
25 | var div = document.createElement('div');
26 | div.innerHTML = '
x
';
27 | head.appendChild(div.childNodes[1]);
28 | }
29 |
30 | if ( options ) {
31 | $.extend( settings, options );
32 | }
33 |
34 | return this.each(function(){
35 | var selectors = [
36 | "iframe[src*='player.vimeo.com']",
37 | "iframe[src*='youtube.com']",
38 | "iframe[src*='youtube-nocookie.com']",
39 | "iframe[src*='kickstarter.com'][src*='video.html']",
40 | "object",
41 | "embed"
42 | ];
43 |
44 | if (settings.customSelector) {
45 | selectors.push(settings.customSelector);
46 | }
47 |
48 | var $allVideos = $(this).find(selectors.join(','));
49 | $allVideos = $allVideos.not("object object"); // SwfObj conflict patch
50 |
51 | $allVideos.each(function(){
52 | var $this = $(this);
53 | if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; }
54 | var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(),
55 | width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(),
56 | aspectRatio = height / width;
57 | if(!$this.attr('id')){
58 | var videoID = 'fitvid' + Math.floor(Math.random()*999999);
59 | $this.attr('id', videoID);
60 | }
61 | $this.wrap('').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+"%");
62 | $this.removeAttr('height').removeAttr('width');
63 | });
64 | });
65 | };
66 | // Works with either jQuery or Zepto
67 | })( window.jQuery || window.Zepto );
68 |
--------------------------------------------------------------------------------
/content/themes/casper/author.hbs:
--------------------------------------------------------------------------------
1 | {{!< default}}
2 | {{! The tag above means - insert everything in this file into the {body} of the default.hbs template }}
3 |
4 | {{! The big featured header }}
5 |
6 | {{! Everything inside the #author tags pulls data from the author }}
7 | {{#author}}
8 |
9 |
15 |
16 |
17 |
18 | {{#if image}}
19 |
20 |
52 |
53 | {{! Ghost outputs important scripts and data with this tag }}
54 | {{ghost_foot}}
55 |
56 | {{! The main JavaScript file for Casper }}
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/content/themes/casper/index.hbs:
--------------------------------------------------------------------------------
1 | {{!< default}}
2 | {{! The tag above means - insert everything in this file into the {body} of the default.hbs template }}
3 |
4 | {{! The big featured header }}
5 |
6 |
12 |
13 |
14 |
{{@blog.title}}
15 |
{{@blog.description}}
16 |
17 |
18 | Scroll Down
19 |
20 |
21 | {{! The main content area on the homepage }}
22 |
23 |
24 | {{! The tag below includes the post loop - partials/loop.hbs }}
25 | {{> "loop"}}
26 |
27 |
28 |
--------------------------------------------------------------------------------
/content/themes/casper/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Casper",
3 | "version": "1.2.4"
4 | }
5 |
--------------------------------------------------------------------------------
/content/themes/casper/page.hbs:
--------------------------------------------------------------------------------
1 | {{!< default}}
2 |
3 | {{! This is a page template. A page outputs content just like any other post, and has all the same
4 | attributes by default, but you can also customise it to behave differently if you prefer. }}
5 |
6 | {{! Everything inside the #post tags pulls data from the page }}
7 | {{#post}}
8 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
',
143 | markdown: 'In a previous post, ...'
144 | }
145 | },
146 |
147 | {
148 | metaTitle: 'Customising Ionic with Sass',
149 | metaDescription: 'In a previous post, ...',
150 | post: {
151 | id: '2',
152 | title: 'Customising Ionic with Sass',
153 | html: '
In a previous post, ...
',
154 | markdown: 'In a previous post, ...'
155 | }
156 | },
157 |
158 | {
159 | metaTitle: 'Ionic, Angular and Cordova',
160 | metaDescription: 'In a previous post, ...',
161 | post: {
162 | id: '3',
163 | title: 'Ionic, Angular and Cordova',
164 | html: '
In a previous post, ...
',
165 | markdown: 'In a previous post, ...'
166 | }
167 | },
168 |
169 | {
170 | metaTitle: 'Annotating JavaScript using JSDoc tags',
171 | metaDescription: 'In a previous post, ...',
172 | post: {
173 | id: '4',
174 | title: 'Annotating JavaScript using JSDoc tags',
175 | html: '
In a previous post, ...
',
176 | markdown: 'In a previous post, ...'
177 | }
178 | },
179 |
180 | {
181 | metaTitle: 'Express, Handlebars and Ghost Themes',
182 | metaDescription: 'In a previous post, ...',
183 | post: {
184 | id: '5',
185 | title: 'Express, Handlebars and Ghost Themes',
186 | html: '
In a previous post, ...
',
187 | markdown: 'In a previous post, ...'
188 | }
189 | },
190 |
191 | {
192 | metaTitle: 'Swagger, Express, and Content Negotiation',
193 | metaDescription: 'In a previous post, ...',
194 | post: {
195 | id: '6',
196 | title: 'Swagger, Express, and Content Negotiation',
197 | html: '
In a previous post, ...
',
198 | markdown: 'In a previous post, ...'
199 | }
200 | },
201 |
202 | {
203 | metaTitle: 'The Vardyger publishing platform :)',
204 | metaDescription: 'In a previous post, ...',
205 | post: {
206 | id: '7',
207 | title: 'The Vardyger publishing platform :)',
208 | html: '
In a previous post, ...
',
209 | markdown: 'In a previous post, ...'
210 | }
211 | }
212 |
213 | ];
214 |
215 | /* jshint ignore:start */
216 |
217 | // GET /vardyger/api/v1.0/posts or 401
218 | $httpBackend.whenGET('https://posts').respond(function (method, url, data, headers) {
219 | var authToken = localStorageService.get('authorizationToken');
220 | return authToken ? [200, posts] : [401];
221 | });
222 |
223 | $httpBackend.whenPOST('https://login').respond(function(method, url, data) {
224 | var authToken = 'NjMwNjM4OTQtMjE0Mi00ZWYzLWEzMDQtYWYyMjkyMzNiOGIy';
225 | return [200 , { authorizationToken: authToken } ];
226 | });
227 |
228 | $httpBackend.whenPOST('https://logout').respond(function(method, url, data) {
229 | return [200];
230 | });
231 |
232 | $httpBackend.whenGET(/.*/).passThrough();
233 |
234 | /* jshint ignore:end */
235 |
236 | });
237 |
238 |
239 | // Code here will be linted with JSHint.
240 | /* jshint ignore:start */
241 | // Code here will be ignored by JSHint.
242 | /* jshint ignore:end */
243 |
244 | // You can also ignore a single line with a trailing comment like this:
245 | // ignoreThis(); // jshint ignore:line
246 |
247 | /*
248 |
249 | // .useStorage();
250 |
251 | */
252 |
--------------------------------------------------------------------------------
/core/client/app/scripts/config/config.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Vardyger
3 | * Copyright(c) 2015 Rob Ferguson
4 | * MIT Licensed
5 | */
6 |
7 | 'use strict';
8 |
9 | angular.module('config', [])
10 | .constant('ENV', {
11 | name:'development',
12 | apiEndpoint:'http://dev.yoursite.com:10000/'
13 | });
14 |
15 |
--------------------------------------------------------------------------------
/core/client/app/scripts/controllers/app-controller.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Vardyger
3 | * Copyright(c) 2015 Rob Ferguson
4 | * MIT Licensed
5 | */
6 |
7 | 'use strict';
8 |
9 | /*
10 | * Dependency Injection Syntax and AngularJS
11 | * The notation that we have used is one of the two ways in which we can declare AngularJS controllers
12 | * (or services, directives, or filters). The style we have used, which is also the recommended way,
13 | * is the safe-style of Dependency Injection, or declaration.
14 | */
15 |
16 | angular.module('vardyger')
17 | .controller('AppController', ['$log', '$scope', '$ionicModal', '$translate', 'AuthenticationService',
18 | function(
19 | $log, // inject the $log service
20 | $scope, // inject the $scope service
21 | $ionicModal, // inject the $ionicModal service
22 | $translate, // inject the $translate service
23 | AuthenticationService // inject the AuthenticationService service
24 | ) {
25 |
26 | $log.info('AppController');
27 |
28 | // AuthenticationService.logout();
29 |
30 | $scope.switchLanguage = function(key) {
31 | $log.info('switchLanguage() to ' + key);
32 | $translate.use(key);
33 | };
34 |
35 | // Login / Logout
36 |
37 | $ionicModal.fromTemplateUrl('templates/login-template.html', {
38 | scope: $scope,
39 | animation: 'slide-in-up', // fade-in, reverse, slide-in-up
40 | focusFirstInput: true
41 | }).then(function(modal) {
42 | $scope.loginModal = modal;
43 | });
44 |
45 | $scope.isLoggedIn = function() {
46 | // $log.info('AppController - isLoggedIn()');
47 | return AuthenticationService.isLoggedIn();
48 | };
49 |
50 | $scope.logout = function() {
51 | // $log.info('AppController - logout()');
52 | AuthenticationService.logout();
53 | };
54 |
55 | $scope.$on('$destroy', function() {
56 | $log.info('AppController - $destroy');
57 | $scope.loginModal.remove();
58 | });
59 |
60 | }]);
61 |
62 |
--------------------------------------------------------------------------------
/core/client/app/scripts/controllers/editor-controller.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Vardyger
3 | * Copyright(c) 2015 Rob Ferguson
4 | * MIT Licensed
5 | */
6 |
7 | 'use strict';
8 |
9 | // Reference the 'vardyger' module to attach a controller
10 |
11 | angular.module('vardyger')
12 | .controller('EditorController',
13 | function(
14 | $log, // inject the $log service
15 | $scope, // inject the $scope service
16 | post // inject Post model
17 | ) {
18 |
19 | $log.info('EditorController');
20 |
21 | $scope.item = post;
22 | $scope.preview = false;
23 |
24 | $scope.previewPost = function(flag) {
25 | $scope.preview = flag;
26 | };
27 |
28 | $scope.isPreview = function() {
29 | return $scope.preview;
30 | };
31 |
32 | });
33 |
34 |
--------------------------------------------------------------------------------
/core/client/app/scripts/controllers/login-controller.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Vardyger
3 | * Copyright(c) 2015 Rob Ferguson
4 | * MIT Licensed
5 | */
6 |
7 | 'use strict';
8 |
9 | // Reference the 'vardyger' module to attach a controller
10 |
11 | angular.module('vardyger')
12 | .controller('LoginController',
13 | function(
14 | $log, // inject the $log service
15 | $scope, // inject the $scope service
16 | $http, // inject the $http service
17 | $state, // inject the $state service
18 | AuthenticationService // inject the AuthenticationService service
19 | ) {
20 |
21 | $log.info('LoginController');
22 |
23 | $scope.message = '';
24 |
25 | $scope.credentials = {
26 | grant_type: 'password',
27 | username: null,
28 | password: null,
29 | client_id: 'ghost-admin'
30 | };
31 |
32 | $scope.login = function() {
33 | AuthenticationService.login($scope.credentials);
34 | };
35 |
36 | $scope.$on('event:auth-loginRequired', function(e, rejection) {
37 | $log.info('LoginController - event:auth-loginRequired');
38 | $scope.loginModal.show();
39 | });
40 |
41 | $scope.$on('event:auth-loginConfirmed', function() {
42 | $log.info('LoginController - event:auth-loginConfirmed');
43 | $scope.loginModal.hide();
44 | });
45 |
46 | $scope.$on('event:auth-login-failed', function(e, status) {
47 | $log.info('LoginController - event:auth-login-failed');
48 | var error = 'Login failed.';
49 | if (status === 401) {
50 | error = 'Invalid Username or Password.';
51 | }
52 | $scope.message = error;
53 | });
54 |
55 | $scope.$on('event:auth-logout-complete', function() {
56 | $log.info('LoginController - event:auth-logout-complete');
57 | $state.go('app.welcome');
58 | });
59 |
60 | });
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/core/client/app/scripts/controllers/main-controller.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Vardyger
3 | * Copyright(c) 2015 Rob Ferguson
4 | * MIT Licensed
5 | */
6 |
7 | 'use strict';
8 |
9 | // Reference the 'vardyger' module to attach a controller
10 |
11 | angular.module('vardyger')
12 | .controller('MainController',
13 | function(
14 | $log, // inject the $log service
15 | $scope, // inject the $scope service
16 | $http, // inject the $http service
17 | posts, // inject the resolved posts data
18 | $timeout,
19 | $ionicScrollDelegate
20 | ) {
21 |
22 | $log.info('MainController');
23 |
24 | $scope.listItems = {};
25 |
26 | // Or you can use $state.reload()
27 |
28 | $scope.$on('$ionicView.beforeEnter', function() {
29 | // The view has fully entered and is now the active view.
30 | // This event will fire, whether it was the first load or a cached view.
31 | $log.info('MainController - $ionicView.beforeEnter');
32 |
33 | // $ionicHistory.clearHistory();
34 | });
35 |
36 | // Values on $scope are called models and are also available in views.
37 |
38 | // $scope.listItems = posts;
39 |
40 | $http.get('https://posts')
41 | .success(function (data, status, headers, config) {
42 | $log.info('MainController - $http.get()');
43 |
44 | // $scope.listItems = data;
45 |
46 | // See: http://forum.ionicframework.com/t/ngfx-animation-in-ionic/15176
47 |
48 | for (var i = 0; i < data.length; i++) {
49 | (function() {
50 | var j = i;
51 | $timeout(function(){
52 | $scope.listItems[j] = data[j];
53 | $ionicScrollDelegate.resize();
54 | }, j * 300);
55 | })();
56 | }
57 | })
58 | .error(function (data, status, headers, config) {
59 | $log.error('An error occurred: ' + status);
60 | });
61 |
62 | });
63 |
64 |
--------------------------------------------------------------------------------
/core/client/app/scripts/controllers/preview-controller.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Vardyger
3 | * Copyright(c) 2015 Rob Ferguson
4 | * MIT Licensed
5 | */
6 |
7 | 'use strict';
8 |
9 | // Reference the 'vardyger' module to attach a controller
10 |
11 | angular.module('vardyger')
12 | .controller('PreviewController',
13 | function(
14 | $log, // inject the $log service
15 | $scope, // inject the $scope service
16 | post // inject resolved post data
17 | ) {
18 |
19 | $log.info('PreviewController');
20 |
21 | $scope.item = post;
22 |
23 | // $log.info('$scope.item: ', $scope.item);
24 |
25 | });
26 |
27 | /*
28 |
29 | $scope.editPost = function() {
30 |
31 | $log.info('editPost()');
32 |
33 | // $state.go('app.editor({postId: item.post.id})');
34 |
35 | };
36 |
37 | */
38 |
--------------------------------------------------------------------------------
/core/client/app/scripts/locales/de.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "MAIN_TEMPLATE_TITLE": "Inhalt",
4 | "PREVIEW_TEMPLATE_TITLE": "Vorschau",
5 | "EDITOR_TEMPLATE_TITLE": "Editor",
6 |
7 | "WELCOME": "Willkommen in der Admin UI :)",
8 |
9 | "LOGIN_BUTTON": "EINLOGGEN",
10 | "FORGOTTEN_PASSWORD": "Passwort vergessen?",
11 |
12 | "CONTENT": "Inhalt",
13 | "NEW_POST": "neuer Beitrag",
14 | "SETTINGS": "Einstellungen",
15 | "LOGIN": "Einloggen",
16 | "LOGOUT": "abmelden",
17 |
18 | "ALL_POSTS": "Alle Beiträge",
19 | "NO_POSTS": "keine Einträge :(",
20 | "EDIT": "BEARBEITEN",
21 | "MARKDOWN": "MARKDOWN",
22 | "PREVIEW": "VORSCHAU",
23 | "UPDATE_POST": "UPDATE BEITRAG"
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/core/client/app/scripts/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "MAIN_TEMPLATE_TITLE": "Content",
4 | "PREVIEW_TEMPLATE_TITLE": "Preview",
5 | "EDITOR_TEMPLATE_TITLE": "Editor",
6 |
7 | "WELCOME": "Welcome to the Admin UI :)",
8 |
9 | "LOGIN_BUTTON": "LOG IN",
10 | "FORGOTTEN_PASSWORD": "Forgotten password?",
11 |
12 | "CONTENT": "Content",
13 | "NEW_POST": "New Post",
14 | "SETTINGS": "Settings",
15 | "LOGIN": "Login",
16 | "LOGOUT": "Logout",
17 |
18 | "ALL_POSTS": "ALL POSTS",
19 | "NO_POSTS": "No posts :(",
20 | "EDIT": "EDIT",
21 | "MARKDOWN": "MARKDOWN",
22 | "PREVIEW": "PREVIEW",
23 | "UPDATE_POST": "UPDATE POST"
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/core/client/app/scripts/services/authentication-service.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Vardyger
3 | * Copyright(c) 2015 Rob Ferguson
4 | * MIT Licensed
5 | */
6 |
7 | 'use strict';
8 |
9 | // Reference the 'vardyger' module to attach a factory
10 |
11 | angular.module('vardyger')
12 | .factory('AuthenticationService',
13 | function(
14 | $log, // inject the $log service
15 | $rootScope, // inject the $rootScope service
16 | $http, // inject the $http service
17 | authService, // inject the authService service
18 | localStorageService // inject the localStorageService service
19 | ) {
20 |
21 | $log.info('AuthenticationService');
22 |
23 | var loggedIn = false;
24 |
25 | var service = {
26 |
27 | login: function(credentials) {
28 |
29 | $log.info('AuthenticationService.login()');
30 |
31 | $http.post('https://login', { user: credentials }, { ignoreAuthModule: true })
32 |
33 | .success(function (data, status, headers, config) {
34 |
35 | $log.info('AuthenticationService.login() - success');
36 |
37 | loggedIn = true;
38 |
39 | $http.defaults.headers.common.Authorization = data.authorizationToken;
40 | // A more secure approach would be to store the token in SharedPreferences
41 | // for Android and keychain for iOS
42 | localStorageService.set('authorizationToken', data.authorizationToken);
43 |
44 | // Need to inform the http-auth-interceptor that the user has logged in successfully.
45 | // To do this, we pass in a function that will configure the request headers with the
46 | // authorization token so previously failed requests(aka with status == 401) will be
47 | // resent with the authorization token placed in the header
48 | authService.loginConfirmed(data, function(config) {
49 | config.headers.Authorization = data.authorizationToken;
50 | return config;
51 | });
52 | })
53 |
54 | .error(function (data, status, headers, config) {
55 | $log.info('AuthenticationService.login() - error');
56 | $rootScope.$broadcast('event:auth-login-failed', status);
57 | });
58 | },
59 |
60 | isLoggedIn: function() {
61 | $log.info('AuthenticationService.isLoggedIn()');
62 | return loggedIn;
63 | },
64 |
65 | loginCancelled: function() {
66 | $log.info('loginCancelled()');
67 | authService.loginCancelled();
68 | },
69 |
70 | logout: function() {
71 |
72 | $log.info('AuthenticationService.logout()');
73 |
74 | loggedIn = false;
75 |
76 | $http.post('https://logout', {}, { ignoreAuthModule: true })
77 | .finally(function(data) {
78 | localStorageService.remove('authorizationToken');
79 | delete $http.defaults.headers.common.Authorization;
80 | $rootScope.$broadcast('event:auth-logout-complete');
81 | });
82 | }
83 |
84 | };
85 |
86 | return service;
87 |
88 | });
89 |
--------------------------------------------------------------------------------
/core/client/app/scripts/services/posts-service.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Vardyger
3 | * Copyright(c) 2015 Rob Ferguson
4 | * MIT Licensed
5 | */
6 |
7 | 'use strict';
8 |
9 | // Reference the 'vardyger' module to attach a service
10 |
11 | angular.module('vardyger')
12 | .service('PostsService',
13 | function(
14 | $log, // inject the $log service
15 | $q // inject the $q service
16 | ) {
17 |
18 | $log.info('PostsService');
19 |
20 | var model = [
21 |
22 | {
23 | metaTitle: 'Ionic Style Guide',
24 | metaDescription: 'AngularJS is the toolset that underpins the Ionic Framework.',
25 | post: {
26 | id: '1',
27 | title: 'Ionic Style Guide',
28 | html: '
AngularJS is the toolset that underpins the Ionic Framework.
' +
29 | '
This means that if you want to use the Ionic Framework to develop hybrid mobile applications' +
30 | ' then you will need to understand how Angular web applications are built and structured. A great ' +
31 | 'place to start is to take a look at the Angular project structure templates created by popular ' +
32 | 'Yeoman generators and projects like ' +
33 | 'ng-boilerplate
' +
34 | '
Yeoman
' +
35 | '
Yeoman provides a generator ecosystem ' +
36 | 'that helps you to kickstart new projects. A generator is basically a plugin that can be run with the ' +
37 | 'yo command to create the scaffolding for a new project:
',
38 | markdown: 'AngularJS is the toolset that underpins the Ionic Framework.' +
39 | 'This means that if you want to use the Ionic Framework to develop hybrid mobile applications then you ' +
40 | 'will need to understand how Angular web applications are built and structured. A great place to start ' +
41 | 'is to take a look at the Angular project structure templates created by popular Yeoman ' +
42 | 'generators and projects like ' +
43 | 'ng-boilerplate ' +
44 | '### Yeoman' +
45 | 'Yeoman provides a generator ecosystem ' +
46 | 'that helps you to kickstart new projects. A generator is basically a plugin that can be run with ' +
47 | 'the `yo` command to create the scaffolding for a new project:'
48 | }
49 | },
50 |
51 | {
52 | metaTitle: 'Customising Ionic with Sass',
53 | metaDescription: 'In a previous post, ...',
54 | post: {
55 | id: '2',
56 | title: 'Customising Ionic with Sass',
57 | html: '
In a previous post, ...
',
58 | markdown: 'In a previous post, ...'
59 | }
60 | },
61 |
62 | {
63 | metaTitle: 'Ionic, Angular and Cordova',
64 | metaDescription: 'In a previous post, ...',
65 | post: {
66 | id: '3',
67 | title: 'Ionic, Angular and Cordova',
68 | html: '
In a previous post, ...
',
69 | markdown: 'In a previous post, ...'
70 | }
71 | },
72 |
73 | {
74 | metaTitle: 'Annotating JavaScript using JSDoc tags',
75 | metaDescription: 'In a previous post, ...',
76 | post: {
77 | id: '4',
78 | title: 'Annotating JavaScript using JSDoc tags',
79 | html: '
In a previous post, ...
',
80 | markdown: 'In a previous post, ...'
81 | }
82 | },
83 |
84 | {
85 | metaTitle: 'Express, Handlebars and Ghost Themes',
86 | metaDescription: 'In a previous post, ...',
87 | post: {
88 | id: '5',
89 | title: 'Express, Handlebars and Ghost Themes',
90 | html: '
In a previous post, ...
',
91 | markdown: 'In a previous post, ...'
92 | }
93 | },
94 |
95 | {
96 | metaTitle: 'Swagger, Express, and Content Negotiation',
97 | metaDescription: 'In a previous post, ...',
98 | post: {
99 | id: '6',
100 | title: 'Swagger, Express, and Content Negotiation',
101 | html: '
In a previous post, ...
',
102 | markdown: 'In a previous post, ...'
103 | }
104 | },
105 |
106 | {
107 | metaTitle: 'The Vardyger publishing platform :)',
108 | metaDescription: 'In a previous post, ...',
109 | post: {
110 | id: '7',
111 | title: 'The Vardyger publishing platform :)',
112 | html: '
In a previous post, ...
',
113 | markdown: 'In a previous post, ...'
114 | }
115 | }
116 |
117 | ];
118 |
119 | this.getModel = function() {
120 |
121 | $log.info('PostsService.getModel()');
122 |
123 | return model;
124 | };
125 |
126 | this.findPosts = function() {
127 |
128 | // $log.info('PostsService.findPosts()');
129 |
130 | return model;
131 | };
132 |
133 | this.findPostById = function(id) {
134 |
135 | // $log.info('PostsService.findPostById(): ' + id);
136 |
137 | var deferred = $q.defer();
138 |
139 | // Note: model.forEach NOT this.model.forEach
140 |
141 | model.forEach(function(item) {
142 | if (item.post.id === id) {
143 | // $log.info('item.post.id === id');
144 | deferred.resolve(item);
145 | }
146 | });
147 |
148 | return deferred.promise;
149 | };
150 |
151 | });
152 |
153 |
154 | /*
155 |
156 | // https://docs.angularjs.org/api/ng/service/$sce
157 |
158 | // $log.info('model.length: ' + model.length);
159 |
160 | setTimeout(function() {
161 | model.forEach(function(item) {
162 | if (item.post.id === id) {
163 | $log.info('item.post.id === id');
164 | deferred.resolve(item);
165 | }
166 | });
167 | }, 2000);
168 |
169 |
170 |
171 | $scope.item = {
172 |
173 | metaTitle: 'metaTitle',
174 | metaDescription: 'metaDescription',
175 | post: {
176 | id: 'id',
177 | title: 'Annotating JavaScript using JSDoc tags',
178 | excerpt: '',
179 | html: '',
180 | url: '',
181 | image: '',
182 | featured: false,
183 | page: false,
184 | // state: 'draft',
185 | // locale: 'en_GB',
186 | publishedAt: '',
187 | updatedAt: '',
188 | createdAt: '',
189 | author: {
190 | name: 'Rob Ferguson',
191 | location: 'Sydney, Australia'
192 | },
193 | tags: ''
194 | }
195 |
196 | };
197 |
198 | */
199 |
200 |
--------------------------------------------------------------------------------
/core/client/app/styles/main.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /**
4 | *
5 | * PATH TO THIS FILE: app/styles/main.scss
6 | *
7 | * This includes all variables. We put them all (both ionic overrides and
8 | * our own variables) in one file so it is easy for anyone who @includes
9 | * our scss to locate and edit our variables.
10 | *
11 | **/
12 |
13 | @import "variables";
14 |
15 | /**
16 | *
17 | * This includes the SASS/SCSS version of the ionic framework so that we can
18 | * customize it by overriding it's variables. To use this we need to make sure
19 | * that the CSS version is not included in app/index.html
20 | *
21 | **/
22 |
23 | @import "../bower_components/ionic/scss/ionic";
24 |
25 | // @import "../bower_components/ionic/scss/ionicons/ionicons";
26 |
27 | /**
28 | *
29 | * These are the actual components of our apps that consume variables. We can
30 | * override ionic's own styles here or add additional styles of our own.
31 | *
32 | **/
33 |
34 | @import "styles";
35 |
36 |
37 |
--------------------------------------------------------------------------------
/core/client/app/styles/styles.scss:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * PATH TO THIS FILE: app/styles/styles.scss
4 | *
5 | * Notice that here we define styles but do not define variables.
6 | * Variables should all be defined ahead of time. If we define any
7 | * variables here, then they will be local to this file, and will
8 | * not reset the globals.
9 | *
10 | **/
11 |
12 | // TODO:
13 | // Update Gruntfile.js so that it only compiles main.scss and not
14 | // all .scss files in the styles directory.
15 | @import "variables";
16 | // e.g., grunt serve --force v grunt serve
17 |
18 | /**
19 | * Typography, see bower_components/ionic/scss/_types.scss
20 | */
21 |
22 | // Body text
23 | // -------------------------
24 |
25 | p {
26 | margin: 0 0 ($line-height-computed / 2);
27 | font-weight: $body-font-weight;
28 | }
29 |
30 | // Emphasis & misc
31 | // -------------------------
32 |
33 | small {
34 | font-size: 60%; // 85%
35 | font-weight: $small-font-weight;
36 | }
37 |
38 | // Headings
39 | // -------------------------
40 |
41 | h1, .h1 { font-size: floor($font-size-base * 2.80); } // ~36px 2.60
42 | h2, .h2 { font-size: floor($font-size-base * 2.15); } // ~30px
43 | h3, .h3 { font-size: ceil($font-size-base * 2.00); } // ~24px 1.7
44 | h4, .h4 { font-size: ceil($font-size-base * 1.25); } // ~18px
45 | h5, .h5 { font-size: $font-size-base; }
46 | h6, .h6 { font-size: ceil($font-size-base * 0.85); } // ~12px
47 |
48 | .v-item {
49 | padding-top: 6px;
50 | padding-bottom: 6px;
51 | }
52 |
53 | .v-content {
54 | background-color: white;
55 | }
56 |
57 | .item.wrap, .wrap.v-item, .item-content.wrap {
58 | white-space: normal;
59 | }
60 |
61 | .v-icon-item-left {
62 | font-size: 24px;
63 | vertical-align: text-top;
64 | }
65 |
66 | .post-title {
67 | padding-top: 6px;
68 | padding-left: 12px;
69 | padding-right: 12px;
70 | }
71 |
72 | .post-content {
73 | padding-top: 6px;
74 | padding-left: 14px;
75 | padding-right: 14px;
76 | }
77 |
78 | textarea {
79 | // height: auto;
80 | resize: none;
81 | }
82 |
83 | .markdown-editor {
84 | width: 100%;
85 | }
86 |
87 | // _bar.scss
88 | .bar-subsubheader {
89 | top: $bar-height + $bar-height;
90 | display: block;
91 |
92 | height: $bar-subheader-height;
93 | }
94 |
95 | // _scaffolding.scss
96 | .has-subsubheader {
97 | top: $bar-height + $bar-subheader-height + $bar-subheader-height;
98 | }
99 |
100 | // Misc
101 | // -------------------------
102 |
103 | .vertical-center-container {
104 | height: 100%;
105 |
106 | @include display-flex();
107 | @include justify-content(center);
108 | @include align-items(center);
109 |
110 | .vertical-center {
111 | width: 100%;
112 |
113 | @include display-flex();
114 | @include flex-direction(column);
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/core/client/app/styles/variables.scss:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * PATH TO THIS FILE: app/styles/variables.scss
4 | *
5 | * In this file we're smoothly overriding any ionic variables that have
6 | * existing defaults inside the framework variables file. We're also defining
7 | * our own variables that we can use in our app's components. Essentially we're
8 | * setting the global variables for our app here.
9 | *
10 | * For a list of the possible variables that you can override, see bower_components/ionic/scss/_variables.scss
11 | *
12 | * Note: we add !default to all variables so that they can be overridden later on if need be.
13 | *
14 | **/
15 |
16 | // The path to the ionicons font files, relative to the built CSS in www/styles
17 | // $ionicons-font-path: "../fonts" !default;
18 |
19 | // Colors
20 | // -------------------------------
21 |
22 | $light: #fff !default;
23 | $stable: #f8f8f8 !default;
24 | $positive: #387ef5 !default;
25 | $calm: #11c1f3 !default;
26 | $balanced: #9FBB58 !default;
27 | $energized: #ffc900 !default;
28 | $assertive: #ef473a !default;
29 | $royal: #886aea !default;
30 | $dark: #242628 !default;
31 |
32 | // Base
33 | // -------------------------------
34 |
35 | $font-family-sans-serif: "Open Sans", sans-serif !default;
36 | $font-family-light-sans-serif: "HelveticaNeue-Light", "Roboto-Light", "Segoe UI-Light", sans-serif-light !default;
37 | $font-family-serif: serif !default;
38 | $font-family-monospace: monospace !default;
39 |
40 | $font-family-base: $font-family-sans-serif !default;
41 | $font-size-base: 18px !default; // 14px
42 | $font-size-large: 18px !default;
43 | $font-size-small: 9px !default; // 11px
44 |
45 | $line-height-base: 1.428571429 !default; // 20/14
46 | $line-height-computed: floor($font-size-base * $line-height-base) !default; // ~20px
47 | $line-height-large: 1.33 !default;
48 | $line-height-small: 1.5 !default;
49 |
50 | $headings-font-family: $font-family-base !default;
51 | $headings-font-weight: bold !default;
52 | $headings-line-height: 1.2 !default;
53 |
54 | $base-background-color: #fff !default;
55 | $base-color: #000 !default;
56 |
57 | $link-color: $positive !default;
58 | $link-hover-color: darken($link-color, 15%) !default;
59 |
60 | $content-padding: 10px !default;
61 |
62 | $padding-base-vertical: 6px !default;
63 | $padding-base-horizontal: 12px !default;
64 |
65 | $padding-large-vertical: 10px !default;
66 | $padding-large-horizontal: 16px !default;
67 |
68 | $padding-small-vertical: 5px !default;
69 | $padding-small-horizontal: 10px !default;
70 |
71 | $border-radius-base: 4px !default;
72 | $border-radius-large: 6px !default;
73 | $border-radius-small: 3px !default;
74 |
75 |
76 | $body-font-weight: 200 !default;
77 | $small-font-weight: 400 !default;
78 |
--------------------------------------------------------------------------------
/core/client/app/templates/editor-template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |