0.0.2 • Published 5 years ago

iwillberemovedaftertesting v0.0.2

Weekly downloads
-
License
MIT
Repository
-
Last release
5 years ago

npm.io

ui.frontend-server

Overview

Fast, flexible and extensible web-server for Component-Based architecture/applications. Best for local development and quickly provide POC for business. Based on express.js web-server. Easy way to quickly setup and start server for frontend developers, who doesn't want to spend a lot of time to do it.

How to use

Install

1) Install node and npm. 2) Create simple package.json (npm init) 3) Install ui.frontend-server as dependency for you project:

npm i ui.frontend-server --save-dev

Quick Start

1) Create demo project(structure):

npx uifrontend-server create-demo-project

2) Start server:

npm run server

3) Easiest! You can make a coffee :)

Engine

Project based on express.js web server with simple, but useful middleware.

Template engine for pages: express-dot-engine with some improvements.

Default routing based on folder/file(see below) structure under ${PROJECT_ROOT}/server/views/pages/.

Server supports pages, layouts, inheriting pages, partials, static resources, middleware, multiprojects and reusable components.

Configuration

Configuration object should be passed as a first argument into .start() function (see server/start.js).

See description and possible options in the source code: ${SERVER_SOURCE_CODE}/config/default.js

Routing based on file system

graph TD
ROOT{URL_PATH is empty or '/'?}
404(Render 'server/views/404.html')

ROOT --> |Yes| Redirect_to_defaultPageUrl( Redirect to '/index.html' )
ROOT --> |No| NoEmptyPath{URL_PATH contains '*.html?'}
NoEmptyPath --> |No| IsFolder{Folder 'server/views/pages/URL_PATH/' exists?}
IsFolder --> |No| 404
IsFolder --> |Yes| Redirect_to_defaultPageUrl_underFolder(Redirect to 'URL_PATH/index.html')
NoEmptyPath --> |Yes| Html{HTML File 'server/views/pages/URL_PATH' exists?}
Html --> |Yes| RenderPageHTML(Render it)
Html --> |No| IsIndex{Is request to 'index.html'?}
IsIndex --> |Yes| RenderIndex(Render 'server/views/index.html')
IsIndex --> |No| 404P(Render 'server/views/404.html')

Page

Overview

All server pages should be placed under server/views/pages/ folder. It can be used as a regular html page or can be generated but using built-in template engine.

Page template structure

HTML page structure contains 2 sections:

  • Configuration section: YAML at the top. Configuration object(defined between ---) available as layout object. Best practice: use it for global layout configuration(title, body classes, scripts for injection). Default values better to defined in parent page (layout option). Properties are inheritable. layout property is reserved and used for showing what is html page to use as a parent.
    Example:
        ---
        layout: '%%PATH_TO_VIEWS%%/layouts/html5.html'
        title: My Page
        bodyClass: my-page
        myCustomNumbers: [1, 2, 3]
        ---
        
        {{##myCustomBlock: 
            <!-- I will available as "layout.myCustomBlock" -->  
        #}}  
    
        {{##body:
            <h1> {{! layout.title }} </h1>
            <div class="url"> {{= page.location.path }} </div>
            <ul class="nums">
            {{~ layout.myCustomNumbers :num }}
                <li> {{! num }} </li>
            {{~}}
            </ul>
        #}}
  • Definition Blocks Section: Section with page blocks. Best Practice: Split layout with important blocks(see: server/views/layouts/ files). Each block available as property in layout global object. Example: for previous code layout object will contain: body, myCustomBlock, title, bodyClass, myCustomNumbers properties. Minimum 1 definition block (between {{##blockName: #}}) required.

Small overview about features you can find in Templates section.

API: Page object

page object provide properties for current page rendition(request). That object available in all pages under server/views/ folder and for each component (in template).

  • page.renderComponent(componentName, componentOptions) : Render component by name with component options. Example: {{= page.renderComponent('demo/hello-world', { data: 'example1' }) }} will render component src/demo/hello-world/ with data src/demo/hello-world/data-example1.json and pass { data: 'example1' } as options.
  • page.request: Express request object
  • page.response: Express response object
  • page.location: Request url object
  • page.getPageTitle(priorityTitle): Calculating page title by request url. If priorityTitle defined, then it will be used. Best practice: define priorityTitle as a yaml property at the top of the page.
  • page.resolveURL(url): Convert url from absolute to relative for request url. Example: request is: /my-project/examples/hi.html. page.resolveURL('/images/log.png') will return ./../../images/log.png.
  • page.invokeController(controllerName, ...args): Run node JS file from server/controllers/${controllerName}.js. Controller should export function. this context will be page object.
  • page.getFile(fileName): Read file. Path should be relative to server/ folder.
  • page.initComponent(componentName, componentOptions): The same as page.renderComponent, but doesn't generate html(it just create Component object).

Components

All components should be placed under src/ folder. Best practice: Place all files(related with your component) into component folder. No requirements regarding folder structure, but we recommend to use minimum 2 levels: src/${groupName}/${componentName}/. It will help in the future to customize existing components(example: will be created new version of buttons or product cards or new page will be created or redesign existing components).

Component folder structure

Only 1 required file is config.json. It should be placed in component folder. We recommend to follow next structure:

/src
    /${groupName}
        /${componentName}
            /ui <- we recommend put UI resources(js, css(less, scss), images, templates etc. what are using in browser) into "ui"  folder
                ${componentName}.js (optional)
                ${componentName}.less (.scss) (optional)
                ${componentName}.hbs (template which is using in browser) (optional)
                ...
            config.json <- JSON file with component configuration. Required.
            data-***.json <- JSON files with predefined data. Helps to prevent copy/paste data between usages. Optional.
            ${componentName}.html <- Server side component template(component rendition). Any name can be used. See "config.json > view" property. 
            ${componentName}Controller.js <- Any server side js logic related with component. Optional.
        /${componentName2}
            ...

config.json

config.json file reserved properties (see demo project: "/src/demo/header/config.json"):

  • view:(required) Path to server side component html template.
  • controller:(optional) Path to js file with server side logic related with component. File should export object(will be prototype for your component object). init() function is required, but you can add another methods for you component and then call them in template. See demo project: "/src/demo/header/HeaderController.js"
  • data:(optional. deprecated). Contains predefined data for component. Better to store data in data-***.json files.

API: Component object

component object available in component server side templates. You can extend object with controller property in config.json file.

  • component.renderComponent(componentName, componentOptions): The same as page.renderComponent(componentName, componentOptions). See: "API: Page Object" section
  • component.initComponent(componentName, componentOptions): The same as page.initComponent(componentName, componentOptions). See: "API: Page Object" section
  • component.render(): Generate HTML for component and fill with data.
  • component._getFile(filePath): Get file content. Path should be relative to component folder.
  • component.config: JSON from "config.json". See description in: config.json section.
  • component.data: JSON from "data-*.json" file or "data" value (if object) from component options. See description in: Component options** section.
  • component.name: Component name.
  • component.options: Component options (second argument in call .renderComponent(componentName, componentOptions)). See description in: Component options section.
  • component.mayCustomMethod(arg1, arg2, ...): Any method declared in object exported by js defined via "config.json > controller" property.

Component options

Any object can be passed. Reserved properties:

  • data: Dataset for component(pre filled data). Can be string or object. Accessible via component.data property.
    • string: Dataset will be read from ${componentName}/data-${dataValue}.json file. You can use @extend: "path/to/data-parent.json" notation. It helps to prevent copy-past data between json files.
    • object: Will be used as it is.

Component view (template)

Currently our system allow to use only doT.js templates. Small overview you can find in Templates section.

Next objects are available in component view:

  • page: page object. See: "API: Page Object" section.
  • component: component object. See: "API: Component Object" section.
  • data: Component data. Shortcut for component.data.
  • options: Component init options. Shortcut for component.options.
  • partial(data): Function to inject HTML from another file.

Templates

Small overview what features can be used in our page & component templates(views). Full documentation you can find here.

  • {{ js_code }}: Evaluate javascript code on server side. Example:
{{
    let myFileContent = component._getFile('./my-file.txt');
    console.log(`Request to: ${page.request.originalUrl}`);
    const rndm = Math.random() * 1000;
}}
  • {{= expression }}: Interpolation. Print expression result. Example:
File content: {{= myFileContent )) 
Random number: {{= Math.random() }}
Button component: {{= page.randomComponent('demo/button', { data: { title: 'My button' } }) }}
  • {{! expression }}: Interpolation with encoding. The same as regular interpolation, but safer(prevent script injection).
  • {{? condition }}: Conditionals. Example:
{{? data.image }} <img src="{{= data.image }}" alt="{{= data.alt}}" /> {{?}}
{{? Math.random() > 0.5 }}
    <!-- if: number is bigger than 0.5 -->
{{??}}
    <!-- else: (0.5 and lower) -->
{{?}}    
  • {{~ arrayList :item:index }} ...iteration block... {{~}}: Array iteration(arrayList.forEach(function (item, index) { ...iteration block... });). item and index can be any variables.
<ul>
{{~ ['hello', 'world', 'frontend'] :word:index }}
    <li> {{! index }} {{! word }} </li>
{{~}}
</ul>

Command Line Interface

  • create-demo-project: Create demo project.

FAQ

Will be updated. If you have any questions, you can ask with "Issues".

Features

  • File-based routing
  • Flexible templates
  • Pages
  • Layouts
  • Components
  • JSON data for components
  • Controllers
  • OOTB BrowserSync integration
  • etc.

npm.io

ui.frontend-server

0.0.3

5 years ago

0.0.2

5 years ago

0.0.1

5 years ago