feat: recipes zip import support, add trmnlp compatible recipe configuration
Some checks are pending
tests / ci (push) Waiting to run

* recipes zip import support
* add trmnlp compatible recipe configuration
* support for multiple polling urls
This commit is contained in:
Benjamin Nussbaum 2025-06-13 12:23:52 +02:00
parent a927c0fb97
commit 414ca47cbf
17 changed files with 2409 additions and 125 deletions

View file

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace App\Liquid\FileSystems;
use Keepsuit\Liquid\Contracts\LiquidFileSystem;
/**
* A file system that allows registering inline templates defined with the template tag
*/
class InlineTemplatesFileSystem implements LiquidFileSystem
{
/**
* @var array<string, string>
*/
protected array $templates = [];
/**
* Register a template with the given name and content
*/
public function register(string $name, string $content): void
{
$this->templates[$name] = $content;
}
/**
* Check if a template exists
*/
public function hasTemplate(string $templateName): bool
{
return isset($this->templates[$templateName]);
}
/**
* Get all registered template names
*
* @return array<string>
*/
public function getTemplateNames(): array
{
return array_keys($this->templates);
}
/**
* Clear all registered templates
*/
public function clear(): void
{
$this->templates = [];
}
public function readTemplateFile(string $templateName): string
{
if (!isset($this->templates[$templateName])) {
throw new \InvalidArgumentException("Template '{$templateName}' not found in inline templates");
}
return $this->templates[$templateName];
}
}

View file

@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
namespace App\Liquid\Tags;
use App\Liquid\FileSystems\InlineTemplatesFileSystem;
use Keepsuit\Liquid\Exceptions\SyntaxException;
use Keepsuit\Liquid\Nodes\BodyNode;
use Keepsuit\Liquid\Nodes\Raw;
use Keepsuit\Liquid\Nodes\VariableLookup;
use Keepsuit\Liquid\Parse\TagParseContext;
use Keepsuit\Liquid\Render\RenderContext;
use Keepsuit\Liquid\TagBlock;
/**
* The {% template [name] %} tag block is used to define custom templates within the context of the current Liquid template.
* These templates are registered with the InlineTemplatesFileSystem and can be rendered using the render tag.
*/
class TemplateTag extends TagBlock
{
protected string $templateName;
protected Raw $body;
public static function tagName(): string
{
return 'template';
}
public static function hasRawBody(): bool
{
return true;
}
public function parse(TagParseContext $context): static
{
// Get the template name from the tag parameters
$templateNameExpression = $context->params->expression();
$this->templateName = match (true) {
is_string($templateNameExpression) => trim($templateNameExpression),
is_numeric($templateNameExpression) => (string) $templateNameExpression,
$templateNameExpression instanceof VariableLookup => (string) $templateNameExpression,
default => throw new SyntaxException("Template name must be a string, number, or variable"),
};
// Validate template name (letters, numbers, underscores, and slashes only)
if (!preg_match('/^[a-zA-Z0-9_\/]+$/', $this->templateName)) {
throw new SyntaxException("Invalid template name '{$this->templateName}' - template names must contain only letters, numbers, underscores, and slashes");
}
$context->params->assertEnd();
assert($context->body instanceof BodyNode);
$body = $context->body->children()[0] ?? null;
$this->body = match (true) {
$body instanceof Raw => $body,
default => throw new SyntaxException('template tag must have a single raw body'),
};
// Register the template with the file system during parsing
$fileSystem = $context->getParseContext()->environment->fileSystem;
if ($fileSystem instanceof InlineTemplatesFileSystem) {
// Store the raw content for later rendering
$fileSystem->register($this->templateName, $this->body->value);
}
return $this;
}
public function render(RenderContext $context): string
{
// Get the file system from the environment
$fileSystem = $context->environment->fileSystem;
if (!$fileSystem instanceof InlineTemplatesFileSystem) {
// If no inline file system is available, just return empty string
// This allows the template to be used in contexts where inline templates aren't supported
return '';
}
// Register the template with the file system
$fileSystem->register($this->templateName, $this->body->render($context));
// Return empty string as template tags don't output anything
return '';
}
public function getTemplateName(): string
{
return $this->templateName;
}
public function getBody(): Raw
{
return $this->body;
}
}