als-layout

2.4.0 • Public • Published

als-layout Documentation

Library Description

What is it?

als-layout is a JavaScript library designed to simplify and enhance the process of constructing and managing web page layouts. It provides a comprehensive API for modifying HTML documents dynamically, allowing developers to add, update, and manipulate various elements such as meta tags, styles, scripts, and more.

What can you do with it and where can it be used?

The als-layout library is versatile, suitable for:

  • Building dynamic web pages that require frequent updates to their metadata, styles, or scripts.
  • Creating templating systems where multiple page layouts share similar structures but differ in content or styling.
  • Developing web applications that need to dynamically adjust their UI based on user interactions or data changes. This library is particularly useful in environments where rapid development and modular design are prioritized.

Installation and Adding

To use the als-layout library in your project, you can install it via npm and then include it in your JavaScript files:

npm i als-layout
const Layout = require('als-layout')

Change Log

  • V2.4.0

    • child components published issue fixed
    • removed throwing error for recursive components
  • V2.3.0

    • Default, component will not be included in $App, if not [publish] attribute
    • When cloning, components and other staff cloned too
      • Reference does not change
  • V2.2.0

    • fixed empty update function if no components for $App
    • if component function return string, it will element.innerHTML = string
    • Now each Layout extends Document (als-document)
    • layout.$ and layout.$$
      • Also $App.$ and $App.$$ on backend too
    • no langs validation any more
      • lang method instead
    • no layout.cached
    • charset meta tag allready exists by default
  • V2.1.0

    • updated als-document version
    • [part] attribute for static components
    • onload() method
    • bugs fixed

Basic Usage

Initialization

To start using als-layout, you first need to create a new instance of Layout. This instance will serve as the foundation for building and modifying your web page.

const Layout = require('als-layout');
const layout = new Layout();

Adding Different Elements

Once you have your Layout instance, you can easily add or modify various elements of your web page. Here are some examples of how you can use the library to customize your layout:

const layout = new Layout()
   .charset() // default UTF-8
   .viewport() // default width=device-width, initial-scale=1.0
   .title('Test title') // adding/updating title and meta[og:title]
   .favicon('/favicon.png') // adding/updating link[rel=icon][type=image/x-icon] with new href
   .keywords(['some', 'keyword']) // adding/updating meta[name=keywords]. not adding existing keywords
   .image('/main-image.png', '1.5') // adding/updating meta - og:image, twitter:image, twitter:card
   .description('Cool site') // adding/updating meta og:description, twitter:description, and description tag
   .version('1.0.0') // adds version parameter to link, script.src, and image
   .url('/some', 'http://site.com') // adding/updating meta[og:url] and link[rel="canonical"]
   .style([{body:{m:0, bgc:'whitesmoke'}}]) // adding as simple-css styles to existing/new style tag
   .style('body {margin:0; background-color:whitesmoke;}', true) // adding css styles to existing/new style tag. Second parameter is minified (default=false).
   .link('/styles.css', '2.0') // adding link[rel=stylesheet] if such href not exists
   .script({src:'/app.js'}, '', true, '3.0') // set script with src to head if such src not exists
   .script({}, 'console.log("hello world")', false) // set script with script code to footer

// Accessors for document parts
layout.body // getter for body element (if not exists, created)
layout.head // getter for head element (if not exists, created)
layout.html // getter for html Element (if not exists, created)

// Outputs
layout.rawHtml // raw HTML of the document
layout.clone // creates a new layout object clone for current object

onload

By adding onload attribute, you can run scripts for each element after dom content has loaded.

Example how it works:

const layout = new Layout().charset().viewport().title('On load').onload()
layout.body.innerHTML = /*html*/`<div onload="this.innerHTML = 'new content'">original content</div>`

Cloning Functionality

What is Cloning and Why is it Necessary?

Cloning in the als-layout library refers to creating a complete, independent copy of the existing Layout instance. This functionality is crucial when you need to generate multiple pages or versions of a page from a single base layout without affecting the original setup.

How to Use Cloning

To clone a Layout instance, simply use the clone method. This method creates a new Layout instance with the same properties and settings as the original, allowing for independent modifications without interference.

const newLayout = layout.clone;

Benefits of Cloning

  • Efficiency: Cloning is highly efficient, especially for creating pages with similar structures but different content or styles. It avoids the overhead of reinitializing and reconfiguring a new Layout instance from scratch.
  • Speed: Cloning is fast, typically taking less than 20ms even for large pages. This makes it ideal for high-performance web applications that need to dynamically generate content.
  • Isolation: Changes made to a cloned Layout do not affect the original, ensuring that each instance can be modified independently based on specific requirements.

Cloning is particularly useful in scenarios where templates or base layouts are used repeatedly with slight variations, providing a robust and scalable solution for web page generation.

Advanced Usage

The als-layout library allows for sophisticated manipulation of web page layouts, providing robust tools for creating dynamic and complex web pages. Below is an advanced example demonstrating various capabilities of the library:

const Layout = require('als-layout')

// Starting with a basic HTML template and specifying the host for URL methods
const raw = /*html*/`<html></html>`
const host = 'http://example.com';
const layout = new Layout(raw, host).lang('fr')
console.log(layout.rawHtml) 
// <!DOCTYPE html><html lang="fr"><head></p></head><body></body></html>

// Cloning the initial layout to create a specialized page
const homePage = layout.clone
homeAutoReload = layout.clone
homePage.title('Home page')
homePage.body.innerHTML = /*html*/`<h1>Home page</h1>`
console.log(homePage.rawHtml)
// <!DOCTYPE html><html lang="fr"><head><title>Home page</title><meta property="og:title" content="Home page"></head><body><h1>Home page</h1></body></html>

// Adding script that reloads the page every minute
homeAutoReload.script({}, 'setTimeout(function() { window.location.reload(); }, 60000);', false)
console.log(homeAutoReload.rawHtml)
// <!DOCTYPE html><html lang="fr"><head><title>Automatic Reload Page</title><meta property="og:title" content="Automatic Reload Page"></head><body><script>setTimeout(function() { window.location.reload(); }, 60000);</script></body></html>

// Demonstrating dynamic stylesheet linkage with versioning
const styleVersion = '1.1';
homePage.link('/css/main.css', styleVersion)
console.log(homePage.rawHtml)
// Includes link to the stylesheet with version parameter to ensure fresh cache

In this example:

  • We start with a basic HTML template and use the lang method to set the language.
  • We use the clone method to create two versions of the base layout: one for the home page and another that automatically reloads every minute.
  • We manipulate the body of the homePage to include custom HTML.
  • We add a script to homeAutoReload that sets up an automatic page reload, showcasing how to insert JavaScript dynamically.
  • We dynamically add a versioned link to a stylesheet in the homePage, demonstrating control over caching and resource management.

This advanced example illustrates how als-layout can be used to handle complex scenarios and requirements in web development, enhancing the flexibility and power at your disposal.

Rendering

Each instance of Layout comes equipped with a render method that compiles the HTML structure and embeds a JavaScript object to manage the page dynamically. This object, known as window.$App, allows for real-time interaction and updates within the page.

Structure

The layout object houses several key properties that facilitate dynamic content management:

  • layout.data: Stores the data that can be used across the page, such as state variables or configuration settings.
  • layout.components: Holds functions that define the behavior and rendering logic for components identified by specific attributes in the HTML.
  • layout.utils: Contains utility functions that can be used throughout the page for common tasks.
  • layout.actions: Methods that can be triggered by user interaction, often modifying layout.data and updating the page accordingly.

The Render Method

The render method processes all elements with a component attribute, dynamically generating their content and behavior based on the defined components. After rendering, the page includes the window.$App JavaScript object, which provides methods and properties to interact with the page elements and data:

window.$App = {
   data,              // Access to the layout data object
   components,        // Access to components functions
   utils,             // Access to utility functions
   actions,           // Access to action functions
   $(selector, parent = document),   // Equivalent to querySelector
   $$(selector, parent = document),  // Equivalent to querySelectorAll
   update(element) {  // Updates the element if it has a component attribute
       // Update logic here
   }
}

Counter Example

To demonstrate dynamic interaction, consider a counter that can be increased or decreased through user input:

const fs = require('fs')
const Layout = require('als-layout')

// Create and configure the layout
const layout = new Layout().title('Counter')
layout.data.counter = 0  // Initialize counter data

// Define a component for displaying the counter
layout.components.counter = function(element, $App) {
   element.innerHTML = `${$App.data.counter}`
}

// Define actions for increasing and decreasing the counter
layout.actions = {
   increase: () => { $App.data.counter++; $App.update($App.$('[component=counter]')); },
   decrease: () => { $We render the html page to measure and write to a document.app.data.counter--; $Page updates are shown in real-time on the rendered HTML.$App.update($App.$('[component=counter]')); }
}

// Add buttons and the counter display to the body
layout.body.innerHTML = /*html*/`
<button onclick="$App.actions.increase()">Increase</button>
<span component="counter" publish></span>
<button onclick="$App.actions.decrease()">Decrease</button>
`

// Measure render time and generate HTML
const time1 = performance.now()
const rawHtml = layout.render()
const time2 = performance.now()
console.log(`${time2 - time1}ms`) // e.g., 1.0649ms

// Write the output to a file
fs.writeFileSync('counter.html', rawHtml, 'utf-8')

Advanced Rendering Details

  • Component Indexing: Each component is assigned a componentIndex during rendering, providing a unique index within its parent component.
  • Publish Attribute: Using the publish attribute in a component make it being added to $App.components, unless it is nested within another component.

Readme

Keywords

none

Package Sidebar

Install

npm i als-layout

Weekly Downloads

192

Version

2.4.0

License

ISC

Unpacked Size

70.4 kB

Total Files

34

Last publish

Collaborators

  • alexsorkin