PHPackages                             princejohnsantillan/weave - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. princejohnsantillan/weave

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

princejohnsantillan/weave
=========================

An elegant and easy way to format strings and stubs.

1.2.0(6mo ago)812[3 issues](https://github.com/princejohnsantillan/weave/issues)MITPHPPHP ^8.2CI passing

Since Oct 14Pushed 6mo ago1 watchersCompare

[ Source](https://github.com/princejohnsantillan/weave)[ Packagist](https://packagist.org/packages/princejohnsantillan/weave)[ RSS](/packages/princejohnsantillan-weave/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (5)Versions (30)Used By (0)

[![Weave](https://camo.githubusercontent.com/844b84ca9271e1efdd45831230698b3fa3e02b45d438288def191b9007493b0e/68747470733a2f2f62616e6e6572732e6265796f6e64636f2e64652f57656176652e706e673f7468656d653d6c69676874267061636b6167654d616e616765723d636f6d706f7365722b72657175697265267061636b6167654e616d653d7072696e63656a6f686e73616e74696c6c616e2532467765617665267061747465726e3d62616d626f6f267374796c653d7374796c655f32266465736372697074696f6e3d416e2b656c6567616e742b616e642b656173792b7761792b746f2b666f726d61742b737472696e67732b616e642b73747562732e266d643d312673686f7757617465726d61726b3d3026666f6e7453697a653d313235707826696d616765733d68747470732533412532462532466c61726176656c2e636f6d253246696d672532466c6f676f6d61726b2e6d696e2e737667267769647468733d32353026686569676874733d323530)](https://camo.githubusercontent.com/844b84ca9271e1efdd45831230698b3fa3e02b45d438288def191b9007493b0e/68747470733a2f2f62616e6e6572732e6265796f6e64636f2e64652f57656176652e706e673f7468656d653d6c69676874267061636b6167654d616e616765723d636f6d706f7365722b72657175697265267061636b6167654e616d653d7072696e63656a6f686e73616e74696c6c616e2532467765617665267061747465726e3d62616d626f6f267374796c653d7374796c655f32266465736372697074696f6e3d416e2b656c6567616e742b616e642b656173792b7761792b746f2b666f726d61742b737472696e67732b616e642b73747562732e266d643d312673686f7757617465726d61726b3d3026666f6e7453697a653d313235707826696d616765733d68747470732533412532462532466c61726176656c2e636f6d253246696d672532466c6f676f6d61726b2e6d696e2e737667267769647468733d32353026686569676874733d323530)

Requirements
------------

[](#requirements)

PHP8.28.38.4Laravel11.x12.xInstallation
------------

[](#installation)

1. Require the package.

```
composer require princejohnsantillan/weave
```

2. Publish the config.

```
php artisan vendor:publish --provider="PrinceJohn\Weave\WeaveServiceProvider"
```

Usage
-----

[](#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
---------

[](#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
------------

[](#token-syntax)

[![Token Syntax](https://private-user-images.githubusercontent.com/60916966/503243961-ecbe3a99-3b29-468c-aafe-f3d91d8f8780.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzU0ODA4MjksIm5iZiI6MTc3NTQ4MDUyOSwicGF0aCI6Ii82MDkxNjk2Ni81MDMyNDM5NjEtZWNiZTNhOTktM2IyOS00NjhjLWFhZmUtZjNkOTFkOGY4NzgwLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA0MDYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNDA2VDEzMDIwOVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTVmN2QxNDI4OGJhZWFhMDJmOTE4OGFjMDc5OWE1MjYyOWIzNTRmOWRmYmQ4NzMwNzRjOWM1NWM5OTFjZTU4YWEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.SM86YTVRMQS8PNFfFgMzFpuuhg1AJziJD0QJHqJJPc8)](https://private-user-images.githubusercontent.com/60916966/503243961-ecbe3a99-3b29-468c-aafe-f3d91d8f8780.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzU0ODA4MjksIm5iZiI6MTc3NTQ4MDUyOSwicGF0aCI6Ii82MDkxNjk2Ni81MDMyNDM5NjEtZWNiZTNhOTktM2IyOS00NjhjLWFhZmUtZjNkOTFkOGY4NzgwLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA0MDYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNDA2VDEzMDIwOVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTVmN2QxNDI4OGJhZWFhMDJmOTE4OGFjMDc5OWE1MjYyOWIzNTRmOWRmYmQ4NzMwNzRjOWM1NWM5OTFjZTU4YWEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.SM86YTVRMQS8PNFfFgMzFpuuhg1AJziJD0QJHqJJPc8)

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
-------------------------

[](#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
----------------

[](#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.

1. 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);
    }
}
```

2. Register it in the weave config file.

```
return [
    'string_functions' => [
        'emojify' => EmojifyString::class
    ],
];
```

3. 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 `FunctionDefinition` class 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 `None` class is used instead of `null` when no input string is provided to the string function.
    - A helper function `is_none($variable)` is available to check whether a variable is `None`. It works similarly to `is_null`.

Available Functions
-------------------

[](#available-functions)

All of these functions are snake\_cased and are based on Laravel's string helpers, [see here](https://laravel.com/docs/12.x/strings).

- [after](https://laravel.com/docs/12.x/strings#method-fluent-str-after)
- [after\_last](https://laravel.com/docs/12.x/strings#method-fluent-str-after-last)
- [apa](https://laravel.com/docs/12.x/strings#method-fluent-str-apa)
- [append](https://laravel.com/docs/12.x/strings#method-fluent-str-append)
- [ascii](https://laravel.com/docs/12.x/strings#method-fluent-str-ascii)
- [basename](https://laravel.com/docs/12.x/strings#method-fluent-str-basename)
- [before](https://laravel.com/docs/12.x/strings#method-fluent-str-before)
- [before\_last](https://laravel.com/docs/12.x/strings#method-fluent-str-before-last)
- [between](https://laravel.com/docs/12.x/strings#method-fluent-str-between)
- [between\_first](https://laravel.com/docs/12.x/strings#method-fluent-str-between-first)
- [camel](https://laravel.com/docs/12.x/strings#method-fluent-str-camel)
- [char\_at](https://laravel.com/docs/12.x/strings#method-fluent-str-char-at)
- [chop\_start](https://laravel.com/docs/12.x/strings#method-fluent-str-chop-start)
- [chop\_end](https://laravel.com/docs/12.x/strings#method-fluent-str-chop-end)
- [class\_basename](https://laravel.com/docs/12.x/strings#method-fluent-str-class-basename)
- [decrypt](https://laravel.com/docs/12.x/strings#method-fluent-str-decrypt)
- [deduplicate](https://laravel.com/docs/12.x/strings#method-fluent-str-deduplicate)
- [dirname](https://laravel.com/docs/12.x/strings#method-fluent-str-dirname)
- [e](https://laravel.com/docs/12.x/strings#method-e)
- [encrypt](https://laravel.com/docs/12.x/strings#method-fluent-str-encrypt)
- [finish](https://laravel.com/docs/12.x/strings#method-fluent-str-finish)
- [from\_base64](https://laravel.com/docs/12.x/strings#method-fluent-str-from-base64)
- [hash](https://laravel.com/docs/12.x/strings#method-fluent-str-hash)
- [headline](https://laravel.com/docs/12.x/strings#method-fluent-str-headline)
- [inline\_markdown](https://laravel.com/docs/12.x/strings#method-fluent-str-inline-markdown)
- [kebab](https://laravel.com/docs/12.x/strings#method-fluent-str-kebab)
- [lcfirst](https://laravel.com/docs/12.x/strings#method-fluent-str-lcfirst)
- [length](https://laravel.com/docs/12.x/strings#method-fluent-str-length)
- [limit](https://laravel.com/docs/12.x/strings#method-fluent-str-limit)
- [lower](https://laravel.com/docs/12.x/strings#method-fluent-str-lower)
- [markdown](https://laravel.com/docs/12.x/strings#method-fluent-str-markdown)
- [mask](https://laravel.com/docs/12.x/strings#method-fluent-str-mask)
- [match](https://laravel.com/docs/12.x/strings#method-fluent-str-match)
- [newline](https://laravel.com/docs/12.x/strings#method-fluent-str-new-line)
- [ordered\_uuid](https://laravel.com/docs/12.x/strings#method-str-ordered-uuid) `Generator`
- [pad\_both](https://laravel.com/docs/12.x/strings#method-fluent-str-padboth)
- [pad\_left](https://laravel.com/docs/12.x/strings#method-fluent-str-padleft)
- [pad\_right](https://laravel.com/docs/12.x/strings#method-fluent-str-padright)
- [pipe](https://laravel.com/docs/12.x/strings#method-fluent-str-pipe)
- [password](https://laravel.com/docs/12.x/strings#method-str-password) `Generator`
- [plural](https://laravel.com/docs/12.x/strings#method-fluent-str-plural)
- [plural\_studly](https://laravel.com/docs/12.x/strings#method-str-plural-studly)
- [position](https://laravel.com/docs/12.x/strings#method-fluent-str-position)
- [prepend](https://laravel.com/docs/12.x/strings#method-fluent-str-prepend)
- [random](https://laravel.com/docs/12.x/strings#method-str-random) `Generator`
- [remove](https://laravel.com/docs/12.x/strings#method-fluent-str-remove)
- [repeat](https://laravel.com/docs/12.x/strings#method-fluent-str-repeat)
- [replace](https://laravel.com/docs/12.x/strings#method-fluent-str-replace)
- [replace\_first](https://laravel.com/docs/12.x/strings#method-fluent-str-replace-first)
- [replace\_last](https://laravel.com/docs/12.x/strings#method-fluent-str-replace-last)
- [replace\_matches](https://laravel.com/docs/12.x/strings#method-fluent-str-replace-matches)
- [replace\_start](https://laravel.com/docs/12.x/strings#method-fluent-str-replace-start)
- [replace\_end](https://laravel.com/docs/12.x/strings#method-fluent-str-replace-end)
- [reverse](https://laravel.com/docs/12.x/strings#method-str-reverse)
- [singular](https://laravel.com/docs/12.x/strings#method-fluent-str-singular)
- [slug](https://laravel.com/docs/12.x/strings#method-fluent-str-slug)
- [snake](https://laravel.com/docs/12.x/strings#method-fluent-str-snake)
- [squish](https://laravel.com/docs/12.x/strings#method-fluent-str-squish)
- [start](https://laravel.com/docs/12.x/strings#method-fluent-str-start)
- [strip\_tags](https://laravel.com/docs/12.x/strings#method-fluent-str-strip-tags)
- [studly](https://laravel.com/docs/12.x/strings#method-fluent-str-studly)
- [substr](https://laravel.com/docs/12.x/strings#method-fluent-str-substr)
- [substr\_count](https://laravel.com/docs/12.x/strings#method-str-substrcount)
- [substr\_replace](https://laravel.com/docs/12.x/strings#method-fluent-str-substrreplace)
- [take](https://laravel.com/docs/12.x/strings#method-fluent-str-take)
- [title](https://laravel.com/docs/12.x/strings#method-fluent-str-title)
- [to\_base64](https://laravel.com/docs/12.x/strings#method-fluent-str-to-base64)
- [transliterate](https://laravel.com/docs/12.x/strings#method-fluent-str-transliterate)
- [trim](https://laravel.com/docs/12.x/strings#method-fluent-str-trim)
- [ltrim](https://laravel.com/docs/12.x/strings#method-fluent-str-ltrim)
- [rtrim](https://laravel.com/docs/12.x/strings#method-fluent-str-rtrim)
- [ucfirst](https://laravel.com/docs/12.x/strings#method-fluent-str-ucfirst)
- [upper](https://laravel.com/docs/12.x/strings#method-fluent-str-upper)
- [ulid](https://laravel.com/docs/12.x/strings#method-str-ulid) `Generator`
- [unwrap](https://laravel.com/docs/12.x/strings#method-fluent-str-unwrap)
- [uuid](https://laravel.com/docs/12.x/strings#method-str-uuid) `Generator`
- [uuid7](https://laravel.com/docs/12.x/strings#method-str-uuid7) `Generator`
- [word\_count](https://laravel.com/docs/12.x/strings#method-fluent-str-word-count)
- [word\_wrap](https://laravel.com/docs/12.x/strings#method-str-word-wrap)
- [words](https://laravel.com/docs/12.x/strings#method-fluent-str-words)
- [wrap](https://laravel.com/docs/12.x/strings#method-fluent-str-wrap)

Additional Functions
--------------------

[](#additional-functions)

Weave has a few additional built-in functions apart from the functions provided by Laravel.

#### **config** `Generator`

[](#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-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-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-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**

[](#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
```

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance59

Moderate activity, may be stable

Popularity11

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

29

Last Release

200d ago

Major Versions

0.11.1 → 1.0.02025-10-20

### Community

Maintainers

![](https://www.gravatar.com/avatar/4eff78899d39d79e9eaf65df18ae55e18ff4be026524d311fdb178f9f2f1d0df?d=identicon)[princejohnsantillan](/maintainers/princejohnsantillan)

---

Top Contributors

[![princejohnsantillan](https://avatars.githubusercontent.com/u/60916966?v=4)](https://github.com/princejohnsantillan "princejohnsantillan (61 commits)")

---

Tags

hacktoberfestlaravelstring-interpolationstring-manipulationstubsstringstubformatinterpolateelegant

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/princejohnsantillan-weave/health.svg)

```
[![Health](https://phpackages.com/badges/princejohnsantillan-weave/health.svg)](https://phpackages.com/packages/princejohnsantillan-weave)
```

###  Alternatives

[akaunting/laravel-money

Currency formatting and conversion package for Laravel

7825.3M18](/packages/akaunting-laravel-money)[hallindavid/manny

a package of manipulators that hopefully come in useful for those of us who always forget regex when we need it (manny is short for manipulation)

38103.3k2](/packages/hallindavid-manny)[madewithlove/laravel-nova-uuid-support

Adds uuid and other string identifier support to Laravel Nova

28132.9k](/packages/madewithlove-laravel-nova-uuid-support)[pishran/laravel-persian-string

Convert Arabic/English/etc numbers and characters to Persian numbers and characters in Laravel models.

206.7k](/packages/pishran-laravel-persian-string)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
