princejohnsantillan / weave
An elegant and easy way to format strings and stubs.
Installs: 12
Dependents: 0
Suggesters: 0
Security: 0
Stars: 5
Watchers: 1
Forks: 0
Open Issues: 2
pkg:composer/princejohnsantillan/weave
Requires
- php: ^8.2
- illuminate/support: ^11.0||^12.0
Requires (Dev)
- larastan/larastan: ^3.7
- laravel/pint: ^1.25
- orchestra/testbench: ^10.0||^9.0
- pestphp/pest: ^v3.8
- dev-main
- 1.2.0
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.0
- 0.11.1
- 0.11.0
- 0.10.0
- 0.9.1
- 0.9.0
- 0.8.2
- 0.8.1
- 0.8.0
- 0.7.0
- 0.6.1
- 0.6.0
- 0.5.0
- 0.4.5
- 0.4.4
- 0.4.3
- 0.4.2
- 0.4.1
- 0.4.0
- 0.3.0
- 0.2.2
- 0.2.1
- 0.2.0
- 0.1.1
- 0.1.0
- dev-add-docs
- dev-improve-blank-token
- dev-improve-blank-token-support
- dev-allow-for-blank-key-and-function
- dev-rename-of-to-str
- dev-fixes
- dev-better-tests
- dev-change-token-symbols
This package is auto-updated.
Last update: 2025-10-21 11:26:50 UTC
README
Requirements
| PHP | 8.2 | 8.3 | 8.4 |
|---|
| Laravel | 11.x | 12.x |
|---|
Installation
- Require the package.
composer require princejohnsantillan/weave
- Publish the config.
php artisan vendor:publish --provider="PrinceJohn\Weave\WeaveServiceProvider"
Usage
use function PrinceJohn\Weave\weave; /** * Swap tokens using empty placeholders. */ weave('Hi {{}}!', 'George'); // Hi George! /** * Swap tokens with values from variadic parameters. */ weave('Hi {{name}}! Your role is: {{role}}', 'Prince', 'wizard'); // Hi Prince! Your role is: wizard /** * Swap tokens with values from a list. * Tokens and values are matched by index position. */ weave('Hi {{name}}! Your role is: {{role}}', ['Prince', 'magician']); // Hi Prince! Your role is: magician /** * Swap tokens with values from an associative array. * Tokens and values are matched by token name and array keys. */ weave('Hi {{name}}! Your role is: {{role}}', [ 'name' => 'John', 'role' => 'developer', ]); // Hi John! Your role is: developer /** * Swap tokens with values from a variadic associative array. * Arrays are merged from left to right and existing keys will be overwritten. */ weave('Hi {{name}}! Your role is: {{role}}', [ 'name' => 'John', 'role' => 'developer', ], [ 'name' => 'Jane', 'email' => 'jane@weaver.test', ]); // Hi Jane! Your role is: developer /** * Swap tokens with values from a nested arrays. */ weave('{{ user.name=headline }}: {{user.role=upper}}', [ 'user' => [ 'name' => 'Prince-John', 'role' => 'staff', ], ]); // Prince John: STAFF /** * Reuse an input value in the same string. */ weave('I am big: {{name=upper}}! I am small: {{name=lower}}.', [ 'name' => 'JoHn', ]); // I am big: JOHN! I am small: john. /** * Transform a string. */ weave('{{text=lower}}', ['CAN YOU HEAR ME?']); // can you hear me? /** * Compound string transformations. */ weave('{{title=kebab|upper}}', ['This is breaking news']); // THIS-IS-BREAKING-NEWS /** * Provide string transformations with a parameter. */ weave('{{controller=append:Controller|studly}}', ['controller' => 'user']); // UserController /** * Generate the current datetime string. */ weave('Today is {{=now:Y-m-d}}!'); // Today is 2025-10-16!
Use Cases
Weave is an alternative way of formatting strings. It can do what sprintf and vsprint do.
But where weave really shines is in scenarios where control is predominantly on the template string side — for example, in stubs or email templates.
Since weave allows for custom string functions, template strings can be empowered with application-specific string transformations/generators.
Token Syntax
Since =, |, :, and , are reserved characters delimiting functions and parameters, you will have to escape them if you
want to pass them as a parameter input; like this \=, \|, \:, or \,.
Types of String Functions
There are two types of string functions: a generator and a transformer.
Generator: This is the kind of function that does not need an input string. It creates a new string from scratch.Transformer: This is the kind of function that transforms a given input string.
Most string functions are transformers; in this document, generators will be tagged to make them easy to identify.
Custom Functions
You can also register your own custom functions. All you need to do is create a class that implements
the \PrinceJohn\Weave\Contracts\StringFunction interface and register it in the configuration file.
- Create the
String Function.
use Illuminate\Support\Str; use PrinceJohn\Weave\Contracts\StringFunction; use PrinceJohn\Weave\FunctionDefinition; use PrinceJohn\Weave\None; class EmojifyString implements StringFunction { public static function handle(FunctionDefinition $definition, None|string $string): string { $emojis = [':cool:' => '😎', ':fire:' => '🔥']; return Str::swap($emojis, $string); } }
- Register it in the weave config file.
return [ 'string_functions' => [ 'emojify' => EmojifyString::class ], ];
- Now use it!
use function PrinceJohn\Weave\weave; weave('This is {{=emojify}} and {{=emojify}}!', [':fire:', ':cool:']); // This is 🔥 and 😎!
Tips on Writing String Functions
- The
FunctionDefinitionclass provides access to the function name and parameters from the token strings.$definition->function: returns a string — the name of the function.$definition->parameters: returns an array of strings — the parameters of the function.- Helpful methods are also available in the class:
hasParameters,getParameter,getParameterOrFail,getParameters,
limitParameters,firstParameter,firstParameterOrFail.
- The
Noneclass is used instead ofnullwhen no input string is provided to the string function.- A helper function
is_none($variable)is available to check whether a variable isNone. It works similarly tois_null.
- A helper function
Available Functions
All of these functions are snake_cased and are based on Laravel's string helpers, see here.
- after
- after_last
- apa
- append
- ascii
- basename
- before
- before_last
- between
- between_first
- camel
- char_at
- chop_start
- chop_end
- class_basename
- decrypt
- deduplicate
- dirname
- e
- encrypt
- finish
- from_base64
- hash
- headline
- inline_markdown
- kebab
- lcfirst
- length
- limit
- lower
- markdown
- mask
- match
- newline
- ordered_uuid
Generator - pad_both
- pad_left
- pad_right
- pipe
- password
Generator - plural
- plural_studly
- position
- prepend
- random
Generator - remove
- repeat
- replace
- replace_first
- replace_last
- replace_matches
- replace_start
- replace_end
- reverse
- singular
- slug
- snake
- squish
- start
- strip_tags
- studly
- substr
- substr_count
- substr_replace
- take
- title
- to_base64
- transliterate
- trim
- ltrim
- rtrim
- ucfirst
- upper
- ulid
Generator - unwrap
- uuid
Generator - uuid7
Generator - word_count
- word_wrap
- words
- wrap
Additional Functions
Weave has a few additional built-in functions apart from the functions provided by Laravel.
config Generator
config allows you to pull a value from your Laravel configuration.
The key may be passed in as a variable or as a parameter.
weave('{{=config:app.name}}'); // Weave weave('{{=config}}', ['app.name']); // Weave
default Generator
default allows you to provide a default value when the input variable does not have a value.
You can also omit the parameter to remove the token when the input is missing.
weave('Hi {{name=default}}!'); // Hi ! weave('Hi {{name=default:John}}!', ['title' => 'This is not the name']); // Hi John!
now Generator
now generates the current datetime. This uses Laravel's now() method.
You can optionally pass in a parameter to define the format.
weave('{{=now}}'); // 2025-10-17 12:45:57 weave('{{=now:Y-m-d}}'); // 2025-10-17
str Generator
str generates a string based on the given parameter.
It generates an empty string if no parameter is provided.
weave('{{=str}}'); // "" weave('{{=str:Hey|upper}}'); // HEY
required
By default, if a token cannot be matched with a value, the token is left as is.
required allows you to change this behavior and make it throw an exception instead.
weave('Hi {{name=required}}!'); ‼️ RequiredStringException weave('Hi {{name=required}}!', ['age' => '1']); ‼️ RequiredStringException