php-web-component-ssr · packagist slogsdon/web-component-ssr
Template in. HTML out.
One PHP file of functions. It reads a custom element's template from disk, fills the template's slots with whatever data you pass, and prints two things: a placeholder for the browser to find, and the template the client half will clone.
the two functions you call
plus one settergetTemplate($name, $data = null)- Prints the server-side half: a
divcarryingdata-template="$name", the template's children moved into it, and — when you pass data — a URL-encodeddata-initial-dataattribute. getClientTemplate($name, $data = null)- Prints the client-side half: the raw template file as a
templateelement withid="template-$name". The hydration library looks the element up by that id. templateLocation($directory = null)- Tells the package where template files live. It keeps the path in a static variable, so call it once before rendering; with no argument it returns the current directory.
Both readers funnel through getTemplateSource($name, $data = []), which
includes <template-location>/<name>.html with $data
extracted into scope, so a template file is ordinary PHP-flavoured HTML. A missing
template file returns an empty string rather than failing.
install
composer + one npm packageThe README's requirements list is short: PHP 7.1+, Composer for the autoloader only,
and web-component-hydration for the client half.
composer.json requires ext-dom and ext-json —
no runtime libraries — and PSR-4 autoloads WebComponentSSR\ from
src/, loading src/functions.php eagerly.
There is no tagged release. Packagist lists the package as
slogsdon/web-component-ssr with exactly one version, dev-master,
pointing at the same commit this page quotes. The README does not give a
composer require line, so none is printed here: a stable constraint would
not resolve.
What the README does document is running the demo. Both lines are quoted exactly:
cd examples/simple && yarn install
cd ../.. && composer start
The second line runs the package's Composer script, which is @php -S 0.0.0.0:5000
-t examples/simple: PHP's built-in server on port 5000, serving the demo
directory. composer test runs Psalm, the only dev dependency
(vimeo/psalm ^3.4).
The yarn install is for the demo's own
examples/simple/js/package.json, which depends on
web-component-hydration@^1.0.0; its lockfile resolves that to 1.0.5. The
demo imports the package by relative path —
./node_modules/web-component-hydration/helpers.js — so there is no bundler
and no build step.
the demo, end to end
two elements, one nestingexamples/simple/index.php sets the template directory and then renders
x-list-item inside x-list, hands the page a client template
for each, and loads the module script. The two calls, quoted:
<?php
WebComponentSSR\templateLocation(__DIR__ . '/js/templates');
?>
<!-- server rendered -->
<?= getTemplate('x-list', getTemplate('x-list-item', ['label' => 'content', 'foo' => 'bar'])); ?>
<!-- client template -->
<?= getClientTemplate('x-list'); ?>
<?= getClientTemplate('x-list-item'); ?>
The templates are plain HTML files in examples/simple/js/templates/,
x-list.html holding <ul><slot></slot></ul>
and x-list-item.html holding
<li><slot name="label"></slot></li>, each wrapped in a
<template>.
What it produced. Running those two calls on PHP 8.5.11, with
templateLocation() pointed at the demo's templates, printed the following.
It is verbatim apart from a trailing newline; the long
data-initial-data value is one line in the output.
<div data-template="x-list" data-initial-data="%3Cdiv+data-template%3D%22x-list-item%22+data-initial-data%3D%22%257B%2522label%2522%253A%2522content%2522%252C%2522foo%2522%253A%2522bar%2522%257D%22%3E%0A++%3Cli%3E%0A++++%3Cslot+name%3D%22label%22%3Econtent%3C%2Fslot%3E%0A++%3C%2Fli%3E%0A%3C%2Fdiv%3E%0A">
<ul>
<slot><div data-template="x-list-item" data-initial-data="%7B%22label%22%3A%22content%22%2C%22foo%22%3A%22bar%22%7D">
<li>
<slot name="label">content</slot>
</li>
</div>
</slot>
</ul>
</div>
And the client template for x-list-item:
<template id="template-x-list-item">
<li>
<slot name="label"></slot>
</li>
</template>
reading the output
worth knowing before you use itThe data shape decides which slots fill. A string fills only the
unnamed slot, inserted as an XML fragment — that is why the outer
x-list slot holds the child element's markup. An array fills only
named slots, one text node each, and leaves an unnamed slot empty. The demo
passes foo => 'bar' to x-list-item, whose template declares
only slot name="label", so that key goes unused here; the hydration
library's README shows a template that declares both.
The placeholder copies the template, minus its id.
getTemplate() moves the template's children into the new
div and copies every attribute except id. So the content is
real, visible light DOM until a script replaces it.
Encoding. String data is passed to urlencode() before it
becomes data-initial-data; arrays go through json_encode()
first. The client half undoes both.
A deprecation notice on current PHP. The same run printed
mb_convert_encoding(): Handling HTML entities via mbstring is deprecated,
naming src/CustomHTMLElement.php line 38. The output above was still
produced. The README's stated floor is PHP 7.1; this was PHP 8.5.11, and nothing in
the repository was changed to silence the notice.
No declarative shadow DOM. The printed markup contains no
<template shadowrootmode>; the shadow root arrives later, when the
client half constructs the element.
where to go
the other half-
Hydration in the browser
What consumes the
divand thetemplateprinted above. -
The three tools
How the pieces fit, and what none of them claims.
-
Source on GitHub
src/functions.php,src/CustomHTMLElement.php, andexamples/simple. -
Packagist
One version:
dev-master.