{"id":39447280,"url":"https://github.com/princejohnsantillan/weave","last_synced_at":"2026-01-18T04:26:02.161Z","repository":{"id":318738051,"uuid":"1075808069","full_name":"princejohnsantillan/weave","owner":"princejohnsantillan","description":"An elegant and easy way to format strings and stubs.","archived":false,"fork":false,"pushed_at":"2025-10-21T11:26:48.000Z","size":154,"stargazers_count":8,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-11T14:20:08.071Z","etag":null,"topics":["hacktoberfest","laravel","string-interpolation","string-manipulation","stubs"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/princejohnsantillan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-14T02:46:33.000Z","updated_at":"2025-11-17T19:08:53.000Z","dependencies_parsed_at":"2025-10-14T15:51:41.768Z","dependency_job_id":"38860379-bb11-4e45-8b1b-e82295764253","html_url":"https://github.com/princejohnsantillan/weave","commit_stats":null,"previous_names":["princejohnsantillan/weave"],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/princejohnsantillan/weave","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/princejohnsantillan%2Fweave","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/princejohnsantillan%2Fweave/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/princejohnsantillan%2Fweave/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/princejohnsantillan%2Fweave/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/princejohnsantillan","download_url":"https://codeload.github.com/princejohnsantillan/weave/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/princejohnsantillan%2Fweave/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28529536,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T00:39:45.795Z","status":"online","status_checked_at":"2026-01-18T02:00:07.578Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","laravel","string-interpolation","string-manipulation","stubs"],"created_at":"2026-01-18T04:26:01.578Z","updated_at":"2026-01-18T04:26:02.140Z","avatar_url":"https://github.com/princejohnsantillan.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Weave](https://banners.beyondco.de/Weave.png?theme=light\u0026packageManager=composer+require\u0026packageName=princejohnsantillan%2Fweave\u0026pattern=bamboo\u0026style=style_2\u0026description=An+elegant+and+easy+way+to+format+strings+and+stubs.\u0026md=1\u0026showWatermark=0\u0026fontSize=125px\u0026images=https%3A%2F%2Flaravel.com%2Fimg%2Flogomark.min.svg\u0026widths=250\u0026heights=250)\n\n## Requirements\n|PHP|8.2|8.3|8.4|\n|---|---|---|---|\n\n|Laravel|11.x|12.x|\n|-------|----|----|\n\n\n## Installation\n\n1. Require the package.\n```php\ncomposer require princejohnsantillan/weave\n```\n\n2. Publish the config.\n```php\nphp artisan vendor:publish --provider=\"PrinceJohn\\Weave\\WeaveServiceProvider\"\n```\n\n\n## Usage\n```php\nuse function PrinceJohn\\Weave\\weave;\n\n/**\n *  Swap tokens using empty placeholders. \n */\nweave('Hi {{}}!', 'George'); // Hi George!\n\n/**\n *  Swap tokens with values from variadic parameters. \n */\nweave('Hi {{name}}! Your role is: {{role}}', 'Prince', 'wizard'); // Hi Prince! Your role is: wizard\n\n/**\n *  Swap tokens with values from a list.\n *  Tokens and values are matched by index position. \n */\nweave('Hi {{name}}! Your role is: {{role}}', ['Prince', 'magician']); // Hi Prince! Your role is: magician \n\n/**\n *  Swap tokens with values from an associative array.\n *  Tokens and values are matched by token name and array keys. \n */\nweave('Hi {{name}}! Your role is: {{role}}', [\n    'name' =\u003e 'John', \n    'role' =\u003e 'developer',\n]); // Hi John! Your role is: developer\n\n/**\n *  Swap tokens with values from a variadic associative array.\n *  Arrays are merged from left to right and existing keys will be overwritten. \n */\nweave('Hi {{name}}! Your role is: {{role}}', [\n    'name' =\u003e 'John', \n    'role' =\u003e 'developer',\n], [\n    'name' =\u003e 'Jane',\n    'email' =\u003e 'jane@weaver.test',\n]); // Hi Jane! Your role is: developer\n\n/**\n * Swap tokens with values from a nested arrays.\n */\nweave('{{ user.name=headline }}: {{user.role=upper}}', [\n    'user' =\u003e [\n        'name' =\u003e 'Prince-John',\n        'role' =\u003e 'staff',\n    ],\n]); // Prince John: STAFF\n    \n/**\n *  Reuse an input value in the same string. \n */\nweave('I am big: {{name=upper}}! I am small: {{name=lower}}.', [\n    'name' =\u003e 'JoHn',     \n]); // I am big: JOHN! I am small: john.\n\n/**\n * Transform a string.\n */\nweave('{{text=lower}}', ['CAN YOU HEAR ME?']); // can you hear me?\n\n/**\n * Compound string transformations.\n */\nweave('{{title=kebab|upper}}', ['This is breaking news']); // THIS-IS-BREAKING-NEWS\n\n/**\n * Provide string transformations with a parameter.\n */\nweave('{{controller=append:Controller|studly}}', ['controller' =\u003e 'user']); // UserController\n\n/**\n * Generate the current datetime string.\n */\nweave('Today is {{=now:Y-m-d}}!'); // Today is 2025-10-16!\n```\n\n## Use Cases\nWeave is an alternative way of formatting strings. It can do what `sprintf` and `vsprint` do.\nBut where **`weave`** really shines is in scenarios where control is predominantly on the template string side — for example, in stubs or email templates.\nSince **`weave`** allows for custom string functions, template strings can be empowered with application-specific string transformations/generators.\n\n\n## Token Syntax\n![Token Syntax](https://github.com/user-attachments/assets/ecbe3a99-3b29-468c-aafe-f3d91d8f8780)\n\nSince `=`, `|`, `:`, and `,` are reserved characters delimiting functions and parameters, you will have to escape them if you \nwant to pass them as a parameter input; like this `\\=`, `\\|`, `\\:`, or `\\,`.\n\n## Types of String Functions\nThere are two types of string functions: a **generator** and a **transformer**.\n\n- `Generator`: This is the kind of function that does not need an input string. It creates a new string from scratch.\n- `Transformer`: This is the kind of function that transforms a given input string.\n\nMost string functions are transformers; in this document, generators will be tagged to make them easy to identify.\n\n## Custom Functions\nYou can also register your own custom functions. All you need to do is create a class that implements\nthe `\\PrinceJohn\\Weave\\Contracts\\StringFunction` interface and register it in the configuration file.\n\n1. Create the `String Function`.\n```php\nuse Illuminate\\Support\\Str;\nuse PrinceJohn\\Weave\\Contracts\\StringFunction;\nuse PrinceJohn\\Weave\\FunctionDefinition;\nuse PrinceJohn\\Weave\\None;\n\nclass EmojifyString implements StringFunction\n{\n    public static function handle(FunctionDefinition $definition, None|string $string): string\n    {\n        $emojis = [':cool:' =\u003e '😎', ':fire:' =\u003e '🔥'];        \n        \n        return Str::swap($emojis, $string);\n    }\n}\n```\n\n2. Register it in the weave config file.\n```php\n\nreturn [\n    'string_functions' =\u003e [        \n        'emojify' =\u003e EmojifyString::class\n    ],\n];\n```\n\n3. Now use it!\n```php\nuse function PrinceJohn\\Weave\\weave;\n\nweave('This is {{=emojify}} and {{=emojify}}!', [':fire:', ':cool:']); // This is 🔥 and 😎!\n```\n\n\u003cins\u003e**Tips on Writing String Functions**\u003c/ins\u003e\n- The `FunctionDefinition` class provides access to the function name and parameters from the token strings.\n    - `$definition-\u003efunction`: returns a string — the name of the function.\n    - `$definition-\u003eparameters`: returns an array of strings — the parameters of the function.\n    - Helpful methods are also available in the class:  \n      `hasParameters`, `getParameter`, `getParameterOrFail`, `getParameters`,  \n      `limitParameters`, `firstParameter`, `firstParameterOrFail`.\n- The `None` class is used instead of `null` when no input string is provided to the string function.\n    - A helper function `is_none($variable)` is available to check whether a variable is `None`. It works similarly to `is_null`.\n\n## Available Functions\n\nAll of these functions are snake_cased and are based on Laravel's string helpers, [see here](https://laravel.com/docs/12.x/strings).\n\n- [after](https://laravel.com/docs/12.x/strings#method-fluent-str-after)\n- [after_last](https://laravel.com/docs/12.x/strings#method-fluent-str-after-last)\n- [apa](https://laravel.com/docs/12.x/strings#method-fluent-str-apa)\n- [append](https://laravel.com/docs/12.x/strings#method-fluent-str-append)\n- [ascii](https://laravel.com/docs/12.x/strings#method-fluent-str-ascii)\n- [basename](https://laravel.com/docs/12.x/strings#method-fluent-str-basename)\n- [before](https://laravel.com/docs/12.x/strings#method-fluent-str-before)\n- [before_last](https://laravel.com/docs/12.x/strings#method-fluent-str-before-last)\n- [between](https://laravel.com/docs/12.x/strings#method-fluent-str-between)\n- [between_first](https://laravel.com/docs/12.x/strings#method-fluent-str-between-first)\n- [camel](https://laravel.com/docs/12.x/strings#method-fluent-str-camel)\n- [char_at](https://laravel.com/docs/12.x/strings#method-fluent-str-char-at)\n- [chop_start](https://laravel.com/docs/12.x/strings#method-fluent-str-chop-start)\n- [chop_end](https://laravel.com/docs/12.x/strings#method-fluent-str-chop-end)\n- [class_basename](https://laravel.com/docs/12.x/strings#method-fluent-str-class-basename)\n- [decrypt](https://laravel.com/docs/12.x/strings#method-fluent-str-decrypt)\n- [deduplicate](https://laravel.com/docs/12.x/strings#method-fluent-str-deduplicate)\n- [dirname](https://laravel.com/docs/12.x/strings#method-fluent-str-dirname)\n- [e](https://laravel.com/docs/12.x/strings#method-e)\n- [encrypt](https://laravel.com/docs/12.x/strings#method-fluent-str-encrypt)\n- [finish](https://laravel.com/docs/12.x/strings#method-fluent-str-finish)\n- [from_base64](https://laravel.com/docs/12.x/strings#method-fluent-str-from-base64)\n- [hash](https://laravel.com/docs/12.x/strings#method-fluent-str-hash)\n- [headline](https://laravel.com/docs/12.x/strings#method-fluent-str-headline)\n- [inline_markdown](https://laravel.com/docs/12.x/strings#method-fluent-str-inline-markdown)\n- [kebab](https://laravel.com/docs/12.x/strings#method-fluent-str-kebab)\n- [lcfirst](https://laravel.com/docs/12.x/strings#method-fluent-str-lcfirst)\n- [length](https://laravel.com/docs/12.x/strings#method-fluent-str-length)\n- [limit](https://laravel.com/docs/12.x/strings#method-fluent-str-limit)\n- [lower](https://laravel.com/docs/12.x/strings#method-fluent-str-lower)\n- [markdown](https://laravel.com/docs/12.x/strings#method-fluent-str-markdown)\n- [mask](https://laravel.com/docs/12.x/strings#method-fluent-str-mask)\n- [match](https://laravel.com/docs/12.x/strings#method-fluent-str-match)\n- [newline](https://laravel.com/docs/12.x/strings#method-fluent-str-new-line)\n- [ordered_uuid](https://laravel.com/docs/12.x/strings#method-str-ordered-uuid) \u003csup\u003e`Generator`\u003c/sup\u003e\n- [pad_both](https://laravel.com/docs/12.x/strings#method-fluent-str-padboth)\n- [pad_left](https://laravel.com/docs/12.x/strings#method-fluent-str-padleft)\n- [pad_right](https://laravel.com/docs/12.x/strings#method-fluent-str-padright)\n- [pipe](https://laravel.com/docs/12.x/strings#method-fluent-str-pipe)\n- [password](https://laravel.com/docs/12.x/strings#method-str-password) \u003csup\u003e`Generator`\u003c/sup\u003e\n- [plural](https://laravel.com/docs/12.x/strings#method-fluent-str-plural)\n- [plural_studly](https://laravel.com/docs/12.x/strings#method-str-plural-studly)\n- [position](https://laravel.com/docs/12.x/strings#method-fluent-str-position)\n- [prepend](https://laravel.com/docs/12.x/strings#method-fluent-str-prepend)\n- [random](https://laravel.com/docs/12.x/strings#method-str-random) \u003csup\u003e`Generator`\u003c/sup\u003e\n- [remove](https://laravel.com/docs/12.x/strings#method-fluent-str-remove)\n- [repeat](https://laravel.com/docs/12.x/strings#method-fluent-str-repeat)\n- [replace](https://laravel.com/docs/12.x/strings#method-fluent-str-replace)\n- [replace_first](https://laravel.com/docs/12.x/strings#method-fluent-str-replace-first)\n- [replace_last](https://laravel.com/docs/12.x/strings#method-fluent-str-replace-last)\n- [replace_matches](https://laravel.com/docs/12.x/strings#method-fluent-str-replace-matches)\n- [replace_start](https://laravel.com/docs/12.x/strings#method-fluent-str-replace-start)\n- [replace_end](https://laravel.com/docs/12.x/strings#method-fluent-str-replace-end)\n- [reverse](https://laravel.com/docs/12.x/strings#method-str-reverse)\n- [singular](https://laravel.com/docs/12.x/strings#method-fluent-str-singular)\n- [slug](https://laravel.com/docs/12.x/strings#method-fluent-str-slug)\n- [snake](https://laravel.com/docs/12.x/strings#method-fluent-str-snake)\n- [squish](https://laravel.com/docs/12.x/strings#method-fluent-str-squish)\n- [start](https://laravel.com/docs/12.x/strings#method-fluent-str-start)\n- [strip_tags](https://laravel.com/docs/12.x/strings#method-fluent-str-strip-tags)\n- [studly](https://laravel.com/docs/12.x/strings#method-fluent-str-studly)\n- [substr](https://laravel.com/docs/12.x/strings#method-fluent-str-substr)\n- [substr_count](https://laravel.com/docs/12.x/strings#method-str-substrcount)\n- [substr_replace](https://laravel.com/docs/12.x/strings#method-fluent-str-substrreplace)\n- [take](https://laravel.com/docs/12.x/strings#method-fluent-str-take)\n- [title](https://laravel.com/docs/12.x/strings#method-fluent-str-title)\n- [to_base64](https://laravel.com/docs/12.x/strings#method-fluent-str-to-base64)\n- [transliterate](https://laravel.com/docs/12.x/strings#method-fluent-str-transliterate)\n- [trim](https://laravel.com/docs/12.x/strings#method-fluent-str-trim)\n- [ltrim](https://laravel.com/docs/12.x/strings#method-fluent-str-ltrim)\n- [rtrim](https://laravel.com/docs/12.x/strings#method-fluent-str-rtrim)\n- [ucfirst](https://laravel.com/docs/12.x/strings#method-fluent-str-ucfirst)\n- [upper](https://laravel.com/docs/12.x/strings#method-fluent-str-upper)\n- [ulid](https://laravel.com/docs/12.x/strings#method-str-ulid) \u003csup\u003e`Generator`\u003c/sup\u003e\n- [unwrap](https://laravel.com/docs/12.x/strings#method-fluent-str-unwrap)\n- [uuid](https://laravel.com/docs/12.x/strings#method-str-uuid) \u003csup\u003e`Generator`\u003c/sup\u003e\n- [uuid7](https://laravel.com/docs/12.x/strings#method-str-uuid7) \u003csup\u003e`Generator`\u003c/sup\u003e\n- [word_count](https://laravel.com/docs/12.x/strings#method-fluent-str-word-count)\n- [word_wrap](https://laravel.com/docs/12.x/strings#method-str-word-wrap)\n- [words](https://laravel.com/docs/12.x/strings#method-fluent-str-words)\n- [wrap](https://laravel.com/docs/12.x/strings#method-fluent-str-wrap)\n\n## Additional Functions\nWeave has a few additional built-in functions apart from the functions provided by Laravel.\n\n#### \u003cins\u003e**config**\u003c/ins\u003e \u003csup\u003e`Generator`\u003c/sup\u003e\n\n`config` allows you to pull a value from your Laravel configuration. \nThe key may be passed in as a variable or as a parameter.\n\n```php\nweave('{{=config:app.name}}'); // Weave\nweave('{{=config}}', ['app.name']); // Weave\n```\n\n#### \u003cins\u003e**default**\u003c/ins\u003e \u003csup\u003e`Generator`\u003c/sup\u003e\n`default` allows you to provide a default value when the input variable does not have a value.\nYou can also omit the parameter to remove the token when the input is missing.\n```php\nweave('Hi {{name=default}}!'); // Hi !\nweave('Hi {{name=default:John}}!', ['title' =\u003e 'This is not the name']); // Hi John!\n```\n\n#### \u003cins\u003e**now**\u003c/ins\u003e \u003csup\u003e`Generator`\u003c/sup\u003e\n`now` generates the current datetime. This uses Laravel's `now()` method.\nYou can optionally pass in a parameter to define the format.\n```php\nweave('{{=now}}'); // 2025-10-17 12:45:57\nweave('{{=now:Y-m-d}}'); // 2025-10-17 \n```\n\n#### \u003cins\u003e**str**\u003c/ins\u003e \u003csup\u003e`Generator`\u003c/sup\u003e\n`str` generates a string based on the given parameter. \nIt generates an empty string if no parameter is provided.\n```php \nweave('{{=str}}'); // \"\"\nweave('{{=str:Hey|upper}}'); // HEY \n```\n\n#### \u003cins\u003e**required**\u003c/ins\u003e\nBy default, if a token cannot be matched with a value, the token is left as is.\n`required` allows you to change this behavior and make it throw an exception instead.\n```php\nweave('Hi {{name=required}}!'); ‼️ RequiredStringException\nweave('Hi {{name=required}}!', ['age' =\u003e '1']); ‼️ RequiredStringException\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprincejohnsantillan%2Fweave","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprincejohnsantillan%2Fweave","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprincejohnsantillan%2Fweave/lists"}