UNPKG

slush-regenerator

Version:

A slush generator for many website things (Optimized for Laravel 5.2)

271 lines (230 loc) 10 kB
var _ = require('underscore'), changeCase = require('change-case'), pluralize = require('pluralize'), gutil = require('gulp-util'), FileQueue = require('filequeue'), fs = require('fs-extra'), path = require('path'); // Queue var fq = new FileQueue(256); var mapper = require('./../../../../classes/mapper'); // Configs var defaults = require('./../../../../config/defaults.json'); /** * Laravel views plugin for slush-blueprints * This is using CRUDL architecture with regular PHP templating **/ var view = { counter: 0, traditional_logging: true, base_files_copied: false, // Different attributes for input type (for automatic browser UIs) input_types: [ 'checkbox', 'color', 'date', 'datetime', 'datetime-local', 'email', 'month', 'number', 'password', 'radio', 'range', 'search', 'tel', 'text', 'time', 'url', 'week' ], // Input attributes which can be mapped directly to native datatypes (if not named in an identical manner) native_mappings: { 'boolean': 'checkbox', }, // HTML form elements supported by this plugin form_elements: [ 'input', 'select', 'select-group' ], /** * Compose form field */ ff: function(name, type, route_name, table_name) { var form_field = { "name": name, "type": type, "label": changeCase.titleCase(name), }; form_field.route_name = (route_name != undefined) ? route_name : null; form_field.table_name = (table_name != undefined) ? table_name : null; return form_field; }, /** * Match schema primative datatypes to desired HTML form field datatypes for selected data source */ form_field_handling: function(context_name, parent_context_name, fields, show_field_handling, list_of_things) { var valid_fields = [], invalid_fields = [], natural_language_fields = []; if (show_field_handling == undefined) { show_field_handling = false; } for (field_name in fields) { // Trial and error data type matching var transformation = mapper.direct_datatype_transformation_match(view.input_types, fields[field_name]); if (transformation != null) { // Got a direct match var data_type = changeCase[transformation]( fields[field_name] ), field_name = changeCase.snakeCase(field_name); // Field that uses natural language, abstract to language tables if (data_type == 'text') { natural_language_fields.push( view.ff(field_name, data_type) ); } else { if (show_field_handling) { var msg = 'Got a direct matching data type for `' + field_name + '` with `' + data_type + '`, adding to valid fields'; gutil.log( gutil.colors.magenta(msg) ); } valid_fields.push( view.ff(field_name, data_type) ); } } else { var humanized_thing = mapper.humanized_class_transformation_match(list_of_things, fields[field_name]), native_mappings = Object.keys(view.native_mappings); if (humanized_thing != null) { // Plural? Use a UI with multiple field instances if (pluralize(field_name) == field_name) { var field_name = changeCase.snakeCase(fields[field_name]); valid_fields.push( view.ff(field_name, 'select-group') ); } else { // Got a reference to another thing, make a dropdown var route_name = changeCase.snakeCase(humanized_thing) + '.admin', table_name = pluralize( changeCase.snakeCase(humanized_thing) ); valid_fields.push( view.ff(field_name, 'select', route_name, table_name) ); } } // Got a native mapping, assign and use it else if (native_mappings.indexOf(changeCase.lowerCase(fields[field_name])) > -1) { var data_type = view.native_mappings[changeCase.lowerCase(fields[field_name])]; if (show_field_handling) { var msg = 'Got an indirect mapping of data type for `' + field_name + '` with `' + data_type + '`, adding to valid fields'; gutil.log( gutil.colors.magenta(msg) ); } valid_fields.push( view.ff(field_name, data_type) ); } else { // Invalid field invalid_fields.push( view.ff(field_name, data_type) ); } } } // If we have any natural language fields, assign specific UI if (Object.keys(natural_language_fields).length != 0) { // TODO: Add language selection with text UI } return {valid_fields, natural_language_fields, invalid_fields}; }, /* Copy base files across */ copy_base_files: function(cwd, layout_name) { if (!view.base_files_copied) { view.base_files_copied = true; var view_path = path.join('resources', 'views'), layout_path = path.join(view_path, 'layouts', layout_name), pages_path = path.join(view_path, 'pages'), error_path = path.join(view_path, 'errors'); // Layout fs.copy(path.join(cwd, 'templates', layout_path), path.join('.', layout_path), function (error) { if (error) throw error; var msg = 'Layout file/s copied successfully'; gutil.log( gutil.colors.green(msg) ); }); // Core pages fs.copy(path.join(cwd, 'templates', pages_path, 'admin'), path.join('.', pages_path, 'admin'), function (error) { if (error) throw error; var msg = 'Core page file/s copied successfully'; gutil.log( gutil.colors.green(msg) ); }); // Handler pages fs.copy(path.join(cwd, 'templates', error_path), path.join('.', error_path), function (error) { if (error) throw error; var msg = 'Handler page file/s copied successfully'; gutil.log( gutil.colors.green(msg) ); }); } }, /** * Create a view based on passed parameters */ create: function(cwd, contextName, parentContextName, formFields, df) { var view_files = ['_form', '_view', '_list', 'create', 'destroy', 'edit', 'index'], relative_path = path.join('resources', 'views'); // Open view template file view_files.forEach( function(view_file) { var filename = view_file + '.php'; fq.readFile(path.join(cwd, 'templates', relative_path, 'pages', 'resource', 'admin', filename), {encoding: defaults.encoding}, function (error, file_contents) { if (error) throw error; var viewFolder = routeName = changeCase.snakeCase(contextName) + '.admin', formElements = view.form_elements, inputTypes = view.input_types; var template_data = {viewFolder, routeName, contextName, parentContextName, formFields, formElements, inputTypes, df}; var tpl = _.template(file_contents); var view_file_contents = tpl(template_data); // Check if views folder exists (Laravel instance) fq.exists(path.join('.', relative_path), function(path_exists) { if (path_exists) { var pages_path = path.join('.', relative_path, 'pages'), view_path = path.join(pages_path, changeCase.snakeCase(contextName)), admin_path = path.join(view_path, 'admin'); // Create pages folder if it does not exist if (!fs.existsSync(pages_path)) { fs.mkdirSync(pages_path); } // Create context folder if it does not exist if (!fs.existsSync(view_path)) { fs.mkdirSync(view_path); } // Create admin folder if it does not exist if (!fs.existsSync(admin_path)) { fs.mkdirSync(admin_path); } // Write view file fq.writeFile(path.join(admin_path, filename), view_file_contents, function (err) { if (error) throw error; view.made(filename); }); } else { throw new Error( gutil.colors.red('Views folder does not exist (' + relative_path + '), did you run this in the correct folder?') ); } }); }); }); }, /* Callback for view being made */ made: function(filename) { view.counter++; if (view.traditional_logging) { var msg = 'View file ' + filename + ' created! ' + '(View ' + view.counter + ')'; gutil.log( gutil.colors.green(msg) ); } } }; module.exports = view;