This site is built with Viewi itself. It is experimental and still in development. If you see any bugs please do not hesitate and open an issue or DM me on Twitter.

Creating Components

Creating a simple component

To create a new component all you have to do is just to create two files in your components folder: .html for template and .php for code logic.

Please note: both files should be in the same folder and should have the same base name.

Inside your php file create a class derived from Viewi\BaseComponent

For example, let's create Counter component.

viewi-app/Components/Views/Counter/Counter.php

<?php

namespace Components\Views\Counter;

use Viewi\BaseComponent;

class Counter extends BaseComponent
{
    public int $count = 0;

    public function increment()
    {
        $this->count++;
    }

    public function decrement()
    {
        $this->count--;
    }
}

viewi-app/Components/Views/Counter/Counter.html

<button (click)="decrement()" class="mui-btn mui-btn--accent">-</button>
<span class="mui--text-dark mui--text-title">$count</span>
<button (click)="increment()" class="mui-btn mui-btn--accent">+</button>

Now you can use it as a tag: <Counter />

Please note: Class name matches the tag name and therefore should be unique across all the application.

Creating a page component

Page component is a component that can be assigned as a route handler. Viewi supports routing out of the box as well as integrating with any framework's through adapter.

This means that you can create a component and assign it to a specific route. All you have to do is to add your component into viewi-app/routes.php file.

For example, let's create HomePage component.

viewi-app/Components/Views/Home/HomePage.php

<?php

namespace Components\Views\Home;

use Viewi\BaseComponent;

class HomePage extends BaseComponent
{
    public string $title = 'My Viewi Application';
}

viewi-app/Components/Views/Home/HomePage.html

<!DOCTYPE html>
<html lang="en">

<head>
    <title>$title</title>
</head>

<body>
    <div id="content">
        <h1>$title</h1>
        <Counter />
    </div>
    <ViewiScripts />
</body>

</html>

Notice <ViewiScripts /> here. It is necessary in order to enable reactivity for the Javascript part. Without it your pages will be just static HTML. But links will continue to be clickable even without Javascript.

And now let's assign it to / route.

Inside viewi-app/routes.php

use Viewi\Routing\Route as ViewiRoute;
use Components\Views\Home\HomePage;

ViewiRoute::get('/', HomePage::class);

Now when you open your site on page / you should be able to see your HomePage component.

Layouts

Almost always you will have more that one page component. In that case you probably don't want to rewrite/copy&paste the same html markup for each page. Likely for you Viewi allows you to define one common component so you will not repeat yourself. Layouts are just the same components, but from architectural perspective it allows you to use them as a wrapper around other components. For example, let's create Layout component.

viewi-app/Components/Views/Layouts/Layout.php

<?php

namespace Components\Views\Layouts;

use Viewi\BaseComponent;

class Layout extends BaseComponent
{
    public string $title;
}

viewi-app/Components/Views/Layouts/Layout.html

<!DOCTYPE html>
<html lang="en">

<head>
    <title>$title</title>
</head>

<body>
    <div id="content">
        <slot></slot>
    </div>
    <ViewiScripts />
</body>

</html>

Notice <slot></slot> here, it allows your to render content passed from parent component.

Now let's modify our HomePage component to use Layout

viewi-app/Components/Views/Home/HomePage.html

<Layout title="$title">
    <h1>$title</h1>
    <Counter />
</Layout>

All content inside Layout tag will be rendered instead of <slot></slot> inside of layout component.

Also notice title attribute on Layout tag. By doing that we can pass additional data into the component that will be assigned to the public property that matches attribute name. In this case $title from HomePage will be passed to $title property in Layout component.