├── .gitignore ├── screenshots └── electron.png ├── public ├── js │ ├── home.js │ └── init.js └── css │ └── custom-style.css ├── README.md ├── package.json ├── helpers └── page-build-helper.js ├── pages-content ├── home.html └── about.html ├── main.js └── layouts └── layout.hbs /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | pages 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /screenshots/electron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/John-Lin/electron-boilerplate/HEAD/screenshots/electron.png -------------------------------------------------------------------------------- /public/js/home.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | // Document is ready 3 | // NProgress.configure({ easing: 'ease', speed: 500, trickleRate: 0.1}); 4 | // NProgress.start(); 5 | // setTimeout(() => {NProgress.done();}, 5000); 6 | }); 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # electron-boilerplate 2 | 3 | # Installation 4 | 5 | 1. `git clone https://github.com/John-Lin/electron-boilerplate.git` 6 | 2. `cd electron-boilerplate` 7 | 3. `npm install` 8 | 9 | # Build the pages html 10 | 11 | ```sh 12 | npm run build 13 | ``` 14 | 15 | # Run the app 16 | ```sh 17 | npm run start 18 | ``` 19 | 20 | # Screenshots 21 | ![electron-app](https://rawgit.com/John-Lin/electron-boilerplate/master/screenshots/electron.png) 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "version": "0.1.0", 4 | "main": "main.js", 5 | "scripts": { 6 | "start": "node ./helpers/page-build-helper.js && electron .", 7 | "build": "node ./helpers/page-build-helper.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "devDependencies": { 11 | "electron-prebuilt": "^0.36.0", 12 | "handlebars": "^4.0.5", 13 | "handlebars-layouts": "^3.1.3", 14 | "mkdirp": "^0.5.1" 15 | }, 16 | "dependencies": { 17 | "jquery": "^2.1.4" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /helpers/page-build-helper.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | let handlebars = require('handlebars'); 3 | let layouts = require('handlebars-layouts'); 4 | let fs = require('fs'); 5 | let path = require('path'); 6 | let mkdirp = require('mkdirp'); 7 | 8 | mkdirp.sync(path.join(__dirname, '../pages')); 9 | 10 | let input = path.join(__dirname, '../pages-content'); 11 | let pageFiles = fs.readdirSync(input); 12 | let output = path.join(__dirname, '../pages'); 13 | 14 | let layoutPath = path.join(__dirname, '../layouts/layout.hbs'); 15 | 16 | // Register helpers 17 | handlebars.registerHelper(layouts(handlebars)); 18 | 19 | // Register partials 20 | handlebars.registerPartial('layout', fs.readFileSync(layoutPath, 'utf8')); 21 | 22 | function buildPages(files) { 23 | files.forEach((file) => { 24 | 25 | let HTMLPath = path.join(__dirname, `../pages-content/${file}`); 26 | 27 | // Compile template 28 | let template = handlebars.compile(fs.readFileSync(HTMLPath, 'utf8')); 29 | 30 | // Render template 31 | let render = template({ 32 | title: 'myApp', 33 | }); 34 | fs.writeFileSync(path.join(output, file), render); 35 | }); 36 | } 37 | 38 | buildPages(pageFiles); 39 | -------------------------------------------------------------------------------- /pages-content/home.html: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "head" mode="append"}} 3 | {{/content}} 4 | 5 | {{#content "body"}} 6 |

Home pages

7 |
8 |

Aenean vehicula tortor a tellus porttitor, id elementum est tincidunt. Etiam varius odio tortor. Praesent vel pulvinar sapien. Praesent ac sodales sem. Phasellus id ultrices massa. Sed id erat sit amet magna accumsan vulputate eu at quam. Etiam feugiat semper imperdiet. Sed a sem vitae massa condimentum vestibulum. In vehicula, quam vel aliquet aliquam, enim elit placerat libero, at pretium nisi lorem in ex. Vestibulum lorem augue, semper a efficitur in, dictum vitae libero. Donec velit est, sollicitudin a volutpat quis, iaculis sit amet metus. Nulla at ante nec dolor euismod mattis cursus eu nisl.

9 |

Quisque interdum facilisis consectetur. Nam eu purus purus. Curabitur in ligula quam. Nam euismod ligula eu tellus pellentesque laoreet. Aliquam erat volutpat. Curabitur eu bibendum velit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc efficitur lorem sit amet quam porta pharetra. Cras ultricies pellentesque eros sit amet semper.

10 |
11 | 15 |
16 |
17 | 18 |
19 |
20 | {{/content}} 21 | 22 | {{#content "foot" mode="prepend"}} 23 | 24 | {{/content}} 25 | {{/extend}} 26 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | const electron = require('electron'); 2 | const app = electron.app; // Module to control application life. 3 | const BrowserWindow = electron.BrowserWindow; // Module to create native browser window. 4 | 5 | // Report crashes to our server. 6 | electron.crashReporter.start(); 7 | 8 | // Keep a global reference of the window object, if you don't, the window will 9 | // be closed automatically when the JavaScript object is garbage collected. 10 | var mainWindow = null; 11 | 12 | // Quit when all windows are closed. 13 | app.on('window-all-closed', function() { 14 | // On OS X it is common for applications and their menu bar 15 | // to stay active until the user quits explicitly with Cmd + Q 16 | if (process.platform != 'darwin') { 17 | app.quit(); 18 | } 19 | }); 20 | 21 | // This method will be called when Electron has finished 22 | // initialization and is ready to create browser windows. 23 | app.on('ready', function() { 24 | // Create the browser window. 25 | 26 | mainWindow = new BrowserWindow({width: 1024, height: 600}); 27 | 28 | // mainWindow = new BrowserWindow({width: 1024, height: 600, titleBarStyle: 'hidden'}); 29 | 30 | // and load the index.html of the app. 31 | mainWindow.loadURL('file://' + __dirname + '/pages/home.html'); 32 | 33 | // Open the DevTools. 34 | mainWindow.webContents.openDevTools(); 35 | 36 | // Emitted when the window is closed. 37 | mainWindow.on('closed', function() { 38 | // Dereference the window object, usually you would store windows 39 | // in an array if your app supports multi windows, this is the time 40 | // when you should delete the corresponding element. 41 | mainWindow = null; 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /pages-content/about.html: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "head" mode="append"}} 3 | {{/content}} 4 | 5 | {{#content "body"}} 6 |

About pages

7 | 8 |
9 | 10 |

Aenean vehicula tortor a tellus porttitor, id elementum est tincidunt. Etiam varius odio tortor. Praesent vel pulvinar sapien. Praesent ac sodales sem. Phasellus id ultrices massa. Sed id erat sit amet magna accumsan vulputate eu at quam. Etiam feugiat semper imperdiet. Sed a sem vitae massa condimentum vestibulum. In vehicula, quam vel aliquet aliquam, enim elit placerat libero, at pretium nisi lorem in ex. Vestibulum lorem augue, semper a efficitur in, dictum vitae libero. Donec velit est, sollicitudin a volutpat quis, iaculis sit amet metus. Nulla at ante nec dolor euismod mattis cursus eu nisl.

11 |

Quisque interdum facilisis consectetur. Nam eu purus purus. Curabitur in ligula quam. Nam euismod ligula eu tellus pellentesque laoreet. Aliquam erat volutpat. Curabitur eu bibendum velit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc efficitur lorem sit amet quam porta pharetra. Cras ultricies pellentesque eros sit amet semper.

12 |
13 | 17 |
18 |
19 | 20 |
21 |
22 | 23 | {{/content}} 24 | 25 | {{#content "foot" mode="prepend"}} 26 | 27 | {{/content}} 28 | {{/extend}} 29 | -------------------------------------------------------------------------------- /public/js/init.js: -------------------------------------------------------------------------------- 1 | jQuery(function($) { 2 | var $bodyEl = $('body'); 3 | var $sidedrawerEl = $('#sidedrawer'); 4 | 5 | // ========================================================================== 6 | // Toggle Sidedrawer 7 | // ========================================================================== 8 | function showSidedrawer() { 9 | // show overlay 10 | var options = { 11 | onclose: function() { 12 | $sidedrawerEl 13 | .removeClass('active') 14 | .appendTo(document.body); 15 | }, 16 | }; 17 | 18 | var $overlayEl = $(mui.overlay('on', options)); 19 | 20 | // show element 21 | $sidedrawerEl.appendTo($overlayEl); 22 | setTimeout(function() { 23 | $sidedrawerEl.addClass('active'); 24 | }, 20); 25 | } 26 | 27 | function hideSidedrawer() { 28 | $bodyEl.toggleClass('hide-sidedrawer'); 29 | } 30 | 31 | $('.js-show-sidedrawer').on('click', showSidedrawer); 32 | $('.js-hide-sidedrawer').on('click', hideSidedrawer); 33 | 34 | // ========================================================================== 35 | // Animate menu 36 | // ========================================================================== 37 | var $titleEls = $('strong', $sidedrawerEl); 38 | 39 | $titleEls 40 | .next() 41 | .hide(); 42 | 43 | $titleEls.on('click', function() { 44 | $(this).next().slideToggle(200); 45 | }); 46 | 47 | // ========================================================================== 48 | // Progress bar 49 | // ========================================================================== 50 | 51 | NProgress.configure({ 52 | parent: '#appbar', 53 | easing: 'ease', 54 | speed: 1000, 55 | trickleRate: 0.03, 56 | }); 57 | NProgress.start(); 58 | 59 | }); 60 | 61 | $(window).load(function() { 62 | NProgress.done(); 63 | }); 64 | -------------------------------------------------------------------------------- /public/css/custom-style.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Body CSS 3 | */ 4 | 5 | html, 6 | body { 7 | height: 100%; 8 | background-color: #f2f3f4; 9 | } 10 | 11 | html, 12 | body, 13 | input, 14 | textarea, 15 | buttons { 16 | -webkit-font-smoothing: antialiased; 17 | -moz-osx-font-smoothing: grayscale; 18 | text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.004); 19 | } 20 | 21 | 22 | /** 23 | * Layout CSS 24 | */ 25 | 26 | #header { 27 | position: fixed; 28 | top: 0; 29 | right: 0; 30 | left: 0; 31 | z-index: 2; 32 | transition: left 0.2s; 33 | 34 | } 35 | 36 | #sidedrawer { 37 | position: fixed; 38 | top: 0; 39 | bottom: 0; 40 | width: 200px; 41 | left: -200px; 42 | overflow: auto; 43 | z-index: 2; 44 | background-color: #FAF7F3; 45 | transition: transform 0.2s; 46 | } 47 | 48 | #content-wrapper { 49 | min-height: 100%; 50 | overflow-x: hidden; 51 | margin-left: 0px; 52 | transition: margin-left 0.2s; 53 | 54 | /* sticky bottom */ 55 | margin-bottom: -160px; 56 | padding-bottom: 160px; 57 | } 58 | 59 | #footer { 60 | height: 100px; 61 | margin-left: 0px; 62 | transition: margin-left 0.2s; 63 | } 64 | 65 | @media (min-width: 768px) { 66 | #header { 67 | left: 200px; 68 | } 69 | 70 | #sidedrawer { 71 | transform: translate(200px); 72 | } 73 | 74 | #content-wrapper { 75 | margin-left: 200px; 76 | } 77 | 78 | #footer { 79 | margin-left: 200px; 80 | } 81 | 82 | body.hide-sidedrawer #header { 83 | left: 0; 84 | } 85 | 86 | body.hide-sidedrawer #sidedrawer { 87 | transform: translate(0px); 88 | } 89 | 90 | body.hide-sidedrawer #content-wrapper { 91 | margin-left: 0; 92 | } 93 | 94 | body.hide-sidedrawer #footer { 95 | margin-left: 0; 96 | } 97 | } 98 | 99 | 100 | /** 101 | * Toggle Sidedrawer 102 | */ 103 | #sidedrawer.active { 104 | transform: translate(200px); 105 | } 106 | 107 | 108 | /** 109 | * Header CSS 110 | */ 111 | 112 | .sidedrawer-toggle { 113 | color: #fff; 114 | cursor: pointer; 115 | font-size: 20px; 116 | line-height: 20px; 117 | margin-right: 10px; 118 | } 119 | 120 | .sidedrawer-toggle:hover { 121 | color: #fff; 122 | text-decoration: none; 123 | } 124 | 125 | #header .mui-appbar { 126 | /*dark organge*/ 127 | background-color: #ee9430; 128 | 129 | /*background-color: #FAF7F3;*/ 130 | 131 | /*light blue*/ 132 | /*background-color: #A5ECFA;*/ 133 | 134 | /*dark blue*/ 135 | /*background-color: #2196F3;*/ 136 | } 137 | 138 | 139 | /** 140 | * Sidedrawer CSS 141 | */ 142 | 143 | #sidedrawer-brand { 144 | padding-left: 20px; 145 | } 146 | 147 | #sidedrawer ul { 148 | list-style: none; 149 | } 150 | 151 | #sidedrawer > ul { 152 | padding-left: 0px; 153 | } 154 | 155 | #sidedrawer > ul > li:first-child { 156 | padding-top: 15px; 157 | } 158 | 159 | #sidedrawer strong { 160 | display: block; 161 | padding: 15px 22px; 162 | cursor: pointer; 163 | } 164 | 165 | #sidedrawer strong:hover { 166 | background-color: #E0E0E0; 167 | } 168 | 169 | #sidedrawer strong + ul > li { 170 | padding: 6px 0px; 171 | } 172 | 173 | 174 | /** 175 | * Footer CSS 176 | */ 177 | 178 | #footer { 179 | /*background-color: #0288D1;*/ 180 | background-color: #757575; 181 | color: #fff; 182 | 183 | /*position: fixed; 184 | bottom: 0; 185 | right: 0; 186 | width: 100%;*/ 187 | } 188 | 189 | #footer a { 190 | color: #fff; 191 | text-decoration: underline; 192 | } 193 | -------------------------------------------------------------------------------- /layouts/layout.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | {{#block "head"}} 13 | {{title}} 14 | {{/block}} 15 | 16 | 17 | 18 | 19 | 20 |
21 |
Brand.io
22 |
23 | 51 |
52 | 53 | 54 | 55 | 64 | 65 | 66 | 67 |
68 |
69 |
70 |
71 | {{#block "body"}} 72 | {{/block}} 73 |
74 |
75 | 76 | 77 | 78 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | {{#block "foot"}} 91 | {{/block}} 92 | 93 | 94 | --------------------------------------------------------------------------------