承接 spintax/core 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

spintax/core

Composer 安装命令:

composer require spintax/core

包简介

Framework-agnostic spintax engine: enumerations, permutations, variables, conditionals, plural agreement, includes and a post-processing pipeline. Zero dependencies.

README 文档

README

CI Packagist License: MIT

A framework-agnostic spintax engine for PHP. Zero dependencies, PHP 8.0+.

This is the engine behind the Spintax WordPress plugin and @spintax/core on npm — extracted, so it can be used from any PHP application.

use Spintax\Core\Render\Pipeline;

echo (new Pipeline())->render(
    'Hola %name%, {tenemos|traemos} [<, > ofertas|novedades|precios] para ti. ' .
    '{plural 3: producto|productos}.',
    ['name' => 'Ana'],
    locale: 'es_ES',
);

// Every render is a different variant of the same message:
//   Hola Ana, tenemos ofertas, novedades, precios para ti. Productos.
//   Hola Ana, traemos novedades, precios, ofertas para ti. Productos.

Why another one

Most PHP spintax libraries parse {a|b|c} and stop there. That is a replacement primitive, and it is enough only until your copy needs to agree with itself:

{a|b|c} […] permutations %vars% conditionals plural agreement #include prose clean-up
typical spintax libs
spintax/core

Plural agreement is the one people discover late. %n% {товар|товара|товаров} picks a form at random — which is wrong for 1, wrong for 3, and wrong for 5. Russian, Ukrainian and Polish content cannot be generated correctly without a number-gated form; this engine has one.

Install

composer require spintax/core

Syntax

construct meaning
{a|b|c} enumeration — pick one. Nests: {a|{b|c}}
[a|b|c] permutation — pick N, shuffle, join
[<minsize=2;maxsize=3;sep=", ";lastsep=" and "> a|b|c] configured permutation
%var% variable reference (case-insensitive)
#set %var% = value local variable; enumerations inside collapse once, so every reference sees the same value
{?VAR?then|else} conditional — {?!VAR?…} inverts it
{plural <count>: one|few|many} plural agreement by grammatical bucket (RU/UK/BE 3-form, EN-style 2-form)
#include "name" embed another template
/# … #/ comment, stripped from the output

Full reference with a live playground: spintax.net/docs/syntax.

Includes

Fetching a template is I/O, so it belongs to your application. Everything around the fetch — recursion, cycle detection, depth and fan-out budgets, and scope isolation — stays in the engine, so a naive host cannot hang itself:

$pipeline = new Pipeline(
    globals: ['brand' => 'Acme'],
    source: fn (string $name): ?string => $repository->rawTemplate($name),
);

echo $pipeline->render("Intro.\n#include \"footer\"");

A nested template inherits globals and runtime variables, but never the parent's #set locals — it defines its own. A circular include resolves to nothing rather than looping.

Validation

use Spintax\Core\Engine\Validator;

$result = (new Validator())->validate($template);
// $result['errors'] — line/column diagnostics: unbalanced brackets, bad plural arity, unknown includes…

Deterministic output

Inject the RNG and a render becomes reproducible — which is what makes the test suite below possible:

use Spintax\Core\Engine\Parser;

$always_first = new Parser(fn (int $min, int $max): int => $min);
$pipeline     = new Pipeline($always_first);

The parity contract

The same spintax syntax is implemented three times: here, in @spintax/core (TypeScript), and in the WordPress plugin. They are held together by a shared golden corpus — one set of JSON fixtures that every engine must reproduce.

This package's test suite is that corpus, run against the shipped Pipeline. Not a replica of it, not a subset: the same file the TypeScript engine is tested against. If a fixture goes red here, the engines have diverged, and that is the point.

git clone https://github.com/investblog/spintax-js ../spintax-js
SPINTAX_FIXTURES=../spintax-js/packages/conformance/fixtures vendor/bin/phpunit

Deliberately not here

Caching, template storage, settings, and output sanitisation. render() returns pre-sanitise text; a host emitting HTML must run its own sanitiser over it (the WordPress plugin applies wp_kses_post()). Those are host concerns, and an engine that guesses at them is an engine you have to fight.

Also available

License

MIT © 301st

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-07-13

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固