mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 19:57:22 +08:00
Feature(generate): Add generators into the tooling/generators folder. Add in main file into package.json. Bump lodash to 3.10.1 for template and camelCase methods. Move lodash to dependencies from devDependencies. Have index.js require in the generate module.
This commit is contained in:
3
index.js
Normal file
3
index.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module.exports = {
|
||||||
|
generate: require('./tooling/generate')
|
||||||
|
};
|
@ -6,13 +6,16 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/driftyco/ionic2.git"
|
"url": "https://github.com/driftyco/ionic2.git"
|
||||||
},
|
},
|
||||||
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "gulp karma",
|
"test": "gulp karma",
|
||||||
|
"test:generators": "jasmine-node ./tooling/spec",
|
||||||
"link": "npm install && gulp src && npm link"
|
"link": "npm install && gulp src && npm link"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"angular2": "2.0.0-alpha.44",
|
"angular2": "2.0.0-alpha.44",
|
||||||
"es6-shim": "^0.33.6",
|
"es6-shim": "^0.33.6",
|
||||||
|
"lodash": "^3.10.1",
|
||||||
"@reactivex/rxjs": "5.0.0-alpha.4",
|
"@reactivex/rxjs": "5.0.0-alpha.4",
|
||||||
"reflect-metadata": "0.1.1",
|
"reflect-metadata": "0.1.1",
|
||||||
"zone.js": "0.5.8"
|
"zone.js": "0.5.8"
|
||||||
@ -47,7 +50,6 @@
|
|||||||
"karma-chrome-launcher": "^0.1.7",
|
"karma-chrome-launcher": "^0.1.7",
|
||||||
"karma-jasmine": "^0.3.5",
|
"karma-jasmine": "^0.3.5",
|
||||||
"lazypipe": "^0.2.3",
|
"lazypipe": "^0.2.3",
|
||||||
"lodash": "^2.4.1",
|
|
||||||
"lunr": "^0.5.12",
|
"lunr": "^0.5.12",
|
||||||
"minimist": "^1.1.3",
|
"minimist": "^1.1.3",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
|
229
tooling/generate.js
Normal file
229
tooling/generate.js
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
var _ = require('lodash'),
|
||||||
|
fs = require('fs'),
|
||||||
|
// logging = require('../logging'),
|
||||||
|
path = require('path'),
|
||||||
|
shell = require('shelljs'),
|
||||||
|
Generate = module.exports;
|
||||||
|
|
||||||
|
Generate._generators;
|
||||||
|
|
||||||
|
Generate.__defineGetter__('generators', function() {
|
||||||
|
if (!Generate._generators) {
|
||||||
|
Generate._generators = Generate.loadGenerators();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Generate._generators;
|
||||||
|
});
|
||||||
|
|
||||||
|
// options: appDirectory, generatorName, name
|
||||||
|
Generate.generate = function generate(options) {
|
||||||
|
// console.log('Generate options', options);
|
||||||
|
if (!options) {
|
||||||
|
throw new Error('No options passed to generator');
|
||||||
|
}
|
||||||
|
// var generatorPath = path.join(__dirname, 'generators');
|
||||||
|
if (!options.generatorName) {
|
||||||
|
options.generatorName = 'page';
|
||||||
|
}
|
||||||
|
|
||||||
|
var generateOptions = {
|
||||||
|
appDirectory: options.appDirectory,
|
||||||
|
fileAndClassName: Generate.fileAndClassName(options.name),
|
||||||
|
javascriptClassName: Generate.javascriptClassName(options.name),
|
||||||
|
name: options.name
|
||||||
|
};
|
||||||
|
|
||||||
|
Generate.createScaffoldDirectories({appDirectory: options.appDirectory, fileAndClassName: generateOptions.fileAndClassName});
|
||||||
|
|
||||||
|
return Generate.generators[options.generatorName].run(generateOptions);
|
||||||
|
};
|
||||||
|
|
||||||
|
Generate.loadGeneratorTemplates = function loadGeneratorTemplates(generatorPath) {
|
||||||
|
// var generatorPath = path.join(__dirname, 'generators', generatorName);
|
||||||
|
var templates = [];
|
||||||
|
fs.readdirSync(generatorPath)
|
||||||
|
.forEach(function(template) {
|
||||||
|
var type;
|
||||||
|
// Go through all the files in the folder, grab the templates, read in the file contents
|
||||||
|
// return as template type, contents
|
||||||
|
if (template.indexOf('.tmpl') == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
templates.push({file: template, type: path.extname(template)});
|
||||||
|
});
|
||||||
|
|
||||||
|
return templates;
|
||||||
|
};
|
||||||
|
|
||||||
|
Generate.loadGenerator = function loadGenerator(file) {
|
||||||
|
var generatorPath = path.join(__dirname, 'generators', file);
|
||||||
|
var generateModule;
|
||||||
|
try {
|
||||||
|
generateModule = require(generatorPath);
|
||||||
|
} catch (ex) {
|
||||||
|
console.log('Error loading generator module', ex);
|
||||||
|
}
|
||||||
|
return generateModule;//page
|
||||||
|
};
|
||||||
|
|
||||||
|
Generate.loadGenerators = function loadGenerators() {
|
||||||
|
var generators = {};
|
||||||
|
fs.readdirSync(path.join(__dirname, 'generators'))
|
||||||
|
.forEach(function (file) {
|
||||||
|
var generatorName = file.replace('.js', '');
|
||||||
|
generators[generatorName] = Generate.loadGenerator(generatorName);
|
||||||
|
});
|
||||||
|
return generators;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Will take options to render an html, js, or scss template.
|
||||||
|
options:
|
||||||
|
they differ based on what is needed in template
|
||||||
|
For JavaScript file: filename, javascriptClassName
|
||||||
|
For HTML file: name, nameUppercased
|
||||||
|
templatePath: the path of the template to render (html/js/scss), ex: '/path/to/page.tmpl.html'
|
||||||
|
*/
|
||||||
|
Generate.renderTemplateFromFile = function renderTemplateFromFile(options) {
|
||||||
|
var templateContents = fs.readFileSync(options.templatePath, 'utf8');
|
||||||
|
var templateCompiler = _.template(templateContents);
|
||||||
|
var result = templateCompiler(options);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Will take options to render the basic page javascript template
|
||||||
|
the name of the component/page being rendered, ex: 'IonicTest'
|
||||||
|
*/
|
||||||
|
Generate.generateJsTemplate = function generateJsTemplate(name) {
|
||||||
|
var jsTemplatePath = path.join(__dirname, 'page.tmpl.js');
|
||||||
|
var options = { javascriptClassName: Generate.javascriptClassName(name), filename: Generate.fileAndClassName(name), templatePath: jsTemplatePath};
|
||||||
|
return Generate.renderTemplateFromFile(options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Will take options to render the basic page html template
|
||||||
|
the name of the component/page being rendered, ex: 'IonicTest'
|
||||||
|
*/
|
||||||
|
Generate.generateHtmlTemplate = function generateHtmlTemplate(name) {
|
||||||
|
var htmlTemplatePath = path.join(__dirname, 'page.tmpl.html');
|
||||||
|
return Generate.renderTemplateFromFile({ name: Generate.fileAndClassName(name), capitalizedName: Generate.capitalizeName(name) ,templatePath: htmlTemplatePath});
|
||||||
|
};
|
||||||
|
|
||||||
|
Generate.generateScssTemplate = function generateScssTemplate(name) {
|
||||||
|
var scssTemplatePath = path.join(__dirname, 'page.tmpl.scss');
|
||||||
|
return Generate.renderTemplateFromFile({ name: Generate.fileAndClassName(name), templatePath: scssTemplatePath});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tabs - name = name of the page with the tabs,
|
||||||
|
// tabs = array of the tabs to create.
|
||||||
|
Generate.tabPages = function tabPages(appDirectory, name, tabs) {
|
||||||
|
Generate.createScaffoldDirectories(appDirectory, name);
|
||||||
|
|
||||||
|
// Generate page with tabs:
|
||||||
|
var tabsFileAndClassName = Generate.fileAndClassName(name);
|
||||||
|
|
||||||
|
var tabsHtml = Generate.generateTabsHtmlTemplate(appDirectory, name, tabs);
|
||||||
|
var tabsJs = Generate.generateTabsJsTemplate(appDirectory, name, tabs);
|
||||||
|
// var tabsScss = Generate.generateTabsScssTemplate(appDirectory, name, tabs);
|
||||||
|
var pagePath = path.join(appDirectory, 'www', 'app', tabsFileAndClassName),
|
||||||
|
jsPath = path.join(pagePath, [tabsFileAndClassName, '.js'].join('')),
|
||||||
|
htmlPath = path.join(pagePath, [tabsFileAndClassName, '.html'].join(''));
|
||||||
|
// scssPath = path.join(pagePath, [tabsFileAndClassName, '.scss'].join(''));
|
||||||
|
|
||||||
|
tabs.forEach(function(tab) {
|
||||||
|
Generate.createScaffoldDirectories(appDirectory, tab);
|
||||||
|
var tabJs = Generate.generateJsTemplate(appDirectory, tab);
|
||||||
|
var tabHtml = Generate.generateHtmlTemplate(appDirectory, tab);
|
||||||
|
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
Generate.generateTabHtmlTemplate = function generateTabHtmlTemplate(appDirectory, name) {
|
||||||
|
throw new Error('not implemented');
|
||||||
|
};
|
||||||
|
|
||||||
|
Generate.generateTabsHtmlTemplate = function generateTabsHtmlTemplate(appDirectory, name, tabs) {
|
||||||
|
// throw new Error('not implemented');
|
||||||
|
var fileAndClassName = Generate.fileAndClassName(name);
|
||||||
|
var javascriptClassName = Generate.javascriptClassName(name);
|
||||||
|
// Generate.createScaffoldDirectories(appDirectory, fileAndClassName);
|
||||||
|
|
||||||
|
var tabsData = [];
|
||||||
|
tabs.forEach(function(tab) {
|
||||||
|
var tabObj = { name: tab, javascriptClassName: Generate.javascriptClassName(tab)};
|
||||||
|
tabsData.push(tabObj);
|
||||||
|
});
|
||||||
|
|
||||||
|
var tabsHtmlTemplatePath = path.join(__dirname, 'tabs.tmpl.html');
|
||||||
|
return Generate.renderTemplateFromFile({tabs: tabsData, templatePath: tabsHtmlTemplatePath });
|
||||||
|
|
||||||
|
// <ion-tabs>
|
||||||
|
// <% _.forEach(tabs, function(tab) { %>
|
||||||
|
// <ion-tab tab-title="<%= tab.name %>" tab-icon="globe" [root]="<%= tab.javascriptClassName %>">
|
||||||
|
// </ion-tab>
|
||||||
|
// <% }); %>
|
||||||
|
// </ion-tabs>
|
||||||
|
};
|
||||||
|
|
||||||
|
Generate.generateTabJsTemplate = function generateTabJsTemplate(appDirectory, name) {
|
||||||
|
throw new Error('not implemented');
|
||||||
|
};
|
||||||
|
|
||||||
|
Generate.generateTabsJsTemplate = function generateTabsJsTemplate(appDirectory, name, tabs) {
|
||||||
|
// import {NavController, Page} from 'ionic/ionic';
|
||||||
|
// <% _.forEach(tabs, function(tab) { %>
|
||||||
|
// import {<%= tab.javascriptClassName %>} from '../<%= tab.filename %>/<%= tab.filename %>';
|
||||||
|
// <% }); %>
|
||||||
|
// @Page({
|
||||||
|
// templateUrl: 'app/<%= filename %>/<%= filename %>.html',
|
||||||
|
// providers: [DataService]
|
||||||
|
// })
|
||||||
|
// class <%= javascriptClassName %> {
|
||||||
|
// constructor(nav: NavController) {
|
||||||
|
// // set the root pages for each tab
|
||||||
|
// <% _.forEach(tabs, function(tab) { %>
|
||||||
|
// this.{<%= tab.javascriptClassName %>} = <%= tab.javascriptClassName %>;
|
||||||
|
// <% }); %>
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
var fileAndClassName = Generate.fileAndClassName(name);
|
||||||
|
var javascriptClassName = Generate.javascriptClassName(name);
|
||||||
|
|
||||||
|
var tabsData = [];
|
||||||
|
tabs.forEach(function(tab) {
|
||||||
|
var tabObj = { name: tab, filename: Generate.fileAndClassName(tab), javascriptClassName: Generate.javascriptClassName(tab)};
|
||||||
|
tabsData.push(tabObj);
|
||||||
|
});
|
||||||
|
|
||||||
|
var tabsHtmlTemplatePath = path.join(__dirname, 'tabs.tmpl.js');
|
||||||
|
return Generate.renderTemplateFromFile({tabs: tabsData, templatePath: tabsHtmlTemplatePath, filename: fileAndClassName, javascriptClassName: javascriptClassName });
|
||||||
|
};
|
||||||
|
|
||||||
|
Generate.generateTabScssTemplate = function generateTabScssTemplate(appDirectory, name) {
|
||||||
|
throw new Error('not implemented');
|
||||||
|
};
|
||||||
|
|
||||||
|
Generate.generateTabsScssTemplate = function generateTabsScssTemplate(appDirectory, name) {
|
||||||
|
throw new Error('not implemented');
|
||||||
|
};
|
||||||
|
// end of tabs
|
||||||
|
|
||||||
|
Generate.createScaffoldDirectories = function createScaffoldDirectories(options) {
|
||||||
|
// console.log('Create', options.appDirectory, options.fileAndClassName);
|
||||||
|
var componentPath = path.join(options.appDirectory, 'www', 'app', options.fileAndClassName);
|
||||||
|
shell.mkdir('-p', componentPath);
|
||||||
|
};
|
||||||
|
|
||||||
|
Generate.fileAndClassName = function fileAndClassName(name) {
|
||||||
|
return name.replace(/([a-z])([A-Z])/g, '$1-$2').replace('_', '-').toLowerCase();
|
||||||
|
};
|
||||||
|
|
||||||
|
Generate.capitalizeName = function capitalizeName(name) {
|
||||||
|
return name.charAt(0).toUpperCase() + name.slice(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
Generate.javascriptClassName = function javascriptClassName(name) {
|
||||||
|
return _.capitalize(_.camelCase(name));
|
||||||
|
};
|
5
tooling/generators/page-sidemenu/index.js
Normal file
5
tooling/generators/page-sidemenu/index.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
var SideMenu = module.exports;
|
||||||
|
|
||||||
|
SideMenu.run = function run(options) {
|
||||||
|
|
||||||
|
};
|
6
tooling/generators/page-tabs/index.js
Normal file
6
tooling/generators/page-tabs/index.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
var Generator = module.exports,
|
||||||
|
Generate = require('../../generate');
|
||||||
|
|
||||||
|
Generator.run = function run(options) {
|
||||||
|
console.log('got options!', options);
|
||||||
|
};
|
6
tooling/generators/page-tabs/tabs.tmpl.html
Normal file
6
tooling/generators/page-tabs/tabs.tmpl.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<ion-tabs>
|
||||||
|
<% _.forEach(tabs, function(tab) { %>
|
||||||
|
<ion-tab tab-title="<%= tab.name %>" tab-icon="globe" [root]="<%= tab.javascriptClassName %>">
|
||||||
|
</ion-tab>
|
||||||
|
<% }); %>
|
||||||
|
</ion-tabs>
|
18
tooling/generators/page-tabs/tabs.tmpl.js
Normal file
18
tooling/generators/page-tabs/tabs.tmpl.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import {NavController, Page} from 'ionic/ionic';
|
||||||
|
|
||||||
|
<% _.forEach(tabs, function(tab) { %>
|
||||||
|
import {<%= tab.javascriptClassName %>} from '../<%= tab.filename %>/<%= tab.filename %>';
|
||||||
|
<% }); %>
|
||||||
|
|
||||||
|
@Page({
|
||||||
|
templateUrl: 'app/<%= filename %>/<%= filename %>.html'
|
||||||
|
})
|
||||||
|
export class <%= javascriptClassName %> {
|
||||||
|
constructor(nav: NavController) {
|
||||||
|
// set the root pages for each tab
|
||||||
|
<% _.forEach(tabs, function(tab) { %>
|
||||||
|
this.<%= tab.javascriptClassName %> = <%= tab.javascriptClassName %>;
|
||||||
|
<% }); %>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
61
tooling/generators/page/index.js
Normal file
61
tooling/generators/page/index.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
ionic g page about
|
||||||
|
what should happen:
|
||||||
|
create directories if not existing: /www, /www/app, /www/app/about
|
||||||
|
create files (about.html, about.scss, about.js) in /www/app/about
|
||||||
|
*/
|
||||||
|
var fs = require('fs'),
|
||||||
|
Generator = module.exports,
|
||||||
|
Generate = require('../../generate'),
|
||||||
|
path = require('path'),
|
||||||
|
Q = require('q');
|
||||||
|
/*
|
||||||
|
Run: generate a page template from the name and save
|
||||||
|
it in the desired app directory
|
||||||
|
@options
|
||||||
|
name: Page name
|
||||||
|
appDirectory: App directory of where to save file
|
||||||
|
*/
|
||||||
|
Generator.run = function run(options) {
|
||||||
|
options.rootDirectory = options.rootDirectory || path.join('www', 'app');
|
||||||
|
var savePath = path.join(options.appDirectory, options.rootDirectory, options.fileAndClassName);
|
||||||
|
|
||||||
|
var templates = Generate.loadGeneratorTemplates(__dirname);
|
||||||
|
|
||||||
|
templates.forEach(function(template) {
|
||||||
|
var templatePath = path.join(__dirname, template.file);
|
||||||
|
options.templatePath = templatePath;
|
||||||
|
var renderedTemplate = Generate.renderTemplateFromFile(options);
|
||||||
|
var saveFilePath = path.join(savePath, [options.fileAndClassName, template.type].join(''));
|
||||||
|
// console.log('renderedTemplate', renderedTemplate, 'saving to', saveFilePath);
|
||||||
|
console.log('\n√ Create'.blue, path.relative(options.appDirectory, saveFilePath));
|
||||||
|
fs.writeFileSync(saveFilePath, renderedTemplate);
|
||||||
|
});
|
||||||
|
|
||||||
|
return Q();
|
||||||
|
};
|
||||||
|
|
||||||
|
// var fileAndClassName = Generate.fileAndClassName(name);
|
||||||
|
// var javascriptClassName = Generate.javascriptClassName(name);
|
||||||
|
// Generate.createScaffoldDirectories(appDirectory, fileAndClassName);
|
||||||
|
|
||||||
|
// var jsTemplate = Generate.generateJsTemplate(name);
|
||||||
|
// var htmlTemplate = Generate.generateHtmlTemplate(name);
|
||||||
|
// var scssTemplate = Generate.generateScssTemplate(name);
|
||||||
|
|
||||||
|
// var pagePath = path.join(appDirectory, 'www', 'app', fileAndClassName),
|
||||||
|
// jsPath = path.join(pagePath, [fileAndClassName, '.js'].join('')),
|
||||||
|
// htmlPath = path.join(pagePath, [fileAndClassName, '.html'].join('')),
|
||||||
|
// scssPath = path.join(pagePath, [fileAndClassName, '.scss'].join(''));
|
||||||
|
|
||||||
|
// logging.logger.info('√ Create'.blue, path.relative(appDirectory, jsPath));
|
||||||
|
// fs.writeFileSync(jsPath, jsTemplate, 'utf8');
|
||||||
|
// logging.logger.info('√ Create'.blue, path.relative(appDirectory, htmlPath));
|
||||||
|
// fs.writeFileSync(htmlPath, htmlTemplate, 'utf8');
|
||||||
|
// logging.logger.info('√ Create'.blue, path.relative(appDirectory, scssPath));
|
||||||
|
// fs.writeFileSync(scssPath, scssTemplate, 'utf8');
|
||||||
|
|
||||||
|
// //TODO: Modify the main sass file (via config) to somehow update it
|
||||||
|
// //to include this sass file.
|
||||||
|
// //In the meantime, put a console message to alert them
|
||||||
|
// logging.logger.info('* Tip: if youd like to use the generated sass file, use \'@import "' + path.relative(appDirectory, scssPath) + '"\' in your main sass file');
|
6
tooling/generators/page/page.tmpl.html
Normal file
6
tooling/generators/page/page.tmpl.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<ion-navbar *navbar>
|
||||||
|
<ion-title><%= javascriptClassName %></ion-title>
|
||||||
|
</ion-navbar>
|
||||||
|
|
||||||
|
<ion-content padding class="<%= fileAndClassName %>">
|
||||||
|
</ion-content>
|
9
tooling/generators/page/page.tmpl.js
Normal file
9
tooling/generators/page/page.tmpl.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import {Page, NavController} from 'ionic/ionic';
|
||||||
|
@Page({
|
||||||
|
templateUrl: 'app/<%= fileAndClassName %>/<%= fileAndClassName %>.html',
|
||||||
|
})
|
||||||
|
export class <%= javascriptClassName %> {
|
||||||
|
constructor(nav: NavController) {
|
||||||
|
this.nav = nav;
|
||||||
|
}
|
||||||
|
}
|
3
tooling/generators/page/page.tmpl.scss
Normal file
3
tooling/generators/page/page.tmpl.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.<%= fileAndClassName %> {
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user