ace-clir

Ace CLI is a modern framework to build awesome static websites using customized components

Usage no npm install needed!

<script type="module">
  import aceClir from 'https://cdn.skypack.dev/ace-clir';
</script>

README

Social Media & Contacts

Facebook https://www.facebook.com/mayukhchakrabortyweb
Instagtam https://www.instagram.com/pgmayukh/
Email kismotechindia@gmail.com


Welcome to Ace Framework!

Ace is a modern framework to build static websites a lot faster using features like components, variables, packages and more

This version of Ace is the next generation of Delta-CLI [https://npmjs.com/packages/delta-cli] updated to comply to faster changes and build times

Features to note in Ace

Ace has a lot of new features to offer, some of them includes

  • JIT Compiler with 4x faster build times
  • On-demand updates to reduce unnessesary updates
  • XHTML Supporting custom single tags
  • Conditional rendering using for loops, if and else
  • Subfolder capturing support

And many more down the road!

Getting started using Ace

Ace is very easy to get started with. To create a new project, you can use two commands

Creating a new Project using the create command

$ ace create <app_name>

This will create a new project inside of a folder named app_name

Initializing a new Project using init command

$ ace init

This will initialize the current working directory to a valid ace app

Building the app

After writing the app, you also have two options on how you can build the app

Build the app using build command

$ ace build

This will build the entiere app ready for production inside the build folder of the app

Building the app using watch command

$ ace watch

This command watches for changes and build your app on-demand.

It is also the recommended option because it also launches a live-reloaded webserver that can be accessed from the browser

Ace Basics

This section is a small documentaion of the entiere application, how it works and how should one approach it

The Components

The components are the core of the entiere app.

To create a component, simply create a html file, eg example.html inside the components folder

Now you can use this component inside any page, template or other component.

Let's use this inside page.html

components/example.html

<p>Hello World</p>

pages/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello World</title>
</head>
<body>
    <!--The component goes below-->
    <example />

</body>
</html>

It is this easy!

Component Props

You can pass properties to the components using attributes that can be interpolated for the component itself

Let's see an example

components/example.html

<p>{ msg }</p>

pages/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello World</title>
</head>
<body>
    <!--The component goes below-->
    <example msg="Hello World" />

</body>
</html>

You can have as many properties you want inside a component

Child elements

So far, we saw that components are singletags, but they can have closing tag as well if they have some children

Let's see an example

components/example.html

<p>Hello World</p>
<div>
    { children }
</div>

pages/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello World</title>
</head>
<body>
    <!--The component goes below-->
    <example>
        <h1>Hi! I am a child of example</h1>
    </example>

</body>
</html>

As you can see, anything within a custom tag is treated as it's children and it can be accessed by the children variable

Subfolders and deep components

Sometimes you might want to group or re-organize your components. Let's say you have some components that are related to working on navigation.

You can create a subfolder inside the components folder, and for our case, we will call the folder navigation.

Let's see an example

components/navigation/head.html

<div>
    <p>Home</p>
    <p>Contacts</p>
    <p>Downloads</p>
</div>

But how are we going to use this? Ace followes a very simple convention, the dash separator

In dash separator, we seperate the subfolders from individual html files

Like if you want to represent a file in directory, we use the slash convention directory/subsirectory/file.bin

Similarly the name of the component will be directory-subdirectory-component

the .html will not be used since it is a component. We will also not use the folder components as it is the default search folder for Ace

Let's see how er can use the above component

pages/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello World</title>
</head>
<body>
    <!--The component goes below-->
    <navigation-head />

</body>
</html>

And the same rule applies for props and children

Recursion

Ace prohibits recursion of components because it is absolutely not needed.

But there are caveats that the Ace engine cannot detect without loosing performance

Like for example

components/example.html

<name />

components/name.html

<example />

You can start to see the problem here, the engine will stuck inside an infinite recursion loop ultimately crashing with error logs, so try to avoid double references

Notes

  • You can use components in any file ( pages, templates, other components )

  • The component dash conventions always follow a fixed path from components folder everywhere, and it is not relative, so the path will refer to the same components regardless of scope

  • A folder and a component name can have dashes as well, but it is not recommended since it can cause confusion

Templates

Templates are like components, but it works the opposite way. You insert a page content inside a template, and that template is rendered as the file itself.

You may use templates to share re-usable pieces of code, Like the HTML boilerplate code, which instead of being repeated, can be moved to a template and reused.

Components cannot use templates, but templates can use components inside them.

Let's see an example

templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello World</title>
</head>
<body>
    
    { children }

</body>
</html>

pages/index.html

<index>
    <div>Hello World</div>
</index>

As you can see, the { children } variable holds the internal data.

Templates can be made inside subfolders as well, using the dash convention and can even accept attributes

Variables [NEW]

Ace introduced custom variables that can be created and re-used throughout the page and components.

To create a variable, you need to use the type of variable and name, with it's value inside

Let's create a few variables

<string name>Hello World</string>

<int a>10</int>

<array myarray>[10, 20, 30]</array>

<define myobject>{ "name": "Mayukh" }</define>

<bool type>true</bool>

You can access these like normal variables, i.e { myarray }

This is powered by JS engine, meaning you can use internals as well, like

{ myarray[0] } and { myobject.name }

Variables defined in a page cascades to a component as well, meaning all the variables are available in component if it is defined in the page

Conditional Rendering [NEW]

You can loop over an array, string or object using the new <for> tag.

Let's see some example

<array myarray>[10, 20, 30]</array>

<for i="myarray">
    <div>{ i }</div>
</for>

Here, the variable i is an iterator, returning individual values of the array

For object, the iterator returns another object with keys and values

<define myobject>{ "name": "Mayukh" }</define>

<for i="object">
    <div>{ i.key } : { i.value }</div>
</for>

Variables are immutable and cannot be changed.

You can also check if a variable is false, undefined or null using the new <if> tag

You can use if-else pair

<if variable>
    <!--if true-->
</if>
<else>
    <!--if not true-->
</else>

or just only if statement

<if variable>
    <!--if true-->
</if>

If there is an else tag without if tag, it will not be parsed and will be ignored

Packages

You can now install packages to add custom component logic directly into your project

Thank you for reading the docs