Skip to content

Commit

Permalink
Implement named argument
Browse files Browse the repository at this point in the history
  • Loading branch information
vidy committed Jun 7, 2022
1 parent 9108a26 commit 429f399
Show file tree
Hide file tree
Showing 19 changed files with 703 additions and 75 deletions.
80 changes: 72 additions & 8 deletions README.md
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
```
15 changes: 9 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
{
"name": "conedevelopment/blade-filters",
"name": "videni/blade-filters",
"description": "Use filters easily in your blade templates.",
"type": "project",
"license": "MIT",
"authors": [
{
"name": "Vidy Videni",
"email": "videni@foxmail.com"
},
{
"name": "Cone Development",
"email": "hello@conedevelopment.com"
Expand All @@ -20,13 +24,12 @@
}
},
"require": {
"php": "^7.3 || ^8.0",
"illuminate/support": "^8.0 || ^9.0",
"illuminate/view": "^8.0 || ^9.0"
"php": "^7.2.5 | ^8.0",
"illuminate/support": "^6.0|^7.0|^8.0|^9.0"
},
"require-dev": {
"laravel/laravel": "9.x-dev",
"phpunit/phpunit": "^9.5"
"laravel/laravel": "^6.0|^7.0|^8.0|^9.0",
"phpunit/phpunit": "^9.0"
},
"extra": {
"laravel": {
Expand Down
105 changes: 105 additions & 0 deletions src/BladeFilterLexer.php
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;;
}
}
}
Loading

0 comments on commit 429f399

Please sign in to comment.