Packages
A Liaison package wraps together a bunch of fuctionality into a single directory and integrates seamlessly with Liaison.
A Liaison package includes addons, public files (routes), views, methods, hooks, configuration, a bootsrap file, custom Package subclass and more (or less!). A most basic package will typically include public files and views.
Most Liaison features can be accessed without using a package, such as if you just want to add a route or two, but Packages are generally recommended for building Liaison-powered websites. If you're integrating existing Liaison packages into a non-Liaison website, you likely won't create your own package.
There is a base package class, but most Liaison packages will extend from the Server
package subclass, and this documentation is geared toward that Server subclass.
Note: The Server Package is not to be confused with the Server Addon. The addon compiles requests and processes routes. The package class puts together packages.
Related: Views, Routes, Addons, Package Base Class, Server Package Subclass, Redirect Addon, Server Addon
Docs
- Useful Methods
- Initialize a package
- Directory Structure
- Configs (config.json)
- bootstrap.php
- Subclassing Server Package
Useful Methods
-
$package->dir('/rel-dir/')
gets the path to a directory within the package. Does NOT remove any path traversal or double-slashes. -
$package->url('/some-relative-url/')
prepends the package's base_url and returns a full path (no domain). Any double-slashes are removed. Does NOT remove any path traversal. -
$package->goto('/some-relative-url/')
redirects to a path within$package
, using the Redirect addon. (same rules asurl()
method) -
$package->config(string $key)
get a config from a package -
$package->setConfig(string $key, mixed $value)
set a configuration value
Initialize a package
A package can use the built-in Server package class or a subclass of it.
<?php
// Create your site's package, containing your routes, views, theme, addons, hooks, and more
$site_package = new \Lia\Package\Server($lia, 'vendor:namespace', __DIR__.'/Site/', '/base_url/');
// or using a subclass
$site_package = new \My\WebsitePackage($lia);
// base_url could be overwritten, but the package fqn and directory should typically be pre-defined in your package class's code.
Directory Structure
This is the structure for a typical package, with each file and directory being optional.
packages/Site/
- config.json <- Package settings
- bootstrap.php <- called right after the package is initialized. Use `$this` for your `Package`.
- public/ <- Public files to be routed to.
- index.php <- home page
- contact.php <- /contact/
- view/ <- Views
- theme.php <- site layout
- theme.css <- automatically included when theme is displayed
- addon/ <- Addons (extend \Lia\Addon)
- MarkdownSupport.php <- A custom addon to add features to Liaison
- class/ <- Point composer's autoloader to this directory. The Autoload addon within Liaison is not recommended.
Configs (config.json)
The config.json
configures some settings on a package, and provides dynamic configurability for other packages to reference. For example, an addon that enables markdown support might check if an added package set vendor:namespace.markdown_support = true
in its config.json.
Built-in configuratinos available:
{
"base_url": "/my-package/",
"fqn": "vendor:namespace",
"public_file_params": {}
}
Notes:
-
$package->config(string $key)
get a config from a package -
$package->setConfig(string $key, mixed $value)
set a configuration value -
base_url
defaults to/
, can be set inconfig.json
or can be overwritten via a paramater passed to the constructor. -
fqn
is the fully qualified name of a package -
public_file_params
areextract()
ed and exposed to public files within the package. -
2025-02-11: The
config.json
is loaded BEFORE the bootstrap is loaded, howeverbase_url
,fqn
, andpublic_file_params
are set AFTER bootstrapping.base_url
andfqn
will be overwritten by configs/constructor, whereaspublic_file_params
will bearray_merge()
d (config ovewrites same-named-keys). This implementation is likely to be changed.
bootstrap.php
If bootstrap.php
exists in the root of your package, it is called at the end of Package::__construct()
, prior to any additional setup done by the Server
package subclass.
Example boostrap.php
, adding some routes & protecting requests to /admin/
pages within it:
<?php
/**
* This file is loaded after the base Package class is initialized, before addons are loaded. For access to addons within your package, call `$this->load_addons()`. For guarantees that other packages are loaded, setup hooks here (*assuming you've loaded the main package first*).
*
* @param $this \Lia\Package the package this bootstrap file belongs to (typically a subclass)
*/
$package = $this;
$lia = $this->lia;
// Add a directory of additional routes for admin pages
\Lia\Addon\Router::from($lia)
->addDirectoryRoutes($package, \My\ClassOfConsts::DIR_ADMIN, $package->url('/admin/'),['.php']);
// `['.php']` is an array of extensions to be hidden. i.e. public2/bear.php becomes /bear/
// protect all requests to `admin/*` with a hook, only if this package is being requested.
$lia->hook(\Lia\Hooks::ROUTES_FILTERED,
function(\Lia\Obj\Route $route) use ($package){
if ($route->package() !== $package)return; // we're not filtering for other's packages.
$admin_url = $package->url("/admin/"); // we must consider the base_url if the package is portable.
if (substr($route->url(), 0, strlen($admin_url)) == $admin_url){
// current_user_is_admin() is NOT part of Liaison, but might be part of your package subclass.
if (!$package->current_user_is_admin()){
// Elsewhere, you might catch \My\Exception and display a message to the user.
throw new \My\Exception(\My\ClassOfConsts::ERR_ADMIN_REQUIRED);
}
}
}
);
Subclassing Server Package
A custom Package
class makes it easier for others to setup your package, allows you to declare properties and methods, and the constructor can serve as a bootstrapper.
Minimal Example:
<?php
namespace ReedyBear\PageCreator;
class Package extends \Lia\Package\Server {
public string $fqn = 'reedybear:page_creator';
public string $name = 'page_creator';
public function __construct(\Lia $lia, ?string $base_url=null){
parent::__construct($lia, $this->fqn, \ReedyBear\PageCreator::DIR_PACKAGE, $base_url);
// implement liaison integrations so the user of your package doesn't have to do extra work, such as automatically setting up hooks.
}
// define additional methods
}