forked from conedevelopment/blade-filters
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
vidy
committed
Jun 7, 2022
1 parent
9108a26
commit 429f399
Showing
19 changed files
with
703 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,79 @@ | ||
# Blade Filters | ||
Laravel Blade Filters | ||
====================== | ||
|
||
Forked from [`conedevelopment/blade-filters`](https://github.com/conedevelopment/blade-filters), comparing with the original, your can resolve filters with custom resolver. | ||
- [Laravel Blade Filters](#laravel-blade-filters) | ||
- [Installation](#installation) | ||
- [Named filter arguments](#named-filter-arguments) | ||
- [Pass variables to filter arguments](#pass-variables-to-filter-arguments) | ||
- [Add simple custom filter](#add-simple-custom-filter) | ||
- [Filter provider](#filter-provider) | ||
- [Internal filters](#internal-filters) | ||
- [Testing](#testing) | ||
|
||
Originated from [`conedevelopment/blade-filters`](https://github.com/conedevelopment/blade-filters), but with huge improvements, the original doesn't support named arguments and a context for filter to run, which are essential in my case. this libary implements a custom lexer and parser to anyalize filter syntax. | ||
|
||
Because this libary is almost refactored, this package renamed as `videni/blade-filters`, but the namespace still keeps it is. | ||
|
||
## Installation | ||
|
||
``` | ||
composer require "videni/blade-filters": "^1.0@dev" | ||
``` | ||
|
||
## Named filter arguments | ||
|
||
``` | ||
{{ 'a wonderful place' | slug:separator='_', language='en' }} | ||
``` | ||
|
||
For slug filter which provided by `\Illuminate\Support\Str`, the first argument is the value being filtered, the second argument would be the `separator`, the third would be `language`, if a argument name doesn't not exists in slug method of `\Illuminate\Support\Str`, it will be simply ignored. | ||
|
||
|
||
## Pass variables to filter arguments | ||
|
||
``` | ||
$assetContextResolver = function(){ | ||
return '(isset($local_asset_context)? $local_asset_context: $base_asset_context)->'; | ||
}; | ||
BladeFiltersCompiler::extend('theme_asset_url', $assetContextResolver); | ||
BladeFiltersCompiler::extend('theme_asset_import', $assetContextResolver); | ||
{{ "hello world" | slug:separator=$separator }} | ||
``` | ||
|
||
the `$separator` will be captured where the filter runs. | ||
|
||
## Add simple custom filter | ||
|
||
For the simplest case, you can add custom filter as following | ||
``` | ||
\Pine\BladeFilters\BladeFilters::macro('script_tag', function (string $asset,$type = 'text/javascript', $async = null, $defer = null) { | ||
// Your code here | ||
} | ||
) | ||
``` | ||
|
||
Please check original repo for other documents. | ||
## Filter provider | ||
|
||
You may not need this if you just want to add [simple custom filters](#add-simple-custom-filter). | ||
|
||
The provided `StaticMacroableFilterProvider` class allows you to hook static methods and `Laravel Macroable` as Blade filters. usually, you don't need to add a `static macroable` class like `\Illuminate\Support\Str` and `\Pine\BladeFilters\BladeFilters`, but it may be helpful, if you want to support other third party utilities class. | ||
|
||
``` | ||
$registry = new BladeFilterProviderRegistry(); | ||
$registry | ||
->register(new StaticMacroableFilterProvider(\Illuminate\Support\Str::class), 10); | ||
``` | ||
|
||
Uncommonly, your filter may be context aware, let's assume a context like this: | ||
|
||
A filter named `cdn_url` which generated url for an asset. | ||
```php | ||
cdn_url('assets/carosel.css'); | ||
``` | ||
the domain of the CDN will change depending on the context where the filter run, the context itself is not part of the API of our filter, the user doen't need to worry about. this is the difference with `filter argument`. you can always pass a variable to your filter as an argument as [Pass variables to filter arguments](#pass-variables-to-filter-arguments), however, the variable must be filled by the filter's user(you or someone). | ||
|
||
## Internal filters | ||
|
||
all static methods from `Pine\BladeFilters\BladeFilters` and `\Illuminate\Support\Str` are provided as blade filters, it is quite simple, please check its source code reference. | ||
|
||
|
||
## Testing | ||
|
||
``` | ||
phpunit | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
<?php | ||
|
||
namespace Pine\BladeFilters; | ||
|
||
use Doctrine\Common\Lexer\AbstractLexer; | ||
|
||
class BladeFilterLexer extends AbstractLexer | ||
{ | ||
/** | ||
* All tokens that are not valid identifiers must be < 100 | ||
*/ | ||
public const T_NONE = 1; | ||
public const T_STRING = 2; | ||
public const T_VARIABLE = 7; | ||
public const T_LITERAL = 8; | ||
public const T_INTEGER = 9; | ||
public const T_FLOAT = 10; | ||
|
||
/** | ||
* All tokens that are also identifiers should be >= 100, | ||
*/ | ||
public const T_OPEN_PARENTHESIS = 100; | ||
public const T_CLOSE_PARENTHESIS = 101; | ||
public const T_EQUALS = 102; | ||
public const T_COLON = 103; | ||
public const T_COMMA = 104; | ||
public const T_PIPE = 105; | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
protected function getCatchablePatterns() | ||
{ | ||
return [ | ||
'\(.*?\)', | ||
//Expression | ||
|
||
'[a-z_\\\][a-z0-9_]*[a-z0-9_]{1}', | ||
// safe string | ||
|
||
"[\'\"](?:[^'\"]|'')*[\'\"]", | ||
// single or double quoted string | ||
|
||
'(?:[0-9]+(?:[\.][0-9]+)*)(?:e[+-]?[0-9]+)?', | ||
//integer, float | ||
|
||
'\$[a-z_][a-z0-9_]*(?:->[a-z_][a-z0-9_]*)*', | ||
// a variable | ||
]; | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
protected function getNonCatchablePatterns() | ||
{ | ||
/** | ||
* whitespace | ||
*/ | ||
return ['\s+']; | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
protected function getType(&$value) | ||
{ | ||
switch (true) { | ||
/** | ||
* Recognize numeric values | ||
*/ | ||
case (is_numeric($value)): | ||
if (strpos($value, '.') !== false || stripos($value, 'e') !== false) { | ||
return self::T_FLOAT; | ||
} | ||
|
||
return self::T_INTEGER; | ||
|
||
/** | ||
* Recognize quoted strings | ||
*/ | ||
case ($value[0] === '\'' || $value[0] == '"'): | ||
return self::T_STRING; | ||
/** | ||
* Recognize variables | ||
*/ | ||
case ($value[0] === '$'): | ||
return self::T_VARIABLE; | ||
|
||
/** | ||
* Recognize symbols | ||
*/ | ||
case ($value === '|'): | ||
return self::T_PIPE; | ||
case ($value === ':'): | ||
return self::T_COLON; | ||
case ($value === ','): | ||
return self::T_COMMA; | ||
case ($value === '='): | ||
return self::T_EQUALS; | ||
default: | ||
return self::T_LITERAL;; | ||
} | ||
} | ||
} |
Oops, something went wrong.