Viewi Versions Save

Unique and efficient front-end framework for PHP

v2.3.2

2 weeks ago

v2.3.2

  • New configuration options
  • mounting hook
  • Router lazy groping

Full Changelog: https://github.com/viewi/viewi/compare/v2.3.1...v2.3.2

v2.3.1

1 month ago

v2.3.0

1 month ago

v2.3.0

Breaking changes

  1. IViewiBridge::request has changed to allow linking with the parent context:
function request(Request $request): mixed; // old
function request(Request $request, Engine $currentEngine): mixed; // new 
  1. HTTP client error handler signature has changed and now accepts Response object as a parameter:
class ContentPage extends BaseComponent
{
    use HasLocalization;
    public string $title = 'Loading..';
    public ?PageModel $page = null;
    public bool $notFound = false;

    public function __construct(private HttpClient $http, private ClientRoute $route)
    {
    }

    public function init()
    {
        $this->http->get("/api/content?path={$this->route->getUrlPath()}")
            ->then(function (?PageModel $page) {
                $this->page = $page;
                $this->title = $this->page->MetaTitle ? $this->page->MetaTitle : $this->page->Title;
            }, function (Response $response) {
                if ($response && $response->status) {
                    if ($response->status === 404) {
                        $this->notFound = true;
                        $this->title = $this->localization->t('layout.page-not-found');
                        $this->route->setResponseStatus($response->status);
                    }
                }
            });
    }
}

New features

  • Engine set and getIfExists methods for more convenient integration:
getIfExists(string $name);
set(string $name, $mixed);
  • Subscriber - consume/provide data in publish/subscribe manner:
#[Singleton]
class AuthService
{
    private Subscriber $userSubscriber;

    public function usage()
    {
        // create
        $this->userSubscriber = new Subscriber();
        // pusblish value
        $this->userSubscriber->publish($this->userSession);
        // subscribe
        $subscription = $this->userSubscriber->subscribe(function (UserSession $user) { /** use it **/});
        // unsubscribe
        $this->userSubscriber->unsubscribe($subscription);
    }
  • ClientRoute::urlWatcher - watch URL change and get notified:
    public function __construct(private ClientRoute $route)
    {
    }

    public function init()
    {
        $this->pathSubscription = $this->route->urlWatcher()->subscribe(function (string $urlPath) {
            $this->activeLink = $urlPath;
        });
  • Nullsafe property fetch support for JavaScript transpiler. Ex.: $user?->Name converts to user?.Name
  • Unset, --$i, ++$i support for JavaScript transpiler.
  • Explicit array type support for JavaScript transpiler. private array $list = /* @jsobject */ []; converts to list = {};
  • Reference support for child component.
class ValidationMessage extends BaseComponent
{
    publis string $error = '';
}
Order details:
...
Errors:
<ValidationMessage #validationMessages />
class OrderEdit extends BaseComponent
{
    public ?ValidationMessage $validationMessages = null;
    
    public function validate()
    {
        // ...
        $this->validationMessages->error = 'Something happend';
  • Dependency injection scopes for parent/child relationship.

Provide a new instance with #[Inject(Scope::COMPONENT)]:

class ActionForm extends BaseComponent
{
    public function __construct(
        #[Inject(Scope::COMPONENT)]
        private FormContext $form
    ) {
    }

Use provided instance with #[Inject(Scope::PARENT)]:

class TextInput extends BaseComponent
{
    public function __construct(
        #[Inject(Scope::PARENT)]
        private ?FormContext $form = null
    ) {
    }

Alternative usage, provide with $this->provide:

class ActionForm extends BaseComponent
{
    public function init()
    {
        $this->formContext = new FormContext();
        $this->provide(ActionForm::class, $this->formContext);
    }

Use provided instance with $this->inject:

class TextInput extends BaseComponent
{
    public function init()
    {
        /**
         * @var ?FormContext $formContext
         */
        $formContext = $this->inject(ActionForm::class);
    }
  • preg_match JavaScript version.
  • Improved foreach directive.
  • array_filter JavaScript version.
  • ClientRoute::setResponseStatus to provide the response status code at runtime.
  • Start up actions support with IStartUp:
#[Singleton]
class Localization implements IStartUp
{
    private array $resources = /* @jsobject */ [];

    public function __construct(private HttpClient $http)
    {
    }

    // execute the action on application start up
    public function setUp()
    {
        $this->http->get("/api/locale-resource/1")
            ->then(function ($resources) {
                $this->resources = $resources;
            }, function () {
                // error
            });
    }
  • Global methods support with #[GlobalEntry]:

Example:

#[Singleton]
class Localization implements IStartUp
{
    private array $resources = /* @jsobject */ [];

    #[GlobalEntry]
    public function t(string $key, ?array $params = null)
    {
        $text = $this->resources[$key] ?? $key;
        if ($params !== null) {
            foreach ($params as $key => $value) {
                $text = str_replace("{{$key}}", $value, $text);
            }
        }
        return $text;
    }
}

Use it anywhere in the template

<h1>
    {t('email.layout.title')}
</h1>
  • Dependency injection for properties with #[Inject(Scope)]:
class MyPage
{
    #[Inject(Scope::SINGLETON)]
    public Localization $localization;
}
  • Trait support:
trait HasLocalization
{
    #[Inject(Scope::SINGLETON)]
    public Localization $localization;
}
class ContentPage extends BaseComponent
{
    use HasLocalization;

    public function init()
    {
        //...
        if ($pageNotFound) {
              $this->title = $this->localization->t('layout.page-not-found');
          }
    }
}

Full Changelog: https://github.com/viewi/viewi/compare/v2.2.4...v2.3.0

v2.2.4

4 months ago

v2.2.4

  • Fixed bug with foreach order mismatch

Full Changelog: https://github.com/viewi/viewi/compare/v2.2.3...v2.2.4

v2.2.3

4 months ago

v2.2.3

  • Default bridge: added support for JSON data in external HTTP calls.

Full Changelog: https://github.com/viewi/viewi/compare/v2.2.2...v2.2.3

v2.2.2

4 months ago

v2.2.2

  • Added support for SVG Xlink attributes:
<svg class="bi pe-none " width="16" height="16">
    <use xlink:href="#home" />
</svg>

Full Changelog: https://github.com/viewi/viewi/compare/v2.2.1...v2.2.2

v2.2.1

4 months ago

v2.2.1

  • Fixed bug with viewi bin -a argument

Full Changelog: https://github.com/viewi/viewi/compare/v2.2.0...v2.2.1

v2.2.0

4 months ago

v2.2.0

Bug fix release

  • Fixed external request SSR

Full Changelog: https://github.com/viewi/viewi/compare/v2.1.1...v2.2.0

v2.1.1

4 months ago

v2.1.1

What's Changed

Full Changelog: https://github.com/viewi/viewi/compare/v2.1.0...v2.1.1

v2.1.0

4 months ago

v2.1.0

Bug fix release with improvements for NPM watch and build.

Full Changelog: https://github.com/viewi/viewi/compare/v2.0.3...v2.1.0