Compare commits
338 Commits
Author | SHA1 | Date |
---|---|---|
Ivan Shalganov | fbf4f46f1f | |
ivan shalganov | e1601dce6c | |
ivan shalganov | 65c33ac2e3 | |
ivan shalganov | 74fbcd1534 | |
ivan shalganov | 9269c96fc3 | |
Ivan Shalganov | c7b8835ff7 | |
ivan shalganov | f8863ee0ad | |
ivan shalganov | e8647cfb02 | |
ivan shalganov | b04c38a533 | |
ivan shalganov | 3af87c3419 | |
ivan shalganov | a4fbc2a6aa | |
ivan shalganov | ba1bc18aba | |
ivan shalganov | 4cdfd306d9 | |
ivan shalganov | 84dac62a85 | |
Ivan Shalganov | 065ccaec23 | |
Ivan Shalganov | 6650668b72 | |
Anton | b24d9d9e1e | |
Anton | 5e14c6bf90 | |
Anton | 79283c6f7f | |
Ivan Shalganov | 8fb0a70311 | |
Ivan Shalganov | f3722a5f37 | |
Vitalii P | 87324033e7 | |
EMDM45 | 317c775f50 | |
Ivan Shalganov | decad1d1fa | |
Ivan Shalganov | f0cb251843 | |
Ivan Shalganov | cb1f25d8af | |
Ivan Shalganov | 5f9d01ae6f | |
Ivan Shalganov | daf9d3cb20 | |
Ivan Shalganov | 52fea74cc4 | |
Ivan Shalganov | 493fcce6e0 | |
Ivan Shalganov | 07ff960324 | |
Maxim Kostjukevich | 47fb3b5e0a | |
Maxim Kostjukevich | 4dd1e1870c | |
Maxim Kostjukevich | 55b84888e8 | |
Миша | b4ff112237 | |
Ivan Shalganov | fc188a5822 | |
OrderTarget | e4e9b2e73c | |
Maxim Kostjukevich | 5b46e54133 | |
Maxim Kostjukevich | ebbec8c6be | |
Pavel_Belousov | d477607831 | |
Ivan Shalganov | dbc9388b2f | |
Sreenadh H | 85bdf5ca94 | |
Sreenadh H | c1531ea81a | |
Ivan Shalganov | 9a1e56d164 | |
Maksim K | d141b14017 | |
Maksim K | 3c083cc0dd | |
Loki3000 | 3e1fa19c70 | |
Loki3000 | 00112bb4d5 | |
Loki3000 | 80a537de8c | |
Loki3000 | de8dbb4d53 | |
Loki3000 | 40f50d20fd | |
Maksim | 5dd197ffac | |
Maxim Kostjukevich | 7b0dab9247 | |
Георгий Попов | d8d9833ec8 | |
Max Kostjukevich | ab6c5ea47c | |
Max Kostjukevich | e251305ef5 | |
Max Kostjukevich | 999a23995f | |
Max Kostjukevich | cc2a56339d | |
sartatpdev999 | ec17a083d4 | |
sartatpdev999 | c481365d9c | |
sartatpdev999 | eedf775238 | |
Ivan Shalganov | 7b38f936c9 | |
sartatpdev999 | d7a8a2372a | |
sartatpdev999 | 9457ac60df | |
sartatpdev999 | 75c56ebe81 | |
Max Kostjukevich | cce0e578f1 | |
Max Kostjukevich | 293893a9c8 | |
sartatpdev999 | 7d9b474de1 | |
sartatpdev999 | 73bb8791a5 | |
Max Kostjukevich | 0e5d0a27cd | |
sartatpdev999 | cbab4d3184 | |
Ivan Shalganov | 2d968ab8d0 | |
Vasily Naumkin | 6a7291fac6 | |
bzick | 8730343442 | |
Ivan Shalganov | 7d0db43050 | |
bzick | 44ac3b16e5 | |
bzick | 4d9a82314b | |
bzick | 2fac2bbc9f | |
bzick | a591724d07 | |
bzick | 4666fdced5 | |
bzick | 66d9201a61 | |
bzick | abf3bd5414 | |
bzick | 902284a76b | |
bzick | 9670f0433a | |
bzick | 28b4074d66 | |
Ivan Shalganov | 449b76e554 | |
1f7 | 91c4dc611a | |
bzick | e97ef95ef5 | |
bzick | 23646edb6e | |
bzick | d139a1ebf3 | |
bzick | 35455b761f | |
bzick | b92e0bbad3 | |
Max Kostjukevich | 05cda5426d | |
bzick | cd4f688088 | |
bzick | 514b0b6769 | |
bzick | 3171d80d8b | |
Max Kostjukevich | 58f8c0facb | |
Anton Popov | d64706b675 | |
Max Kostjukevich | a4c8ae17ba | |
Igor | ade29f5d67 | |
Max Kostjukevich | aa587a6293 | |
Xesau | 0d599cb211 | |
Max Kostjukevich | f160664f0e | |
Vasily Krakovetsky | 23cf3e72ad | |
bzick | 7fffa19fa9 | |
Ivan Shalganov | eef14ecf06 | |
Ivan Shalganov | a3a84ea606 | |
bzick | 76e1b5a48c | |
bzick | f486c7d5d4 | |
bzick | c87d831189 | |
bzick | 1e724e4c70 | |
bzick | a910b71a81 | |
bzick | e357a38946 | |
bzick | 626334017b | |
bzick | 24621099bf | |
bzick | 19ba9d3031 | |
bzick | e557123e3c | |
Max Kostjukevich | 180c171b1e | |
Max Kostjukevich | 8e57ef2853 | |
Max Kostjukevich | ed1c9f4837 | |
Daisuke-sama | f8a2df3041 | |
Daisuke-sama | 36b5c213a2 | |
Max Kostjukevich | c6d6bc6e12 | |
Max Kostjukevich | c1ca6d2246 | |
Daisuke-sama | a005732286 | |
Daisuke-sama | 4d76ce7abf | |
bzick | dec06c888e | |
bzick | d23e2b4c4f | |
bzick | 32ce405de2 | |
Ivan Shalganov | 48f42c82a9 | |
Ivan Shalganov | 0d1e7e56a6 | |
bzick | f315d937a8 | |
Ivan Shalganov | 279459be55 | |
bzick | e289b9b3b1 | |
bzick | ba4ba548ff | |
Ivan Shalganov | 9d1f0c4cae | |
Anton Popov | 165d4816d6 | |
Anton Popov | bfb64f150a | |
bzick | 1559adf030 | |
bzick | 45c9f27ae6 | |
bzick | eb75ae0bbb | |
bzick | 497f2e5b4b | |
bzick | 1c73d35681 | |
bzick | d6aa777fd0 | |
bzick | 027075d7b5 | |
Max Kostjukevich | 2d3c89ec1e | |
Vasily Krakovetsky | 1a3a3739ce | |
Max Kostjukevich | 2ed57c959c | |
DaaGER | 0dfcdfbcf7 | |
Ivan Shalganov | d52aaa57a2 | |
bzick | 3766505e5c | |
Ivan Shalganov | 7668426f65 | |
bzick | 46708c6195 | |
Ivan Shalganov | 32755c3787 | |
Ivan Shalganov | 9f1bad3740 | |
zhabinka | 939a608db0 | |
Max Kostjukevich | b9ee7bf609 | |
zhabinka | de35e9addb | |
Ivan Shalganov | da9cafe4f3 | |
sin4end | 6ca82e267b | |
Ivan Shalganov | 4491176cf4 | |
Ivan Shalganov | 359cf5fbcb | |
Ivan Shalganov | 28935c0ddc | |
Ivan Shalganov | 10c8109bb5 | |
Max Kostjukevich | b82b6e7a58 | |
Ivan Shalganov | e2a3087dfa | |
bzick | 5c86d2d6ae | |
bzick | 544aa4f248 | |
bzick | 1363945716 | |
Ivan Shalganov | d596c81b4c | |
bzick | 10221b87ea | |
bzick | 4fe339ba21 | |
bzick | 213184c8a8 | |
bzick | 5da2df1eb4 | |
Ivan Shalganov | ae93c8f94a | |
maxicms | 0a8793fe7b | |
maxicms | 05e35261e4 | |
Ivan Shalganov | 6331ad44a4 | |
Andrey Mukamolow | f5d05e81a6 | |
Ivan Shalganov | 35cfda7516 | |
Alexey | f9fa4fe474 | |
Ivan Shalganov | 56dfcfc71f | |
bzick | bf44511a53 | |
bzick | bd5557925d | |
bzick | 10bc614a84 | |
bzick | 48e4931506 | |
bzick | c6dbdfff95 | |
bzick | c2751e069c | |
bzick | e0fc70b751 | |
bzick | ef4458ca10 | |
bzick | 3b56906ec8 | |
bzick | 30921d3500 | |
bzick | ec890cc819 | |
bzick | bf0a0ffedc | |
Ivan Shalganov | 0511a43539 | |
bzick | 806467453d | |
Ivan Shalganov | 86c6630243 | |
Pavel Belousov | fd777eb606 | |
Ivan Shalganov | 7f05e13725 | |
bzick | 9269b6b4ad | |
Ivan Shalganov | 034b4b7f14 | |
Anton Popov | 4d11eeed0d | |
Ivan Shalganov | 3a1da1c154 | |
bzick | c34d45698a | |
bzick | 9a725deaff | |
bzick | 83fbfb1fca | |
Ivan Shalganov | fdc6caeb20 | |
Pavel Belousov | a9f8a34aa2 | |
Ivan Shalganov | d9df706ae1 | |
Pavel Belousov | b07a9beea1 | |
bzick | 22501f3704 | |
bzick | 3db7d0b220 | |
bzick | 8f3c94a7a1 | |
Ivan Shalganov | 4dbbc81785 | |
Pavel Belousov | 89f9da8c9d | |
bzick | ed860a49cb | |
Ivan Shalganov | 45a3abed88 | |
bzick | a9b9c89f88 | |
Ivan Shalganov | 5dc7bbfd56 | |
bzick | d5417630ac | |
bzick | f985fff314 | |
bzick | a09b2f7620 | |
bzick | 89f2e23750 | |
Ivan Shalganov | 1a72b9d43e | |
Ivan Shalganov | feb3a51884 | |
bzick | 5d87060f42 | |
bzick | fb544b10e8 | |
bzick | 76b5d3e6fa | |
bzick | 4beacd57b9 | |
bzick | 0592e248e2 | |
bzick | 0339a12b3d | |
Ivan Shalganov | 1ec97221f5 | |
Ivan Shalganov | e157c08dcf | |
Ivan Shalganov | 269dd36a30 | |
Ivan Shalganov | dd6986b60f | |
bzick | e310236745 | |
Ivan Shalganov | 7e32c38db4 | |
Ivan Shalganov | 01ae6081c6 | |
bzick | 2f769c294c | |
Ivan Shalganov | 47cee02dd3 | |
bzick | 7ac11fb3cc | |
bzick | d096a80395 | |
bzick | 16d5f337c0 | |
Ivan Shalganov | e4a7a07107 | |
bzick | 5e42892979 | |
bzick | 8d6bfb00d1 | |
bzick | 22fb471c89 | |
Ivan Shalganov | 7d1b7cb691 | |
bzick | d4bfb366b8 | |
bzick | ae592d22c7 | |
Ivan Shalganov | 317bce9e19 | |
Ivan Shalganov | 964f20a914 | |
bzick | 2fbb6b44e4 | |
bzick | bc73e5b733 | |
bzick | e88d416df1 | |
bzick | 4ca7ccb5e0 | |
bzick | 22dc90943f | |
bzick | b0422ad43c | |
bzick | f532658cc4 | |
bzick | 7e8598ae3b | |
bzick | 1c439fedb7 | |
bzick | e0a3cc3a0d | |
bzick | c238053e99 | |
Ivan Shalganov | ab52186dfa | |
bzick | 0091b17c8a | |
Ivan Shalganov | d89a315d4b | |
bzick | 4b65e80312 | |
bzick | e55402c2f4 | |
Ivan Shalganov | 8259503efe | |
Ivan Shalganov | e01a474b90 | |
Shmavon Gazanchyan | 292bdd90b5 | |
Shmavon Gazanchyan | 16b1bef169 | |
Ivan Shalganov | 88a5efb7ea | |
Pavel Belousov | 435fd15a67 | |
Ivan Shalganov | cd8b466951 | |
Ivan Shalganov | 94c468032b | |
Pavel Belousov | f27ddd904e | |
Pavel Belousov | 0514d579c8 | |
Ivan Shalganov | 506fbd8909 | |
Ivan Shalganov | 94a588e494 | |
Ivan Shalganov | 57d1ca37ee | |
Ivan Shalganov | 4d89a7f3d0 | |
Ivan Shalganov | b3992033c9 | |
Ivan Shalganov | 0be8b15d68 | |
Ivan Shalganov | b842421408 | |
Ivan Shalganov | b6f363eaff | |
bzick | af7546a8ec | |
Ivan Shalganov | 8772df82db | |
Pavel Belousov | 7142641ac3 | |
Ivan Shalganov | 90e235047a | |
Pavel Belousov | 823b7fc15a | |
Ivan Shalganov | 250c9c1e1c | |
Ivan Shalganov | 8ce6779119 | |
bzick | bb8d351e93 | |
bzick | 295ad63cf1 | |
bzick | 11af8fd2c1 | |
bzick | d43887a3d8 | |
Ivan Shalganov | 4af53621e6 | |
bzick | 72b4e36585 | |
bzick | 0118ef192b | |
bzick | 7d59b0e642 | |
bzick | 469833376d | |
Ivan Shalganov | f15fbb323d | |
bzick | 3dc64aa2ce | |
bzick | 6329765572 | |
Pavel Belousov | c5217075ca | |
bzick | 0b96a02dd9 | |
bzick | 0ff3ffc27f | |
bzick | 5972884c80 | |
Ivan Shalganov | 00eaafc39f | |
bzick | 86479f6459 | |
bzick | e357dbe5f3 | |
Ivan Shalganov | eb5ba94ff9 | |
Ivan Shalganov | 05e501a096 | |
bzick | 342078b45e | |
bzick | 14bcae4fa1 | |
bzick | c52606a5ab | |
Ivan Shalganov | 9314d9ca46 | |
bakatrouble | 7ef193749b | |
bakatrouble | f7d30418b6 | |
Ivan Shalganov | ca95ce0ec7 | |
Ivan Shalganov | 87105bf683 | |
bzick | b1b88e932a | |
bzick | 97838eb0b9 | |
bzick | e6a9b511bd | |
bzick | 8e48d1aaee | |
bzick | 702dbfd88d | |
bzick | d9b21ea68c | |
Ivan Shalganov | 7422aef4de | |
Ivan Shalganov | f74ee26d95 | |
bzick | 0340915b76 | |
bzick | a4883d75e5 | |
bzick | eb49861ab8 | |
Ivan Shalganov | 8024cd614a | |
Ivan Shalganov | 19aa493474 | |
bzick | 3a6347d96b | |
Dmitry Krokhin | 89d1cae918 | |
Ivan Shalganov | ce9245cb50 |
|
@ -1,5 +1,4 @@
|
|||
service_name: travis-ci
|
||||
|
||||
src_dir: src
|
||||
coverage_clover: build/logs/clover.xml
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
Contributing
|
||||
============
|
||||
|
||||
Issue tracker
|
||||
-------------
|
||||
|
||||
The Issue tracker serves mainly as a place to report bugs and request new features.
|
||||
Please do not abuse it as a general questions or troubleshooting location.
|
||||
|
||||
For these questions you can always use the
|
||||
[fenom tag](https://stackoverflow.com/questions/tagged/fenom) at [Stack Overflow](https://stackoverflow.com/).
|
||||
|
||||
* Please provide a small example in php/html that reproduces your situation
|
||||
* Please report one feature or one bug per issue
|
||||
* Failing to provide necessary information or not using the issue template may cause the issue to be closed without consideration.
|
||||
|
||||
Pull requests
|
||||
-------------
|
||||
|
||||
Pull requests should be always based on the default [development](https://github.com/fenom-template/fenom/tree/master)
|
||||
branch except for backports to older versions.
|
||||
|
||||
Some guidelines:
|
||||
|
||||
* Use an aptly named feature branch for the Pull request.
|
||||
|
||||
* Only files and lines affecting the scope of the Pull request must be affected.
|
||||
|
||||
* Make small, *atomic* commits that keep the smallest possible related code changes together.
|
||||
|
||||
* Code should be accompanied by a unit test testing expected behaviour.
|
||||
|
||||
When updating a PR, do not create a new one, just `git push --force` to your former feature branch, the PR will
|
||||
update itself.
|
|
@ -0,0 +1,18 @@
|
|||
> Please use https://stackoverflow.com/questions/tagged/fenom for all your general questions or troubleshooting!
|
||||
|
||||
>
|
||||
> *Warning*: Failing to provide necessary information may cause the issue to be closed without consideration
|
||||
|
||||
### I found this bug / would like to have this new functionality
|
||||
|
||||
|
||||
### This is Fenom and PHP version and environment (server/fpm/cli etc) I am using
|
||||
|
||||
|
||||
### This is a template code snippet I use
|
||||
|
||||
```
|
||||
{var x=10}
|
||||
{Calc x=10 y=20}
|
||||
|
||||
```
|
|
@ -0,0 +1,31 @@
|
|||
name: PHP Composer
|
||||
|
||||
on: push
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Validate composer.json and composer.lock
|
||||
run: composer validate --strict
|
||||
|
||||
- name: Cache Composer packages
|
||||
id: composer-cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: vendor
|
||||
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-php-
|
||||
- name: Install dependencies
|
||||
run: composer install --prefer-dist --no-progress
|
||||
|
||||
- name: Run tests
|
||||
run: vendor/bin/phpunit
|
|
@ -1,17 +1,9 @@
|
|||
.idea
|
||||
vendor
|
||||
coverage
|
||||
build
|
||||
composer.lock
|
||||
composer.phar
|
||||
tests/resources/compile/*
|
||||
!.gitkeep
|
||||
tests/resources/template/*
|
||||
!.gitkeep
|
||||
sandbox/compiled/*
|
||||
!.gitkeep
|
||||
benchmark/compile/*
|
||||
benchmark/templates/inheritance/smarty
|
||||
benchmark/templates/inheritance/twig
|
||||
benchmark/sandbox/compiled/*
|
||||
!.gitkeep
|
||||
/.phpunit.result.cache
|
||||
|
|
17
.travis.yml
17
.travis.yml
|
@ -1,16 +1,21 @@
|
|||
language: php
|
||||
|
||||
sudo: false
|
||||
|
||||
php:
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 7.3
|
||||
- 7.4
|
||||
|
||||
before_script:
|
||||
- composer install --dev
|
||||
- composer global require satooshi/php-coveralls
|
||||
- composer update --quiet
|
||||
|
||||
script:
|
||||
- phpunit
|
||||
- vendor/bin/phpunit phpunit -c phpunit.xml.dist
|
||||
|
||||
after_script:
|
||||
- php vendor/bin/coveralls
|
||||
- coveralls
|
||||
|
|
147
CHANGELOG.md
147
CHANGELOG.md
|
@ -1,12 +1,153 @@
|
|||
Changelog
|
||||
=========
|
||||
## 3.0.0 (2023-02-23)
|
||||
|
||||
### 2.0.1 (2013-06-09)
|
||||
- Fenom supported php8+
|
||||
- Remove `eval` from template compiler
|
||||
- `strftime` -> `date` with fallback support.
|
||||
- update tokenizer
|
||||
- bugfixes and optimizations
|
||||
|
||||
## 2.11.0 (2016-06-09)
|
||||
|
||||
- Added method to get the name of the cache template `$fenom->getCacheName($template_name)`(#231)
|
||||
- Fix bug with before-code in template inheritance (#229)
|
||||
- Added `??` operator.
|
||||
- Improve compile mechanism
|
||||
- ++Docs
|
||||
- ++Test
|
||||
|
||||
## 2.10.0 (2016-05-08)
|
||||
|
||||
- Add tag `{do ...}`
|
||||
- ++Docs
|
||||
- ++Tests
|
||||
|
||||
## 2.9.0 (2016-05-08)
|
||||
|
||||
- Add `$.block`
|
||||
- Refactory range
|
||||
- Refactory blocks
|
||||
- Docs
|
||||
|
||||
...
|
||||
|
||||
## 2.6.0 (2015-02-22)
|
||||
|
||||
- Add range operator (`1..3`)
|
||||
- Tag `for` now is deprecated, use tag `foreach` with range
|
||||
- Internal improves
|
||||
|
||||
### 2.5.4 (2015-02-19)
|
||||
|
||||
- Fix bug #152
|
||||
- Add composer.lock to git
|
||||
|
||||
### 2.5.3 (2015-02-19)
|
||||
|
||||
- Fix bug #147
|
||||
|
||||
### 2.5.2 (2015-02-10)
|
||||
|
||||
- Fix bug: unexpected array conversion when object given to {foreach} with force verify option (pull #148)
|
||||
|
||||
### 2.5.1 (2015-02-10)
|
||||
|
||||
- Fix bugs #144, #135
|
||||
|
||||
|
||||
## 2.5.0 (2015-02-01)
|
||||
|
||||
- Internal improvement: functions accept array of template variables
|
||||
- Improve `in` operator
|
||||
- Fix bug #142
|
||||
|
||||
### 2.4.6 (2015-01-30)
|
||||
|
||||
- Fix bug #138
|
||||
|
||||
### 2.4.5 (2015-01-30)
|
||||
|
||||
Move project to organization `fenom-template`
|
||||
|
||||
### 2.4.4 (2015-01-22)
|
||||
|
||||
- Fix: parse error then modifier's argument converts to false
|
||||
|
||||
### 2.4.3 (2015-01-08)
|
||||
|
||||
- Fix #132
|
||||
|
||||
### 2.4.2 (2015-01-07)
|
||||
|
||||
- Internal improvements and code cleaning
|
||||
|
||||
### 2.4.2 (2015-01-07)
|
||||
|
||||
- Fix bug #128
|
||||
|
||||
## 2.4.0 (2015-01-02)
|
||||
|
||||
- Fix bugs #120, #104, #119
|
||||
- Add `~~` operator. Concatenation with space.
|
||||
- Improve #126. Disable clearcachestats() by default in Fenom\Provider. clearcachestats() may be enabled.
|
||||
- Improve accessors (unnamed system variable). Now possible add, redefine yours accessors.
|
||||
- ++Docs
|
||||
- ++Tests
|
||||
|
||||
### 2.3.1 (2014-11-06)
|
||||
|
||||
- Fix #122
|
||||
|
||||
### 2.3.1 (2014-08-27)
|
||||
|
||||
- Fix #105
|
||||
- ++Tests
|
||||
|
||||
## 2.3.0 (2014-08-08)
|
||||
|
||||
- Add tags {set} and {add}
|
||||
- Fix bug #97
|
||||
- ++Docs
|
||||
- --Bugs
|
||||
- ++Tests
|
||||
|
||||
### 2.2.1 (2014-07-29)
|
||||
|
||||
- ++Docs
|
||||
- --Bugs
|
||||
|
||||
## 2.2.0 (2014-07-11)
|
||||
- Add new modifiers: match, ematch, replace, ereplace, split, esplit, join
|
||||
- ++Docs
|
||||
- ++Tests
|
||||
|
||||
### 2.1.2 (2014-07-03)
|
||||
|
||||
- Add test for bug #86
|
||||
- Fix bug #90
|
||||
- --Bugs
|
||||
- ++Tests
|
||||
|
||||
### 2.1.1 (2014-06-30)
|
||||
|
||||
- Fix bug #86: mismatch semicolon separator when value for foreach got from method (by nekufa)
|
||||
|
||||
## 2.1.0 (2014-06-29)
|
||||
|
||||
- Check variable before using in {foreach} (#83)
|
||||
- Add tag {unset} (#80)
|
||||
- Refactory array parser
|
||||
- --Bugs
|
||||
- ++Tests
|
||||
- ++Docs
|
||||
|
||||
### 2.0.1 (2014-06-09)
|
||||
|
||||
- Fix string concatenation. If `~` in the end of expression Fenom generates broken template.
|
||||
- Fix `~=` operator. Operator was not working.
|
||||
- Tests++
|
||||
- Docs++
|
||||
- ++Tests
|
||||
- ++Docs
|
||||
|
||||
## 2.0.0
|
||||
|
||||
|
|
74
README.md
74
README.md
|
@ -1,29 +1,63 @@
|
|||
Fenom - Template Engine for PHP
|
||||
===============================
|
||||
|
||||
> Composer [package](https://packagist.org/packages/fenom/fenom): `{"fenom/fenom": "2.*"}`. <br />
|
||||
> For old version: `{"fenom/fenom": "1.*"}`. [List](https://github.com/bzick/fenom/wiki/Migrate-from-1.4.9-to-2.0) of incompatibilities between 1.* and 2.* versions.
|
||||
**Fenóm** - lightweight and fast template engine for PHP.
|
||||
|
||||
[![Latest Stable Version](https://poser.pugx.org/fenom/fenom/v/stable.png)](https://packagist.org/packages/fenom/fenom)
|
||||
[![Build Status](https://travis-ci.org/bzick/fenom.svg?branch=master)](https://travis-ci.org/bzick/fenom)
|
||||
[![Coverage Status](https://coveralls.io/repos/bzick/fenom/badge.png?branch=master)](https://coveralls.io/r/bzick/fenom?branch=master)
|
||||
[![Total Downloads](https://poser.pugx.org/fenom/fenom/downloads.png)](https://packagist.org/packages/fenom/fenom)
|
||||
## [Quick start](./docs/start.md) :: [Documentation](./docs/readme.md) :: [Benchmark](./docs/benchmark.md)
|
||||
<!-- :: [Articles](./docs/articles.md) -->
|
||||
* **Subject:** Template engine
|
||||
* **Syntax:** Smarty-like
|
||||
* **Documentation:** **[English](./docs/en/readme.md)**, **[Russian](./docs/ru/readme.md)**
|
||||
* **PHP version:** 8.0+
|
||||
* **State:** [![PHP Composer](https://github.com/fenom-template/fenom/actions/workflows/php.yml/badge.svg?branch=master)](https://github.com/fenom-template/fenom/actions/workflows/php.yml) [![Coverage Status](https://coveralls.io/repos/fenom-template/fenom/badge.svg?branch=master)](https://coveralls.io/r/fenom-template/fenom?branch=master)
|
||||
* **Version:** [![Latest Stable Version](https://poser.pugx.org/fenom/fenom/v/stable.png)](https://packagist.org/packages/fenom/fenom)
|
||||
* **Packagist:** [fenom/fenom](https://packagist.org/packages/fenom/fenom) [![Total Downloads](https://poser.pugx.org/fenom/fenom/downloads.png)](https://packagist.org/packages/fenom/fenom)
|
||||
* **Composer:** `composer require fenom/fenom`
|
||||
* **Discussion:** [Fenom Forum](https://groups.google.com/forum/#!forum/php-ion)
|
||||
* **Versioning:** [semver2](http://semver.org/)
|
||||
* **Performance:** see [benchmark](./docs/en/benchmark.md)
|
||||
|
||||
### What is it
|
||||
***
|
||||
|
||||
**Fenom** *(from "fenomenal")* — lightweight template engine for PHP.
|
||||
## Quick Start
|
||||
|
||||
It means:
|
||||
### Install
|
||||
|
||||
* Known Smarty-like [syntax](./docs/syntax.md) with improvements.
|
||||
* Very [fast](./docs/benchmark.md).
|
||||
* [Lightweight](./docs/benchmark.md).
|
||||
* Very [flexible](./docs/configuration.md#extends).
|
||||
* Progressive parser without regular expressions.
|
||||
* High [code coverage](https://coveralls.io/r/bzick/fenom?branch=master).
|
||||
* Easy to understand [how it works](./docs/dev/readme.md).
|
||||
* Easy to [use](./docs/start.md).
|
||||
* Maximum [protection](./docs/configuration.md#configure).
|
||||
If you use composer in your project then you can to install Fenom as package.
|
||||
|
||||
### Setup
|
||||
|
||||
There is two-way to create Fenom instance:
|
||||
|
||||
* Long way: use operator `new`
|
||||
* Shot way: use static factory-method
|
||||
|
||||
**Long way.** Create you own template provider or default provider `Fenom\Provider` (that is provider read [there](./)).
|
||||
Using provider instance create Fenom instance:
|
||||
|
||||
```php
|
||||
$fenom = new Fenom(new Fenom\Provider($template_dir));
|
||||
```
|
||||
|
||||
After that, set compile directory:
|
||||
|
||||
```php
|
||||
$fenom->setCompileDir($template_cache_dir);
|
||||
```
|
||||
|
||||
This directory will be used for storing compiled templates, therefore it should be writable for Fenom.
|
||||
Now Fenom is ready to work and now you can to configure it:
|
||||
|
||||
```php
|
||||
$fenom->setOptions($options);
|
||||
```
|
||||
|
||||
**Short way.** Creating an object via factory method with arguments from long way.
|
||||
|
||||
```php
|
||||
$fenom = Fenom::factory($template_dir, $template_cache_dir, $options);
|
||||
```
|
||||
|
||||
Now Fenom is ready to work.
|
||||
|
||||
### Usage
|
||||
|
||||
### Example
|
|
@ -3,7 +3,7 @@
|
|||
"type": "library",
|
||||
"description": "Fenom - excellent template engine for PHP",
|
||||
"keywords": ["fenom", "template", "templating", "templater"],
|
||||
"license": "BSD-3",
|
||||
"license": "BSD-3-Clause",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ivan Shalganov",
|
||||
|
@ -11,15 +11,17 @@
|
|||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"php": ">=8.0.0",
|
||||
"ext-tokenizer": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "3.7.*",
|
||||
"satooshi/php-coveralls": "dev-master"
|
||||
"phpunit/phpunit": "9.*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "Fenom\\": "src/" },
|
||||
"psr-4": { "Fenom\\": "src/Fenom" },
|
||||
"classmap": [ "src/Fenom.php" ]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"classmap": [ "tests/cases" ]
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +0,0 @@
|
|||
Git conversation
|
||||
================
|
||||
|
||||
Ветка `master` содержит стабильную последнюю версию проекта. В ветку `master` может сливаться новая версия проекта из `develop` или исправления.
|
||||
Ветка `develop`, для разработки, содержит не стабильную версию проекта. Принимает все новшевства, изменения и исправления.
|
|
@ -1,12 +0,0 @@
|
|||
Develop
|
||||
=======
|
||||
|
||||
If you want to discuss the enhancement of the Fenom, create an issue on Github or submit a pull request.
|
||||
|
||||
There tho branches — master and develop.
|
||||
The branch master for stable releases and hotfixes; the branch develop for development of features. Each tag names by rule `major.minor.fix` (1.4.9, 1.1.2 etc) and creates from master. Version changes by the rule of [semantic versioning](http://semver.org/).
|
||||
|
||||
For questions: a.cobest@gmail.com (English, Russian languages)
|
||||
|
||||
|
||||
* the [scheme of work](schema.md)
|
|
@ -5,4 +5,5 @@ Adapters
|
|||
* [Fenom + Kohana](https://github.com/2bj/kofenom) — Kofenom
|
||||
* Fenom + Symphony
|
||||
* Fenom + Symphony2
|
||||
* Fenom + Zend Framework
|
||||
* Fenom + Zend Framework
|
||||
* [Fenom + Slim Framework 3](https://github.com/runcmf/runbb-ext-renderer) — RunBB forum extension
|
|
@ -38,7 +38,7 @@ Options may by associative array like `'option_name' => true` or bitwise mask.
|
|||
|
||||
```php
|
||||
$fenom->setOptions(array(
|
||||
"compile_check" => true,
|
||||
"force_compile" => true,
|
||||
"force_include" => true
|
||||
));
|
||||
// same
|
|
@ -0,0 +1,15 @@
|
|||
Develop
|
||||
=======
|
||||
|
||||
If you want to contribute to Fenom please feel free to create an issue or submit a pull request on Github.
|
||||
|
||||
There are two branches:
|
||||
|
||||
* `master` branch is for stable releases and hotfixes
|
||||
* `develop` branch is for development of features
|
||||
|
||||
Each tag names by rule `major.minor.fix` (1.4.9, 1.1.2, etc.) and creates from master. Version changes by the rule of [semantic versioning](http://semver.org/).
|
||||
|
||||
For questions: a.cobest@gmail.com (English, Russian languages)
|
||||
|
||||
* the [scheme of work](schema.md)
|
|
@ -8,12 +8,12 @@ By default format is: `%b %e, %Y`.
|
|||
```smarty
|
||||
{var $ts = time()}
|
||||
|
||||
{$ts|date_format:"%Y/%m/%d %H:%M:%s"} outputs 2013/02/08 21:01:43
|
||||
{$ts|date_format:"%Y/%m/%d %H:%M:%S"} outputs 2013/02/08 21:01:43
|
||||
{$ts|date_format:"-1 day"} outputs 2013/02/07 21:01:43
|
||||
|
||||
{var $date = "2008-12-08"}
|
||||
|
||||
{$ts|date_format:"%Y/%m/%d %H:%M:%s"} outputs 2008/12/08 00:00:00
|
||||
{$ts|date_format:"%Y/%m/%d %H:%M:%S"} outputs 2008/12/08 00:00:00
|
||||
```
|
||||
|
||||
[Allowed quantificators](http://docs.php.net/strftime#refsect1-function.strftime-parameters) in **date_format**
|
|
@ -0,0 +1,18 @@
|
|||
Modifier ematch
|
||||
==============
|
||||
|
||||
Perform a regular expression match.
|
||||
[Read more](http://www.php.net/manual/en/reference.pcre.pattern.syntax.php) about regular expression.
|
||||
|
||||
|
||||
```
|
||||
{$string|ematch:$pattern}
|
||||
```
|
||||
|
||||
Searches `$string` for a match to the regular expression given in `$pattern`.
|
||||
|
||||
```smarty
|
||||
{if $color|ematch:'/^gr[ae]y$/i'}
|
||||
some form of gray ...
|
||||
{/if}
|
||||
```
|
|
@ -0,0 +1,23 @@
|
|||
Modifier ereplace
|
||||
=================
|
||||
|
||||
Perform a regular expression search and replace.
|
||||
[Read more](http://www.php.net/manual/en/reference.pcre.pattern.syntax.php) about regular expression.
|
||||
|
||||
```
|
||||
{$string|replace:$pattern:$replacement}
|
||||
```
|
||||
|
||||
Searches `$string` for matches to `$pattern` and replaces them with `$replacement`.
|
||||
|
||||
`$replacement` may contain references of the form `\n`, `$n` or `${n}`, with the latter form being the preferred one.
|
||||
Every such reference will be replaced by the text captured by the n'th parenthesized pattern. n can be from 0 to 99,
|
||||
and `\0` or `$0` refers to the text matched by the whole pattern.
|
||||
Opening parentheses are counted from left to right (starting from 1) to obtain the number of the capturing subpattern.
|
||||
To use backslash in replacement, it must be doubled.
|
||||
|
||||
```smarty
|
||||
{var $string = 'April 15, 2014'}
|
||||
|
||||
{$string|ereplace:'/(\w+) (\d+), (\d+)/i':'${1}1, $3'} {* April1, 2014 *}
|
||||
```
|
|
@ -0,0 +1,19 @@
|
|||
Modifier esplit
|
||||
===============
|
||||
|
||||
Split string by a regular expression.
|
||||
[Read more](http://www.php.net/manual/en/reference.pcre.pattern.syntax.php) about regular expression.
|
||||
|
||||
```
|
||||
{$string|esplit:$pattern = '/,\s*/'}
|
||||
```
|
||||
|
||||
My default modifier split string by comma with spaces.
|
||||
|
||||
```smarty
|
||||
{var $fruits1 = "banana, apple, pear"|esplit}
|
||||
$fruits1 is array ["banana", "apple", "pear"]
|
||||
|
||||
{var $fruits2 = "banana; apple; pear"|esplit:'/;\s/'} is ["banana", "apple", "pear"]
|
||||
$fruits2 is array ["banana", "apple", "pear"] too
|
||||
```
|
|
@ -0,0 +1,16 @@
|
|||
Modifier split
|
||||
==============
|
||||
|
||||
Join array elements with a string.
|
||||
|
||||
```
|
||||
{$string|join:$delimiter = ","}
|
||||
```
|
||||
|
||||
Returns an array of strings, each of which is a substring of `$string` formed by splitting it on boundaries formed by the string `$delimiter`.
|
||||
|
||||
```smarty
|
||||
{var $fruits1 = ["banana", "apple", "pear"]}
|
||||
{$fruits1|join} output banana, apple, pear
|
||||
{$fruits1|join:" is not "} output banana is not apple is not pear
|
||||
```
|
|
@ -8,6 +8,6 @@ This is equivalent to the PHP [strtolower()](http://docs.php.net/lower) function
|
|||
{var $name = "Bzick"}
|
||||
|
||||
{$name} output Bzick
|
||||
{$name|upper} output bzick
|
||||
{$name|up} output bzick too
|
||||
```
|
||||
{$name|lower} output bzick
|
||||
{$name|low} output bzick too
|
||||
```
|
|
@ -0,0 +1,24 @@
|
|||
Modifier match
|
||||
==============
|
||||
|
||||
Match string against a pattern.
|
||||
The average user may be used to shell patterns or at least in their simplest form to `?` and `*` wildcards so using `match`
|
||||
instead of `ematch` for frontend search expression input may be way more convenient for non-programming users.
|
||||
|
||||
```
|
||||
{$string|match:$pattern}
|
||||
```
|
||||
|
||||
Special pattern symbols:
|
||||
|
||||
* `?` — match one or zero unknown characters. `?at` matches `Cat`, `cat`, `Bat` or `bat` but not `at`.
|
||||
* `*` — match any number of unknown characters. `Law*` matches `Law`, `Laws`, or `Lawyer`.
|
||||
* `[characters]` — Match a character as part of a group of characters. `[CB]at` matches `Cat` or `Bat` but not `cat`, `rat` or `bat`.
|
||||
* `\` - Escape character. `Law\*` will only match `Law*`
|
||||
|
||||
|
||||
```smarty
|
||||
{if $color|match:"*gr[ae]y"}
|
||||
some form of gray ...
|
||||
{/if}
|
||||
```
|
|
@ -0,0 +1,14 @@
|
|||
Modifier replace
|
||||
================
|
||||
|
||||
Replace all occurrences of the search string with the replacement string
|
||||
|
||||
```
|
||||
{$string|replace:$search:$replace}
|
||||
```
|
||||
|
||||
This modifier returns a string with all occurrences of `$search` in subject replaced with the given `$replace` value.
|
||||
|
||||
```smarty
|
||||
{$fruits|replace:"pear":"orange"}
|
||||
```
|
|
@ -0,0 +1,18 @@
|
|||
Modifier split
|
||||
==============
|
||||
|
||||
Split a string by string
|
||||
|
||||
```
|
||||
{$string|split:$delimiter = ","}
|
||||
```
|
||||
|
||||
Returns an array of strings, each of which is a substring of `$string` formed by splitting it on boundaries formed by the string `$delimiter`.
|
||||
|
||||
```smarty
|
||||
{var $fruits1 = "banana,apple,pear"|split}
|
||||
$fruits1 is array ["banana", "apple", "pear"]
|
||||
|
||||
{var $fruits2 = "banana,apple,pear"|split:',apple,'}
|
||||
$fruits2 is array ["banana", "pear"]
|
||||
```
|
|
@ -1,7 +1,7 @@
|
|||
Modifier upper
|
||||
==============
|
||||
|
||||
Modifier is used to uppercase a variable or string. Have short alias `up`.
|
||||
Modifier is used to uppercase a variable or string. Has short alias `up`.
|
||||
This is equivalent to the PHP [strtoupper()](http://docs.php.net/strtoupper) function.
|
||||
|
||||
```smarty
|
||||
|
@ -10,4 +10,4 @@ This is equivalent to the PHP [strtoupper()](http://docs.php.net/strtoupper) fun
|
|||
{$name} outputs Bzick
|
||||
{$name|upper} outputs BZICK
|
||||
{$name|up} outputs BZICK too
|
||||
```
|
||||
```
|
|
@ -55,7 +55,7 @@ Operators
|
|||
{if $a & 1} {var $b = 4 | $flags} {/if}
|
||||
```
|
||||
|
||||
### Assignment Operators
|
||||
### Assignment operators
|
||||
|
||||
* `$a = $b` - assignment
|
||||
* `$a += $b` - assignment with addition
|
||||
|
@ -81,9 +81,11 @@ Operators
|
|||
* `--$a` - decrement the variable and use it
|
||||
* `$a--` - use the variable and decrement it
|
||||
|
||||
### String operator
|
||||
### String operators
|
||||
|
||||
* `$a ~ $b` - return concatenation of variables `$a` and `$b`
|
||||
* `$a ~ $b` - return concatenation of variables `$a` and `$b`
|
||||
* `$a ~~ $b` - return concatenation of variables `$a` and `$b` separated by a space
|
||||
* `$a ~= $b` - assignment with concatenation
|
||||
|
||||
### Ternary operators
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
Documentation
|
||||
=============
|
||||
|
||||
### Fenom
|
||||
|
||||
* [Quick start](./start.md)
|
||||
* [Usage](./start.md#install-fenom)
|
||||
* [Framework adapters](./adapters.md)
|
||||
* [For developers](./dev/readme.md)
|
||||
* [Configuration](./configuration.md)
|
||||
* [Syntax](./syntax.md)
|
||||
* [Variables](./syntax.md#Variables)
|
||||
* [Values](./syntax.md#Values)
|
||||
* [Arrays](./syntax.md#Arrays)
|
||||
* [Operators](./operators.md)
|
||||
* [Modificators](./syntax.md#Modificators)
|
||||
* [Tags](./syntax.md#Tags)
|
||||
* [Tag configuration](./syntax.md#Tag-configuration)
|
||||
|
||||
***
|
||||
|
||||
### Tags
|
||||
|
||||
[Usage](./syntax.md#tags)
|
||||
|
||||
* [set](./tags/set.md), [add](./tags/set.md#add) and `var` — define variables
|
||||
* [if](./tags/if.md), [elseif](./tags/if.md#elseif) and [else](./tags/if.md#else) — conditional statement
|
||||
* [foreach](./tags/foreach.md), [foreaelse](./tags/foreach.md#foreaelse),
|
||||
[break](./tags/foreach.md#break) and [continue](./tags/foreach.md#continue) — traversing items in an array or object
|
||||
* [switch](./tags/switch.md), [case](./tags/switch.md#case) — complex condition statement
|
||||
* [cycle](./tags/cycle.md) — cycles on an array of values
|
||||
* [include](./tags/include.md), [insert](./tags/include.md#insert) — includes and evaluates the specified template
|
||||
* [extends](./tags/extends.md), [use](./tags/extends.md#use),
|
||||
[block](./tags/extends.md#block), [parent](./tags/extends.md#parent) and [paste](./tags/extends.md#paste) — template inheritance
|
||||
* [filter](./tags/filter.md) — apply modifier on a block of template data
|
||||
* [ignore](./tags/ignore.md) — ignore Fenom syntax
|
||||
* [macro](./tags/macro.md) and [import](./tags/macro.md#import) — template functions
|
||||
* [autoescape](./tags/autoescape.md) — escape template fragment
|
||||
* [raw](./tags/raw.md) — unescape template fragment
|
||||
* [unset](./tags/unset.md) — unset a given variables
|
||||
* or [add](./ext/extend.md#add-tags) yours
|
||||
|
||||
Deprecated tags
|
||||
|
||||
* [for](./tags/for.md), `forelse`, `break` and `continue` — loop statement
|
||||
|
||||
***
|
||||
|
||||
### Modifiers
|
||||
|
||||
[Usage](./syntax.md#modifiers)
|
||||
|
||||
* [upper](./mods/upper.md) aka `up` — convert to uppercase a string
|
||||
* [lower](./mods/lower.md) aka `low` — convert to lowercase a string
|
||||
* [date_format](./mods/date_format.md) - format date, timestamp via strftime() function
|
||||
* [date](./mods/date.md) - format date, timestamp via date() function
|
||||
* [truncate](./mods/truncate.md) — truncate thee string to specified length
|
||||
* [escape](./mods/escape.md) aka `e` — escape the string
|
||||
* [unescape](./mods/unescape.md) — unescape the string
|
||||
* [strip](./mods/strip.md) — remove extra whitespaces
|
||||
* [length](./mods/length.md) — calculate length of string, array, object
|
||||
* [in](./mods/in.md) — find value in string or array
|
||||
* [match](./mods/match.md) — match string against a pattern.
|
||||
* [ematch](./mods/ematch.md) — perform a regular expression match.
|
||||
* [replace](./mods/replace.md) — replace all occurrences of the search string with the replacement string.
|
||||
* [ereplace](./mods/ereplace.md) — perform a regular expression search and replace.
|
||||
* [split](./mods/split.md) — split a string by string.
|
||||
* [esplit](./mods/esplit.md) — split string by a regular expression.
|
||||
* [join](./mods/join.md) — join array elements with a string.
|
||||
* allowed functions: `json_encode`, `json_decode`, `count`, `is_string`, `is_array`, `is_numeric`, `is_int`, `is_object`,
|
||||
`strtotime`, `gettype`, `is_double`, `ip2long`, `long2ip`, `strip_tags`, `nl2br`
|
||||
* or [add](./ext/extend.md#add-modifiers) yours
|
||||
|
||||
***
|
||||
|
||||
### Operators
|
||||
|
||||
* [Arithmetic operators](./operators.md#arithmetic-operators) — `+`, `-`, `*`, `/`, `%`
|
||||
* [Logical operators](./operators.md#logical-operators) — `||`, `&&`, `!$var`, `and`, `or`, `xor`
|
||||
* [Comparison operators](./operators.md#comparison-operators) — `>`, `>=`, `<`, `<=`, `==`, `!=`, `!==`, `<>`
|
||||
* [Bitwise operators](./operators.md#bitwise-operators) — `|`, `&`, `^`, `~$var`, `>>`, `<<`
|
||||
* [Assignment operators](./operators.md#assignment-operators) — `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `|=`, `^=`, `>>=`, `<<=`
|
||||
* [String concatenation operators](./operators.md#string-operators) — `$str1 ~ $str2`, `$str1 ~~ $str2`, `$str1 ~= $str2`
|
||||
* [Ternary operators](./operators.md#ternary-operators) — `$a ? $b : $c`, `$a ! $b : $c`, `$a ?: $c`, `$a !: $c`
|
||||
* [Check operators](./operators.md#check-operators) — `$var?`, `$var!`
|
||||
* [Test operator](./operators.md#test-operator) — `is`, `is not`
|
||||
* [Containment operator](./operators.md#containment-operator) — `in`, `not in`
|
||||
|
||||
***
|
||||
|
||||
### Extends
|
||||
|
||||
* [Extend Fenom](./ext/extend.md)
|
||||
* [Add-ons](./ext/extensions.md)
|
|
@ -43,7 +43,7 @@ $fenom->setOptions($options);
|
|||
|
||||
* `/path/to/templates` — directory, where stores your templates.
|
||||
* `/path/to/template/cache` — directory, where stores compiled templates in PHP files.
|
||||
* `$options` - bit-mask or array of [Fenom settings](./docs/settings.md).
|
||||
* `$options` - bit-mask or array of [Fenom settings](./configuration.md#template-settings).
|
||||
|
||||
### Use Fenom
|
||||
|
|
@ -0,0 +1,569 @@
|
|||
Syntax
|
||||
======
|
||||
|
||||
Fenom implements [Smarty](http://www.smarty.net/) syntax with some improvements.
|
||||
All Fenom tags enclosed in the delimiters `{` and `}`, for example `{var $five = 5}`.
|
||||
If you wanna leave delimiters as is in the template use [special statements or tags](#ignoring-delimiters).
|
||||
|
||||
**Note**
|
||||
Fenom implements [Smarty](http://www.smarty.net/) syntax but not implements Smarty tags, however, some tags very similar.
|
||||
But not so bad, Fenom has the [extras](https://github.com/bzick/fenom-extra) that make Fenom like Smarty.
|
||||
|
||||
## Variable
|
||||
|
||||
Variables in Fenom can be either displayed directly or used as arguments for functions, attributes and modifiers,
|
||||
inside conditional expressions, etc.
|
||||
|
||||
### Use variables
|
||||
|
||||
Next example uses simple variables `$user_id` ans `$user_name`
|
||||
```smarty
|
||||
<div class="user">Hello, <a href="/users/{$user_id}">{$user_name}</a>.</div>
|
||||
```
|
||||
|
||||
Example outputs next HTML code:
|
||||
```html
|
||||
<div class="user">Hello, <a href="/users/17">Bzick</a>.</div>
|
||||
```
|
||||
|
||||
You can also reference associative array variables by specifying the key after a dot `.` symbol or paste key name into square brackets, as in PHP.
|
||||
```smarty
|
||||
<div class="user">Hello, <a href="/users/{$user.id}">{$user.name}</a>.</div>
|
||||
```
|
||||
`{$user.id}` and `{$user['id']}` are same:
|
||||
```smarty
|
||||
<div class="user">Hello, <a href="/users/{$user['id']}">{$user['name']}</a>.</div>
|
||||
```
|
||||
|
||||
Properties of objects assigned from PHP can be referenced by specifying the property name after the `->` symbol:
|
||||
```smarty
|
||||
<div class="user">Hello, <a href="/users/{$user->id}">{$user->name}</a>.</div>
|
||||
```
|
||||
|
||||
Methods of objects defined in PHP can be invoked by specifying the method name after the `->` symbol and use parenthesis with arguments:
|
||||
```smarty
|
||||
<div class="user">Hello, <a href="/users/{$user->getId()}">{$user->getName()}</a>.</div>
|
||||
```
|
||||
|
||||
*Note*
|
||||
Be careful, Fenom do not checks existence of the method before invoke.
|
||||
To avoid the problem class of the object have to define method `__call`, which throws an exception, etc.
|
||||
Also you can prohibit method call in [settings](./docs/configuration.md).
|
||||
|
||||
Below is complex example:
|
||||
|
||||
```smarty
|
||||
{$foo.bar.baz}
|
||||
{$foo.$bar.$baz}
|
||||
{$foo[5].baz}
|
||||
{$foo[5].$baz}
|
||||
{$foo.bar.baz[4]}
|
||||
{$foo[ $bar.baz ]}
|
||||
{$foo[5]}
|
||||
{$foo.5}
|
||||
{$foo.bar}
|
||||
{$foo.'bar'}
|
||||
{$foo."bar"}
|
||||
{$foo['bar']}
|
||||
{$foo["bar"]}
|
||||
{$foo.$bar}
|
||||
{$foo[$bar]}
|
||||
{$foo->bar}
|
||||
{$foo->bar.buz}
|
||||
{$foo->bar.buz[ $bar->getId("user") ]}
|
||||
{$foo->bar(5)->buz(5.5)}
|
||||
```
|
||||
|
||||
### System variable
|
||||
|
||||
Unnamed system variable starts with `$.` and allows access to global system variables and template information:
|
||||
|
||||
* `$.get` — array `$_GET`.
|
||||
* `$.post` — array `$_POST`.
|
||||
* `$.cookie` — array `$_COOKIE`.
|
||||
* `$.session` — array `$_SESSION`.
|
||||
* `$.globals` — array `$GLOBALS`.
|
||||
* `$.request` — array `$_REQUEST`.
|
||||
* `$.files` — array `$_FILES`.
|
||||
* `$.server` — array `$_SERVER`.
|
||||
* `$.env` is `$_ENV`.
|
||||
* `$.tpl.name` returns current template name.
|
||||
* `$.tpl.schema` returns current schema of the template.
|
||||
* `$.version` returns version of the Fenom.
|
||||
* `$.const` paste constant.
|
||||
|
||||
```smarty
|
||||
{if $.get.debug? && $.const.DEBUG}
|
||||
...
|
||||
{/if}
|
||||
```
|
||||
|
||||
|
||||
Безименная системная переменная начинается с `$.` и предоставляет доступ к глобальным системным переменным и системной информации:
|
||||
|
||||
* `$.env` — array `$_ENV`.
|
||||
* `$.get` — array `$_GET`.
|
||||
* `$.post` — array `$_POST`.
|
||||
* `$.files` — array `$_FILES`.
|
||||
* `$.cookie` — array `$_COOKIE`.
|
||||
* `$.server` — array `$_SERVER`.
|
||||
* `$.session` — array `$_SESSION`.
|
||||
* `$.globals` — array `$GLOBALS`.
|
||||
* `$.request` — array `$_REQUEST`.
|
||||
* `$.tpl.name` returns name for current template.
|
||||
* `$.tpl.basename` returns name without schema for current template.
|
||||
* `$.tpl.scm` returns schema for current template.
|
||||
* `$.tpl.options` returns options as integer for current template.
|
||||
* `$.tpl.depends` <!-- возвращает массив шаблонов на которые ссылается текущий шаблон.-->
|
||||
* `$.tpl.time` returns last modified timestamp for current template
|
||||
* `$.version` returns Fenom version.
|
||||
* `$.const` returns the value of a PHP constant: `$.const.PHP_EOL` get value of constant `PHP_EOL`.
|
||||
Supported namespace for constants, use dot instead of back-slash for namespace separators: `$.const.Storage.FS::DIR_SEPARATOR` get value of constant `Storage\FS::DIR_SEPARATOR`.
|
||||
But if constant `Storage\FS::DIR_SEPARATOR` does not exists then constant `Storage\FS\DIR_SEPARATOR` will be taken.
|
||||
* `$.php`call PHP static method. `$.php.Storage.FS::put($filename, $data)` calls method `Storage\FS::put($filename, $data)`.
|
||||
`$.php.Storage.FS.put($filename, $data)` `Storage\FS\put($filename, $data)`
|
||||
* System function `$.fetch($name, $values)` calls Fenom::fetch() in template. `$name` — template name,
|
||||
`$values` — additional variables.
|
||||
* also you may [add](./ext/extend.md#Extends-system-variable) yours system variables and functions.
|
||||
|
||||
|
||||
## Scalar values
|
||||
|
||||
### Strings
|
||||
|
||||
A string literal can be specified in two different ways: double quotes (`"string"`) and single quotes (`'string'`).
|
||||
|
||||
#### Double quotes
|
||||
|
||||
If the string is enclosed in double-quotes `"`, Fenom will interpret more escape sequences for special characters:
|
||||
|
||||
|
||||
| Последовательность | Значение |
|
||||
|---------------------|----------|
|
||||
| `\n` | linefeed (LF or 0x0A (10) in ASCII)
|
||||
| `\r` | carriage return (CR or 0x0D (13) in ASCII)
|
||||
| `\t` | horizontal tab (HT or 0x09 (9) in ASCII)
|
||||
| `\v` | vertical tab (VT or 0x0B (11) in ASCII)
|
||||
| `\f` | form feed (FF or 0x0C (12) in ASCII)
|
||||
| `\\` | backslash
|
||||
| `\$` | dollar sign
|
||||
| `\"` | double-quote
|
||||
| `\[0-7]{1,3}` | the sequence of characters matching the regular expression is a character in octal notation
|
||||
| `\x[0-9A-Fa-f]{1,2}`| the sequence of characters matching the regular expression is a character in hexadecimal notation
|
||||
|
||||
The most important feature of double-quoted strings is the fact that variable names will be expanded.
|
||||
There are two types of syntax: a simple one and a complex one. The simple syntax is the most common and convenient.
|
||||
It provides a way to embed a variable, an array value, or an object property in a string with a minimum of effort.
|
||||
The complex syntax can be recognised by the curly braces surrounding the expression.
|
||||
|
||||
##### Simple syntax
|
||||
|
||||
If a dollar sign `$` is encountered, the parser will greedily take as many tokens as possible to form a valid variable name.
|
||||
Enclose the variable name in curly braces to explicitly specify the end of the name.
|
||||
|
||||
```smarty
|
||||
{"Hi, $username!"} outputs "Hi, Username!"
|
||||
```
|
||||
|
||||
For anything more complex, you should use the complex syntax.
|
||||
|
||||
##### Complex syntax
|
||||
|
||||
This isn't called complex because the syntax is complex, but because it allows for the use of complex expressions.
|
||||
Any scalar variable, array element or object property with a string representation can be included via this syntax.
|
||||
Simply write the expression the same way as it would appear outside the string, and then wrap it in `{` and `}`.
|
||||
Since `{` can not be escaped, this syntax will only be recognised when the `$` immediately follows the `{`.
|
||||
Use `{\$` to get a literal `{$`. Some examples to make it clear:
|
||||
|
||||
|
||||
```smarty
|
||||
{"Hi, {$user.name}!"} outputs: Hi, Username!
|
||||
{"Hi, {$user->name}!"} outputs: Hi, Username!
|
||||
{"Hi, {$user->getName()}!"} outputs: Hi, Username!
|
||||
{"Hi, {\$user->name}!"} outputs: Hi, {\$user->name}!
|
||||
```
|
||||
|
||||
Allows modifiers and operators:
|
||||
|
||||
```smarty
|
||||
{"Hi, {$user.name|up}!"} outputs: Hi, USERNAME!
|
||||
{"Hi, {$user.name|up ~ " (admin)"}!"} outputs: Hi, USERNAME (admin)!
|
||||
```
|
||||
|
||||
#### Single quotes
|
||||
|
||||
The simplest way to specify a string is to enclose it in single quotes (the character `'`).
|
||||
To specify a literal single quote, escape it with a backslash (`\`).
|
||||
To specify a literal backslash, double it (`\\`).
|
||||
All other instances of backslash will be treated as a literal backslash: this means that the other escape sequences you might be used to, such as `\r` or `\n`, will be output literally as specified rather than having any special meaning.
|
||||
|
||||
```smarty
|
||||
{'Hi, $foo'} outputs: 'Hi, $foo'
|
||||
{'Hi, {$foo}'} outputs: 'Hi, {$foo}'
|
||||
{'Hi, {$user.name}'} outputs: 'Hi, {$user.name}'
|
||||
{'Hi, {$user.name|up}'} outputs: "Hi, {$user.name|up}"
|
||||
```
|
||||
|
||||
### Integers
|
||||
|
||||
Integers can be specified in decimal (base 10), hexadecimal (base 16), octal (base 8) or binary (base 2) notation, optionally preceded by a sign (- or +).
|
||||
|
||||
To use octal notation, precede the number with a 0 (zero).
|
||||
To use hexadecimal notation precede the number with 0x.
|
||||
To use binary notation precede the number with 0b.
|
||||
|
||||
```smarty
|
||||
{var $a = 1234} decimal number
|
||||
{var $a = -123} a negative number
|
||||
{var $a = 0123} octal number (equivalent to 83 decimal)
|
||||
{var $a = 0x1A} hexadecimal number (equivalent to 26 decimal)
|
||||
{var $a = 0b11111111} binary number (equivalent to 255 decimal)
|
||||
```
|
||||
|
||||
**Notice**
|
||||
Binary notation (`0b1011011`) unavailable on PHP older than 5.3.
|
||||
|
||||
**Notice**
|
||||
The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed).
|
||||
64-bit platforms usually have a maximum value of about 9E18
|
||||
|
||||
**Warning**
|
||||
If an invalid digit is given in an octal integer (i.e. 8 or 9), the rest of the number is ignored.
|
||||
|
||||
### Floating point numbers
|
||||
|
||||
Floating point numbers (also known as "floats", "doubles", or "real numbers") can be specified using any of the following syntaxes:
|
||||
|
||||
```smarty
|
||||
{var $a = 1.234}
|
||||
{var $b = 1.2e3}
|
||||
{var $c = 7E-10}
|
||||
```
|
||||
|
||||
### Booleans
|
||||
|
||||
This is the simplest type. A boolean expresses a truth value. It can be either TRUE or FALSE.
|
||||
To specify a boolean literal, use the constants TRUE or FALSE. Both are case-insensitive.
|
||||
|
||||
|
||||
```smarty
|
||||
{set $a = true}
|
||||
```
|
||||
|
||||
### NULL
|
||||
|
||||
The special NULL value represents a variable with no value. NULL is the only possible value of type null.
|
||||
|
||||
------
|
||||
|
||||
|
||||
### Variable operations
|
||||
|
||||
Fenom supports math, logic, comparison, containment, test, concatenation operators...
|
||||
|
||||
todo
|
||||
|
||||
See all [operators](./operators.md)
|
||||
|
||||
|
||||
### Set variable
|
||||
|
||||
```smarty
|
||||
{var $foo = "bar"}
|
||||
{var $foo = "bar"|upper} {* apply modifier *}
|
||||
{var $foo = 5}
|
||||
{var $foo = $x + $y}
|
||||
{var $foo = $x.y[z] + $y}
|
||||
{var $foo = strlen($a)} {* work with functions *}
|
||||
{var $foo = myfunct( ($x+$y)*3 )}
|
||||
{var $foo.bar.baz = 1} {* multidimensional value support *}
|
||||
{var $foo = $object->item->method($y, 'named')} {* work with object fine *}
|
||||
```
|
||||
|
||||
Using block tag
|
||||
|
||||
```smarty
|
||||
{var $foo}
|
||||
content {$text|truncate:30}
|
||||
{/var}
|
||||
{var $foo|truncate:50} {* apply modifier to content *}
|
||||
content {$text}
|
||||
{/var}
|
||||
```
|
||||
|
||||
Set array
|
||||
|
||||
```smarty
|
||||
{var $foo = [1, 2, 3]} numeric array
|
||||
{var $foo = ['y' => 'yellow', 'b' => 'blue']} associative array
|
||||
{var $foo = [1, [9, 8], 3]} can be nested
|
||||
{var $foo = [1, $two, $three * 3 + 9]}
|
||||
{var $foo = [$a, $d.c, $a + $f]}
|
||||
{var $foo = ['y' => 'yellow', $color|upper => $colors[ $color ]}
|
||||
{var $foo = [1, [$parent, $a->method()], 3]}
|
||||
```
|
||||
|
||||
See also [{var}](./tags/var.md) documentation.
|
||||
|
||||
|
||||
## Scalar values
|
||||
|
||||
### Strings
|
||||
|
||||
When the string in double quotation marks, all the expressions in the string will be run.
|
||||
The result of expressions will be inserted into the string instead it.
|
||||
|
||||
```smarty
|
||||
{var $foo="Username"}
|
||||
{var $user.name="Username"}
|
||||
{"Hi, $foo"} outputs "Hi, Username"
|
||||
{"Hi, {$foo}"} outputs "Hi, Username"
|
||||
{"Hi, {$user.name}"} outputs "Hi, Username"
|
||||
{"Hi, {$user.name|up}"} outputs "Hi, USERNAME"
|
||||
{"Hi, {$user->getName(true)}"} outputs Hi, Username
|
||||
{var $message = "Hi, {$user.name}"}
|
||||
```
|
||||
|
||||
but if use single quote any template expressions will be on display as it is
|
||||
|
||||
```smarty
|
||||
{'Hi, $foo'} outputs 'Hi, $foo'
|
||||
{'Hi, {$foo}'} outputs 'Hi, {$foo}'
|
||||
{'Hi, {$user.name}'} outputs 'Hi, {$user.name}'
|
||||
{'Hi, {$user.name|up}'} outputs "Hi, {$user.name|up}"
|
||||
```
|
||||
|
||||
### Integers
|
||||
|
||||
Integers can be specified in decimal (base 10), hexadecimal (base 16), octal (base 8) or binary (base 2) notation, optionally preceded by a sign (- or +).
|
||||
|
||||
To use octal notation, precede the number with a 0 (zero). To use hexadecimal notation precede the number with 0x.
|
||||
To use binary notation precede the number with 0b.
|
||||
|
||||
```smarty
|
||||
{var $a = 1234} decimal number
|
||||
{var $a = -123} a negative number
|
||||
{var $a = 0123} octal number (equivalent to 83 decimal)
|
||||
{var $a = 0x1A} hexadecimal number (equivalent to 26 decimal)
|
||||
{var $a = 0b11111111} binary number (equivalent to 255 decimal)
|
||||
```
|
||||
|
||||
**Note**
|
||||
The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed).
|
||||
64-bit platforms usually have a maximum value of about 9223372036854775807
|
||||
|
||||
**Warning**
|
||||
If an invalid digit is given in an octal integer (i.e. 8 or 9), the rest of the number is ignored.
|
||||
|
||||
### Floating point numbers
|
||||
|
||||
Floating point numbers (also known as "floats", "doubles", or "real numbers") can be specified using any of the following syntaxes:
|
||||
|
||||
```smarty
|
||||
{var $a = 1.234}
|
||||
{var $b = 1.2e3}
|
||||
{var $c = 7E-10}
|
||||
```
|
||||
|
||||
### Operators
|
||||
|
||||
Fenom supports operators on values:
|
||||
|
||||
* Arithmetic operators — `+`, `-`, `*`, `/`, `%`
|
||||
* Logical operators — `||`, `&&`, `!$var`, `and`, `or`, `xor`
|
||||
* Comparison operators — `>`, `>=`, `<`, `<=`, `==`, `!=`, `!==`, `<>`
|
||||
* Bitwise operators — `|`, `&`, `^`, `~$var`, `>>`, `<<`
|
||||
* Assignment operators — `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `|=`, `^=`, `>>=`, `<<=`
|
||||
* String concatenation operators — `$str1 ~ $str2`, `$str1 ~~ $str2`, `$str1 ~= $str2`
|
||||
* Ternary operators — `$a ? $b : $c`, `$a ! $b : $c`, `$a ?: $c`, `$a !: $c`
|
||||
* Check operators — `$var?`, `$var!`
|
||||
* Test operator — `is`, `is not`
|
||||
* Containment operator — `in`, `not in`
|
||||
|
||||
About [operators](./operators.md).
|
||||
|
||||
## Arrays
|
||||
|
||||
An array can be created using the `[]` language construct. It takes any number of comma-separated `key => value` pairs as arguments.
|
||||
```
|
||||
[
|
||||
key => value,
|
||||
key2 => value2,
|
||||
key3 => value3,
|
||||
...
|
||||
]
|
||||
```
|
||||
The comma after the last array element is optional and can be omitted.
|
||||
This is usually done for single-line arrays, i.e. `[1, 2]` is preferred over `[1, 2, ]`.
|
||||
For multi-line arrays on the other hand the trailing comma is commonly used, as it allows easier addition of new elements at the end.
|
||||
|
||||
```smarty
|
||||
{set $array = [
|
||||
"foo" => "bar",
|
||||
"bar" => "foo",
|
||||
]}
|
||||
```
|
||||
|
||||
The key can either be an integer or a string. The value can be of any type.
|
||||
|
||||
Additionally the following key casts will occur:
|
||||
|
||||
* Strings containing valid integers will be cast to the integer type. E.g. the key "8" will actually be stored under 8.
|
||||
On the other hand "08" will not be cast, as it isn't a valid decimal integer.
|
||||
* Floats are also cast to integers, which means that the fractional part will be truncated.
|
||||
E.g. the key 8.7 will actually be stored under 8.
|
||||
* Bools are cast to integers, too, i.e. the key true will actually be stored under 1 and the key false under 0.
|
||||
* Null will be cast to the empty string, i.e. the key null will actually be stored under "".
|
||||
* Arrays and objects can not be used as keys. Doing so will result in a warning: Illegal offset type.
|
||||
|
||||
If multiple elements in the array declaration use the same key, only the last one will be used as all others are overwritten.
|
||||
|
||||
An existing array can be modified by explicitly setting values in it.
|
||||
This is done by assigning values to the array, specifying the key after dot or in brackets.
|
||||
The key can also be omitted, resulting in an empty pair of brackets (`[]`).
|
||||
|
||||
```smarty
|
||||
{set $arr.key = value}
|
||||
{set $arr[] = value} {* append value to end of array *}
|
||||
```
|
||||
|
||||
If `$arr` doesn't exist yet, it will be created, so this is also an alternative way to create an array.
|
||||
This practice is however discouraged because if `$arr` already contains some value (e.g. string from request variable)
|
||||
then this value will stay in the place and `[]` may actually stand for string access operator.
|
||||
It is always better to initialize variable by a direct assignment.
|
||||
|
||||
## Constants
|
||||
|
||||
A constant is an identifier (name) for a simple value in PHP.
|
||||
As the name suggests, that value cannot change during the execution of the script.
|
||||
A constant is case-sensitive by default. By convention, constant identifiers are always uppercase.
|
||||
|
||||
## PHP functions and methods
|
||||
|
||||
**TODO**
|
||||
|
||||
```smarty
|
||||
{$.php.some_function($a, $b, $c)}
|
||||
```
|
||||
|
||||
```smarty
|
||||
{$.php.MyClass::method($a, $b, $c)}
|
||||
```
|
||||
|
||||
|
||||
```smarty
|
||||
{$.php.My.NS.some_function($a, $b, $c)}
|
||||
{$.php.My.NS.MyClass::method($a, $b, $c)}
|
||||
```
|
||||
|
||||
## Modifiers
|
||||
|
||||
|
||||
Variable modifiers can be applied to variables, custom functions or strings.
|
||||
To apply a modifier, specify the value followed by a | (pipe) and the modifier name.
|
||||
A modifier may accept additional parameters that affect its behavior.
|
||||
These parameters follow the modifier name and are separated by a : (colon).
|
||||
|
||||
```smarty
|
||||
{var $foo="User"}
|
||||
{$foo|upper} outputs "USER"
|
||||
{$foo|lower} outputs "user"
|
||||
{"{$foo|lower}"} outputs "user"
|
||||
{"User"|lower}} outputs "user"
|
||||
{$looong_text|truncate:80:"..."} truncate the text to 80 symbols and append <continue> symbols, like "..."
|
||||
{$looong_text|lower|truncate:$settings.count:$settings.etc}
|
||||
{var $foo="Ivan"|upper} sets $foo value "USER"
|
||||
```
|
||||
|
||||
[List of modifiers](./main.md#modifiers)
|
||||
|
||||
## Tags
|
||||
|
||||
**TODO**
|
||||
|
||||
## Ignoring template code
|
||||
|
||||
It is sometimes desirable or even necessary to have ignore sections it would otherwise parse.
|
||||
A classic example is embedding Javascript or CSS code in a template.
|
||||
The problem arises as those languages use the `{` and `}` characters which are also the default delimiters for Fenom.
|
||||
Fenom has several solutions:
|
||||
|
||||
1. Uses block tag `{ignore} {/ignore}`. Anything within `{ignore} {/ignore}` tags is not interpreted, but displayed as-is.
|
||||
2. The `{` and `}` braces will be ignored so long as they are surrounded by white space.
|
||||
3. Uses tag option `:ignore` for block tag. Все Fenom теги внутри блока будут проигнорированны
|
||||
|
||||
Example:
|
||||
|
||||
```smarty
|
||||
{ignore}
|
||||
<style>
|
||||
h1 {font-size: 24px; color: #F00;}
|
||||
</style>
|
||||
{/ignore}
|
||||
<script>
|
||||
(function (text) {
|
||||
var e = document.createElement('P');
|
||||
e.innerHTML = text;
|
||||
document.body.appendChild(e);
|
||||
})('test');
|
||||
{if:ignore $cdn.yandex}
|
||||
var item = {cdn: "//yandex.st/"};
|
||||
{/if}
|
||||
</script>
|
||||
```
|
||||
|
||||
Outputs
|
||||
|
||||
```html
|
||||
<style>
|
||||
h1 {font-size: 24px; color: #F00;}
|
||||
</style>
|
||||
<script>
|
||||
(function (text) {
|
||||
var e = document.createElement('P');
|
||||
e.innerHTML = text;
|
||||
document.body.appendChild(e);
|
||||
})('test');
|
||||
var item = {cdn: "//yandex.st/"};
|
||||
</script>
|
||||
```
|
||||
|
||||
### Whitespaces
|
||||
|
||||
Tags to allow any number of spaces
|
||||
|
||||
```smarty
|
||||
{include 'control.tpl'
|
||||
$options = $list
|
||||
$name = $cp.name
|
||||
$type = 'select'
|
||||
isolate = true
|
||||
disable_static = true
|
||||
}
|
||||
|
||||
{foreach [
|
||||
"one" => 1,
|
||||
"two" => 2,
|
||||
"three" => 3
|
||||
] as $key => $val}
|
||||
|
||||
{$key}: {$val}
|
||||
|
||||
{/foreach}
|
||||
```
|
||||
|
||||
### Tag options
|
||||
|
||||
**TODO**
|
||||
|
||||
| name | code | type | description |
|
||||
| ------- | ---- | ----- | ------------ |
|
||||
| strip | s | block | enable `strip` option for a block of the template |
|
||||
| raw | a | any | ignore escape option |
|
||||
| escape | e | any | force escape |
|
||||
| ignore | i | block | ignore Fenom syntax |
|
||||
|
||||
```smarty
|
||||
{script:ignore} ... {/script}
|
||||
{foreach:ignore:strip ...} ... {/foreach}
|
||||
```
|
|
@ -1,13 +1,15 @@
|
|||
Tag {cycle}
|
||||
===========
|
||||
|
||||
`{cycle}` is used to alternate a set of values.
|
||||
|
||||
```smarty
|
||||
{for $i=$a.c..}
|
||||
{foreach 1..10}
|
||||
<div class="{cycle ["odd", "even"]}">
|
||||
{/for}
|
||||
{/foreach}
|
||||
|
||||
|
||||
{for $i=$a.c..}
|
||||
{foreach 1..10}
|
||||
<div class="{cycle ["odd", "even"] index=$i}">
|
||||
{/for}
|
||||
{/foreach}
|
||||
```
|
|
@ -0,0 +1,9 @@
|
|||
Tag {do}
|
||||
========
|
||||
|
||||
Evaluates any expression and doesn't print anything
|
||||
|
||||
```smarty
|
||||
{do $count++}
|
||||
{do $object->method()}
|
||||
```
|
|
@ -0,0 +1,70 @@
|
|||
Tag {extends}
|
||||
=============
|
||||
|
||||
`{extends}` tags are used in child templates in template inheritance for extending parent templates.
|
||||
The `{extends}` tag must be on before any block.
|
||||
Also if a child template extends a parent template with the `{extends}` tag it may contain only `{block}` tags. Any other template content is ignored.
|
||||
|
||||
### {extends}
|
||||
|
||||
```smarty
|
||||
{extends 'parent.tpl'}
|
||||
```
|
||||
|
||||
### {block}
|
||||
|
||||
```smarty
|
||||
{block 'bk2'}content 2{/block}
|
||||
```
|
||||
|
||||
### {use}
|
||||
|
||||
Import the blocks defined in another file. Specifying blocks in this template will override those from the other file.
|
||||
|
||||
```smarty
|
||||
{use 'blocks.tpl'} merge blocks from blocks.tpl template
|
||||
|
||||
{block 'alpha'} rewrite block alpha from blocks.tpl template, if it exists
|
||||
...
|
||||
{/block}
|
||||
```
|
||||
|
||||
### {parent}
|
||||
|
||||
Uses the code from the block as defined in the parent.
|
||||
|
||||
```smarty
|
||||
{extends 'parent.tpl'}
|
||||
|
||||
{block 'header'}
|
||||
content ...
|
||||
{parent} pase code from block 'header' from parent.tpl
|
||||
content ...
|
||||
{/block}
|
||||
```
|
||||
|
||||
### {paste}
|
||||
|
||||
Pastes the code of any block
|
||||
|
||||
```smarty
|
||||
{block 'b1'}
|
||||
...
|
||||
{/block}
|
||||
|
||||
{block 'b2'}
|
||||
...
|
||||
{paste 'b1'} paste code from b1
|
||||
{/block}
|
||||
|
||||
```
|
||||
|
||||
### {$.block}
|
||||
|
||||
Checks if clock exists
|
||||
|
||||
```smarty
|
||||
{if $.block.header}
|
||||
block header exists
|
||||
{/if}
|
||||
```
|
|
@ -1,10 +1,12 @@
|
|||
Tags {filter}
|
||||
=============
|
||||
|
||||
Позволяет применить модификаторы на фрагмент шаблона
|
||||
Apply modifier to template area.
|
||||
|
||||
```smarty
|
||||
{filter|strip_tags|truncate:20}
|
||||
Remove all HTML <b>tags</b> and truncate {$text} to 20 symbols
|
||||
{/filter}
|
||||
```
|
||||
```
|
||||
|
||||
**Note**: output buffering used. May be used a lot of memory if you output a lot of data.
|
|
@ -0,0 +1,104 @@
|
|||
Tag {foreach}
|
||||
=============
|
||||
|
||||
The tag `{foreach}` construct provides an easy way to iterate over arrays and ranges.
|
||||
|
||||
```smarty
|
||||
{foreach $list as [$key =>] $value [index=$index] [first=$first] [last=$last]}
|
||||
{* ...code... *}
|
||||
{break}
|
||||
{* ...code... *}
|
||||
{continue}
|
||||
{* ...code... *}
|
||||
{foreachelse}
|
||||
{* ...code... *}
|
||||
{/foreach}
|
||||
```
|
||||
|
||||
### {foreach}
|
||||
|
||||
On each iteration, the value of the current element is assigned to `$value` and the internal array pointer is
|
||||
advanced by one (so on the next iteration, you'll be looking at the next element).
|
||||
|
||||
```smarty
|
||||
{foreach $list as $value}
|
||||
<div>{$value}</div>
|
||||
{/foreach}
|
||||
```
|
||||
|
||||
The next form will additionally assign the current element's key to the `$key` variable on each iteration.
|
||||
|
||||
```smarty
|
||||
{foreach $list as $key => $value}
|
||||
<div>{$key}: {$value}</div>
|
||||
{/foreach}
|
||||
```
|
||||
|
||||
Gets the current array index, starting with zero.
|
||||
|
||||
```smarty
|
||||
{foreach $list as $value}
|
||||
<div>№{$value@index}: {$value}</div>
|
||||
{/foreach}
|
||||
|
||||
or
|
||||
|
||||
{foreach $list as $value index=$index}
|
||||
<div>№{$index}: {$value}</div>
|
||||
{/foreach}
|
||||
```
|
||||
|
||||
Detect first iteration:
|
||||
|
||||
```smarty
|
||||
{foreach $list as $value}
|
||||
<div>{if $value@first} first item {/if} {$value}</div>
|
||||
{/foreach}
|
||||
|
||||
or
|
||||
|
||||
{foreach $list as $value first=$first}
|
||||
<div>{if $first} first item {/if} {$value}</div>
|
||||
{/foreach}
|
||||
```
|
||||
|
||||
`$first` is `TRUE` if the current `{foreach}` iteration is first iteration.
|
||||
|
||||
Detect last iteration:
|
||||
|
||||
```smarty
|
||||
{foreach $list as $value}
|
||||
<div>{if $value@last} last item {/if} {$value}</div>
|
||||
{/foreach}
|
||||
|
||||
or
|
||||
|
||||
{foreach $list as $value last=$last}
|
||||
<div>{if $last} last item {/if} {$value}</div>
|
||||
{/foreach}
|
||||
```
|
||||
|
||||
`$last` is set to `TRUE` if the current `{foreach}` iteration is last iteration.
|
||||
|
||||
### {break}
|
||||
|
||||
Tag `{break}` aborts the iteration.
|
||||
|
||||
### {continue}
|
||||
|
||||
Tag `{continue}` leaves the current iteration and begins with the next iteration.
|
||||
|
||||
### {foreachelse}
|
||||
|
||||
`{foreachelse}` is executed when there are no values in the array variable.
|
||||
|
||||
```smarty
|
||||
{set $list = []}
|
||||
{foreach $list as $value}
|
||||
<div>{if $last} last item {/if} {$value}</div>
|
||||
{foreachelse}
|
||||
<div>empty</div>
|
||||
{/foreach}
|
||||
```
|
||||
|
||||
`{foreachelse}` does not support tags `{break}` and `{continue}`.
|
|
@ -0,0 +1,44 @@
|
|||
Tag {if}
|
||||
========
|
||||
|
||||
Tag {if} have much the same flexibility as PHP [if](http://docs.php.net/if) statements,
|
||||
with a few added features for the template engine.
|
||||
All operators, allowed functions and variables are recognized in conditions.
|
||||
|
||||
```smarty
|
||||
{if <expression>}
|
||||
{* ...code... *}
|
||||
{elseif <expression>}
|
||||
{* ...code... *}
|
||||
{else}
|
||||
{* ...code... *}
|
||||
{/if}
|
||||
```
|
||||
|
||||
### {if}
|
||||
|
||||
```smarty
|
||||
{if <expression>}
|
||||
{*...some code...*}
|
||||
{/if}
|
||||
```
|
||||
|
||||
### {elseif}
|
||||
|
||||
```smarty
|
||||
{if <expression1>}
|
||||
{*...some code...*}
|
||||
{elseif <expression2>}
|
||||
{*...some code...*}
|
||||
{/if}
|
||||
```
|
||||
|
||||
### {else}
|
||||
|
||||
```smarty
|
||||
{if <expression>}
|
||||
{*...some code...*}
|
||||
{else}
|
||||
{*...some code...*}
|
||||
{/if}
|
||||
```
|
|
@ -0,0 +1,51 @@
|
|||
Tag {macro}
|
||||
===========
|
||||
|
||||
Macros are comparable with functions in regular programming languages.
|
||||
They are useful to put often used HTML idioms into reusable elements to not repeat yourself.
|
||||
|
||||
### {macro}
|
||||
|
||||
Macros can be defined in any template using tag `{macro}`.
|
||||
|
||||
```smarty
|
||||
{macro plus($x, $y, $z=0)}
|
||||
x + y + z = {$x + $y + $z}
|
||||
{/macro}
|
||||
```
|
||||
|
||||
```smarty
|
||||
{macro.plus x=$num y=100}
|
||||
```
|
||||
|
||||
```smarty
|
||||
{macro plus($x, $y, $z=0)}
|
||||
...
|
||||
{macro.plus x=2 y=$y}
|
||||
...
|
||||
{/macro}
|
||||
```
|
||||
|
||||
### {import}
|
||||
|
||||
Macros can be defined in any template, and need to be "imported" before being used.
|
||||
The above import call imports the "math.tpl" file (which can contain only macros, or a template and some macros),
|
||||
and import the functions as items of the `macro` namespace.
|
||||
|
||||
```smarty
|
||||
{import 'math.tpl'}
|
||||
|
||||
{macro.plus x=1 y=3}
|
||||
```
|
||||
|
||||
Use another namespace instead of `macro`
|
||||
|
||||
```smarty
|
||||
{import 'math.tpl' as math}
|
||||
...
|
||||
{math.plus x=5 y=100}
|
||||
```
|
||||
|
||||
```smarty
|
||||
{import [plus, minus, exp] from 'math.tpl' as math}
|
||||
```
|
|
@ -0,0 +1,84 @@
|
|||
Tag {set}
|
||||
=========
|
||||
|
||||
The tag {set} is used for assigning template variables during the execution of a template.
|
||||
|
||||
```smarty
|
||||
{set $var=EXPR}
|
||||
```
|
||||
|
||||
```smarty
|
||||
{set $var}
|
||||
... any content ...
|
||||
{/set}
|
||||
```
|
||||
|
||||
```smarty
|
||||
{set $var|modifiers}
|
||||
... any content ...
|
||||
{/set}
|
||||
```
|
||||
|
||||
Variable names follow the same rules as other labels in PHP.
|
||||
A valid variable name starts with a letter or underscore, followed by any number of letters, numbers, or underscores.
|
||||
|
||||
```smarty
|
||||
{set $v = 5}
|
||||
{set $v = "value"}
|
||||
|
||||
{set $v = $x+$y}
|
||||
{set $v = 4}
|
||||
{set $v = $z++ + 1}
|
||||
{set $v = --$z}
|
||||
{set $v = $y/$x}
|
||||
{set $v = $y-$x}
|
||||
{set $v = $y*$x-2}
|
||||
{set $v = ($y^$x)+7}
|
||||
```
|
||||
|
||||
Works this array too
|
||||
|
||||
```smarty
|
||||
{set $v = [1,2,3]}
|
||||
{set $v = []}
|
||||
{set $v = ["one"|upper => 1, 4 => $x, "three" => 3]}
|
||||
{set $v = ["key1" => $y*$x-2, "key2" => ["z" => $z]]}
|
||||
```
|
||||
|
||||
Getting function result into variable
|
||||
|
||||
```smarty
|
||||
{set $v = count([1,2,3])+7}
|
||||
```
|
||||
|
||||
Fetch the output of the template into variable
|
||||
|
||||
```smarty
|
||||
{set $v}
|
||||
Some long {$text|trim}
|
||||
{/set}
|
||||
|
||||
{set $v|escape} {* apply modifier to variable*}
|
||||
Some long {$text|trim}
|
||||
{/set}
|
||||
```
|
||||
|
||||
### {add}
|
||||
|
||||
The tag {add} the same tag as {set} except that sets the value of the variable if it does not exist.
|
||||
|
||||
```smarty
|
||||
{add $var = 'value'}
|
||||
```
|
||||
|
||||
instead of
|
||||
|
||||
```smarty
|
||||
{if $var is not set}
|
||||
{set $var = 'value'}
|
||||
{/if}
|
||||
```
|
||||
|
||||
### {var}
|
||||
|
||||
Old name of tag {set}. Currently tag {var} the same tag as {set}.
|
|
@ -1,79 +1,5 @@
|
|||
Documentation
|
||||
=============
|
||||
Languages
|
||||
=========
|
||||
|
||||
**Please, help translate documentation to english or fix typos. [Read more](./helpme.md).**
|
||||
|
||||
### Fenom
|
||||
|
||||
* [Quick start](./start.md)
|
||||
* [Usage](./start.md#install-fenom)
|
||||
* [Framework adapters](./adapters.md)
|
||||
* [For developers](./dev/readme.md)
|
||||
* [Configuration](./configuration.md)
|
||||
* [Syntax](./syntax.md)
|
||||
* [Operators](./operators.md)
|
||||
|
||||
***
|
||||
|
||||
### Tags
|
||||
|
||||
[Usage](./syntax.md#tags)
|
||||
|
||||
* [var](./tags/var.md) — define variable
|
||||
* [if](./tags/if.md), `elseif` and `else` — conditional statement
|
||||
* [foreach](./tags/foreach.md), `foreaelse`, `break` and `continue` — traversing items in an array or object
|
||||
* [for](./tags/for.md), `forelse`, `break` and `continue` — loop statement
|
||||
* [switch](./tags/switch.md), `case`, `default` —
|
||||
* [cycle](./tags/cycle.md) — cycles on an array of values
|
||||
* [include](./tags/include.md), `insert` — includes and evaluates the specified template
|
||||
* [extends](./tags/extends.md), `use`, `block` and `parent` — template inheritance
|
||||
* [filter](./tags/filter.md) — apply modifier on a block of template data
|
||||
* [ignore](./tags/ignore.md) — ignore Fenom syntax
|
||||
* [macro](./tags/macro.md) and `import` — template functions
|
||||
* [autoescape](./tags/autoescape.md) — escape template fragment
|
||||
* [raw](./tags/raw.md) — unescape template fragment
|
||||
* [unset](./tags/unset.md) — unset a given variables
|
||||
* or [add](./ext/extend.md#add-tags) yours
|
||||
|
||||
|
||||
***
|
||||
|
||||
### Modifiers
|
||||
|
||||
[Usage](./syntax.md#modifiers)
|
||||
|
||||
* [upper](./mods/upper.md) aka `up` — convert to uppercase a string
|
||||
* [lower](./mods/lower.md) aka `low` — convert to lowercase a string
|
||||
* [date_format](./mods/date_format.md) - format date, timestamp via strftime() function
|
||||
* [date](./mods/date.md) - format date, timestamp via date() function
|
||||
* [truncate](./mods/truncate.md) — truncate thee string to specified length
|
||||
* [escape](./mods/escape.md) aka `e` — escape the string
|
||||
* [unescape](./mods/unescape.md) — unescape the string
|
||||
* [strip](./mods/strip.md) — remove extra whitespaces
|
||||
* [length](./mods/length.md) — calculate length of string, array, object
|
||||
* [in](./mods/in.md) — find value in string or array
|
||||
* allowed functions: `json_encode`, `json_decode`, `count`, `is_string`, `is_array`, `is_numeric`, `is_int`, `is_object`,
|
||||
`strtotime`, `gettype`, `is_double`, `ip2long`, `long2ip`, `strip_tags`, `nl2br`
|
||||
* or [add](./ext/extend.md#add-modifiers) yours
|
||||
|
||||
***
|
||||
|
||||
### Operators
|
||||
|
||||
* [Arithmetic operators](./operators.md#arithmetic-operators) — `+`, `-`, `*`, `/`, `%`
|
||||
* [Logical operators](./operators.md#logical-operators) — `||`, `&&`, `!$var`, `and`, `or`, `xor`
|
||||
* [Comparison operators](./operators.md#comparison-operators) — `>`, `>=`, `<`, `<=`, `==`, `!=`, `!==`, `<>`
|
||||
* [Bitwise operators](./operators.md#bitwise-operators) — `|`, `&`, `^`, `~$var`, `>>`, `<<`
|
||||
* [Assignment operators](./operators.md#assignment-operators) — `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `|=`, `^=`, `>>=`, `<<=`
|
||||
* [String concatenation operator](./operators.md#string-operator) — `$str1 ~ $str2`
|
||||
* [Ternary operators](./operators.md#ternary-operators) — `$a ? $b : $c`, `$a ! $b : $c`, `$a ?: $c`, `$a !: $c`
|
||||
* [Check operators](./operators.md#check-operators) — `$var?`, `$var!`
|
||||
* [Test operator](./operators.md#test-operator) — `is`, `is not`
|
||||
* [Containment operator](./operators.md#containment-operator) — `in`, `not in`
|
||||
|
||||
***
|
||||
|
||||
### Extends
|
||||
|
||||
* [Extend Fenom](./ext/extend.md)
|
||||
* [Add-ons](./ext/extensions.md)
|
||||
* [English](./en/readme.md)
|
||||
* [Russian](./ru/readme.md)
|
|
@ -0,0 +1,10 @@
|
|||
Адаптеры
|
||||
========
|
||||
|
||||
* [Fenom + Yii](https://bitbucket.org/RSol/rfenomviewrender)
|
||||
* [Fenom + Kohana](https://github.com/2bj/kofenom) — Kofenom
|
||||
* Fenom + Symphony
|
||||
* Fenom + Symphony2
|
||||
* Fenom + Zend Framework 2
|
||||
* [Fenom + MODX Revolution](https://docs.modx.pro/components/pdotools/parser#Шаблонизатор-Fenom)
|
||||
* [Fenom + Slim Framework 3](https://github.com/runcmf/runbb-ext-renderer) — RunBB forum extension
|
|
@ -0,0 +1,6 @@
|
|||
Статьи
|
||||
======
|
||||
|
||||
## 2013
|
||||
|
||||
[Fenom — yet another PHP template engine](http://habrahabr.ru/post/169525/) [RU]
|
|
@ -0,0 +1,63 @@
|
|||
Benchmark
|
||||
=========
|
||||
|
||||
To start benchmark use script `benchmark/run.php -h`.
|
||||
|
||||
### Smarty3 vs Twig vs Fenom
|
||||
|
||||
Smarty3 vs Twig vs Fenom
|
||||
|
||||
Generate templates... Done
|
||||
|
||||
Testing a lot output...
|
||||
smarty3: !compiled and !loaded 3.9101 sec, 15.1 MiB
|
||||
smarty3: compiled and !loaded 0.0235 sec, 9.3 MiB
|
||||
smarty3: compiled and loaded 0.0015 sec, 9.3 MiB
|
||||
|
||||
twig: !compiled and !loaded 1.8725 sec, 68.9 MiB
|
||||
twig: compiled and !loaded 0.0337 sec, 17.0 MiB
|
||||
twig: compiled and loaded 0.0013 sec, 17.0 MiB
|
||||
|
||||
fenom: !compiled and !loaded 0.3157 sec, 8.9 MiB
|
||||
fenom: compiled and !loaded 0.0159 sec, 6.6 MiB
|
||||
fenom: compiled and loaded 0.0012 sec, 6.6 MiB
|
||||
|
||||
|
||||
Testing 'foreach' of big array...
|
||||
smarty3: !compiled and !loaded 0.0355 sec, 5.8 MiB
|
||||
smarty3: compiled and !loaded 0.0032 sec, 3.1 MiB
|
||||
smarty3: compiled and loaded 0.0024 sec, 3.1 MiB
|
||||
|
||||
twig: !compiled and !loaded 0.0799 sec, 4.7 MiB
|
||||
twig: compiled and !loaded 0.0065 sec, 3.2 MiB
|
||||
twig: compiled and loaded 0.0054 sec, 3.5 MiB
|
||||
|
||||
fenom: !compiled and !loaded 0.0459 sec, 3.1 MiB
|
||||
fenom: compiled and !loaded 0.0024 sec, 2.5 MiB
|
||||
fenom: compiled and loaded 0.0017 sec, 2.5 MiB
|
||||
|
||||
|
||||
Testing deep 'inheritance'...
|
||||
smarty3: !compiled and !loaded 0.3984 sec, 10.2 MiB
|
||||
smarty3: compiled and !loaded 0.0009 sec, 3.1 MiB
|
||||
smarty3: compiled and loaded 0.0001 sec, 3.1 MiB
|
||||
|
||||
twig: !compiled and !loaded 0.2897 sec, 11.2 MiB
|
||||
twig: compiled and !loaded 0.0197 sec, 6.5 MiB
|
||||
twig: compiled and loaded 0.0019 sec, 6.5 MiB
|
||||
|
||||
fenom: !compiled and !loaded 0.0546 sec, 3.2 MiB
|
||||
fenom: compiled and !loaded 0.0005 sec, 2.5 MiB
|
||||
fenom: compiled and loaded 0.0000 sec, 2.5 MiB
|
||||
|
||||
* **!compiled and !loaded** - template engine object created but parsers not initialized and templates not compiled
|
||||
* **compiled and !loaded** - template engine object created, template compiled but not loaded
|
||||
* **compiled and loaded** - template engine object created, template compiled and loaded
|
||||
|
||||
### Stats
|
||||
|
||||
| Template Engine | Files | Classes | Lines |
|
||||
| --------------- | ------:| --------:| ------:|
|
||||
| Smarty3 (3.1.13)| 320 | 190 | 55095 |
|
||||
| Twig (1.13.0) | 162 | 131 | 13908 |
|
||||
| Fenom (1.0.1) | 9 | 16 | 3899 |
|
|
@ -0,0 +1,3 @@
|
|||
Callbacks
|
||||
=========
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
Настройка
|
||||
=========
|
||||
|
||||
## Configure
|
||||
|
||||
### Кеш шаблонов
|
||||
|
||||
```php
|
||||
$fenom->setCompileDir($dir);
|
||||
```
|
||||
|
||||
Задает имя каталога, в котором хранятся компилированные шаблоны. По умолчанию это `/tmp`. Каталог дожен быть доступен на запись.
|
||||
|
||||
### Параметры обработчика
|
||||
|
||||
Установка параметров через фабрику
|
||||
```php
|
||||
$fenom = Fenom::factory($tpl_dir, $compile_dir, $options);
|
||||
```
|
||||
|
||||
Установка параметров через метод
|
||||
```php
|
||||
$fenom->setOptions($options);
|
||||
```
|
||||
В обоих случаях аргумет `$options` может быть массивом или битовой маской.
|
||||
В массиве ключем должно быть название параметра, а значением — булевый флаг `true` (активировать) или `false` (деактивировать).
|
||||
Битовая маска должна состоять из значений констант, согласно следующей таблице
|
||||
|
||||
| Название параметра | Константа | Описание | Эффект |
|
||||
| ---------------------- | ------------------------- | ------------ | ------- |
|
||||
| *disable_methods* | `Fenom::DENY_METHODS` | отключает возможность вызова методов в шаблоне | |
|
||||
| *disable_native_funcs* | `Fenom::DENY_NATIVE_FUNCS`| отключает возможность использования функций PHP, за исключением разрешенных | |
|
||||
| *auto_reload* | `Fenom::AUTO_RELOAD` | автоматически пересобирать кеш шаблона если шаблон изменился | понижает производительность |
|
||||
| *force_compile* | `Fenom::FORCE_COMPILE` | каждый раз пересобирать кеш шаблонов (рекомендуется только для отладки)| очень сильно понижает производительность |
|
||||
| *disable_cache* | `Fenom::DISABLE_CACHE` | не кешировать компилированный шаблон | эпично понижает производительность |
|
||||
| *force_include* | `Fenom::FORCE_INCLUDE` | стараться по возможности вставить код дочернего шаблона в родительский при подключении шаблона | повышает производительность, увеличивает размер файлов в кеше, уменьшает количество файлов в кеше |
|
||||
| *auto_escape* | `Fenom::AUTO_ESCAPE` | автоматически экранировать HTML сущности при выводе переменных в шаблон | понижает производительность |
|
||||
| *force_verify* | `Fenom::FORCE_VERIFY` | автоматически проверять существование переменной перед использованием в шаблоне | понижает производительность |
|
||||
| *disable_call* | `Fenom::DENY_CALL` | отключает возможность вызова статических методов и функций в шаблоне | |
|
||||
| *disable_php_calls* | `Fenom::DENY_PHP_CALLS` | устаревшее название disable_call | |
|
||||
| *disable_statics* | `Fenom::DENY_STATICS` | устаревшее название disable_call | |
|
||||
| *strip* | `Fenom::AUTO_STRIP` | удаляет лишиние пробелы в шаблоне | уменьшает размер кеша |
|
||||
|
||||
```php
|
||||
$fenom->setOptions(array(
|
||||
"force_compile" => true,
|
||||
"force_include" => true
|
||||
));
|
||||
// тоже самое что и
|
||||
$fenom->setOptions(Fenom::AUTO_RELOAD | Fenom::FORCE_INCLUDE);
|
||||
```
|
||||
|
||||
```php
|
||||
$fenom->addCallFilter('View\Widget\*::get*')
|
||||
```
|
||||
|
||||
**Замечание**
|
||||
По умолчанию все параметры деактивированы.
|
|
@ -0,0 +1,90 @@
|
|||
How it work
|
||||
===========
|
||||
|
||||
**Устарело**
|
||||
|
||||
## Терминология
|
||||
|
||||
* Исходный шаблон - изначальный вид шаблона в специальном синтаксисе
|
||||
* Код шаблона - резальтат компиляции шаблона, PHP код.
|
||||
* Провайдер - объект, источник исходных шаблонов.
|
||||
|
||||
## Классы
|
||||
|
||||
* `Fenom` - является хранилищем
|
||||
* [шаблонов](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L88)
|
||||
* [модификаторов](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L112)
|
||||
* [фильтров](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L73)
|
||||
* [тегов](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L140)
|
||||
* [провайдеров](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L107)
|
||||
* [настройки](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L98) - маска из [опций](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L29)
|
||||
* [список](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L131) разрешенных функций
|
||||
|
||||
а также обладает соответсвующими setter-ами и getter-ами для настройки.
|
||||
* `Fenom\Tokenizer` - разбирает, при помощи [tokens_get_all](http://docs.php.net/manual/en/function.token-get-all.php), строку на токены, которые хранит [массивом](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Tokenizer.php#L84).
|
||||
Обладает методами для обработки токенов, работающими как с [конкретными токенами](http://docs.php.net/manual/en/tokens.php) так и с их [группами](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Tokenizer.php#L94).
|
||||
* `Fenom\Render` - простейший шаблон. Хранит
|
||||
* `Closure` с [PHP кодом](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Render.php#L30) шаблона
|
||||
* [настройки](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Render.php#L19)
|
||||
* [зависимости](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Render.php#L59)
|
||||
* `Fenom\Template` - шаблон с функцией компиляции, расширен от `Fenom\Render`. Содержит различные методы для разбора выражений при помощи `Fenom\Tokenizer`.
|
||||
* `Fenom\Compiler` - набор правил разбора различных тегов.
|
||||
* `Fenom\Modifier` - набор модификаторов.
|
||||
* `Fenom\Scope` - абстрактный уровень блочного тега.
|
||||
* `Fenom\ProviderInterface` - интерфейс провадеров шаблонов
|
||||
* `Fenom\Provider` - примитивный провайдер шаблонов с файловой системы.
|
||||
|
||||
## Процесс работы
|
||||
|
||||
При вызове метода `Fenom::display($template, $vars)` шаблонизатор [ищет](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L712) в своем хранилище уже загруженный шаблон.
|
||||
Если шаблона [нет](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L727) - либо [загружает](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L762) код шаблона с файловой системы, либо [инициирует](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L759) его [компиляцию](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L788).
|
||||
|
||||
### Компиляция шаблонов
|
||||
|
||||
* [Создается](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L660) "пустой" `Fenom\Template`
|
||||
* В него [загружется](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L157) исходный шаблон [из провайдера](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L167)
|
||||
* Исходный шаблон проходит [pre-фильтры](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L200).
|
||||
* Начинается [разбор](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L196) исходного шаблона.
|
||||
* [Ищется](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L204) первый открывающий тег символ - `{`
|
||||
* [Смотрятся](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L205) следующий за `{` символ.
|
||||
* Если `}` или пробельный символ - ищется следующий символ `{`
|
||||
* Если `*` - ищется `*}`, текст до которого, в последствии, вырезается.
|
||||
* Ищется символ `}`. Полученный фрагмент шаблона считается тегом.
|
||||
* Если [был тег](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L238) `{ignore}` название тега проверяется на закрытие этого тега.
|
||||
* Для тега [создается](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L245) токенайзер и отдается в [диспетчер](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L488) тегов
|
||||
* Диспетчер тега вызывает различные парсеры выражений, компилятор тега и возвращает PHP код (см ниже).
|
||||
* Полученный фрагмент PHP кода [обрабатывается и прикрепляется](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L362) к коду шаблона.
|
||||
* Ищется следующий `{` символ...
|
||||
* ...
|
||||
* В конце проверяется токенайзер на наличие не используемых токенов, если таковые есть - выбрасывается ошибка.
|
||||
* [Проверяется](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L264) стек на наличие не закрытых блоковых тегов
|
||||
* PHP код проходит [post-фильтры](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L282)
|
||||
* Код шаблона [сохраняется](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L799) на файлувую систему
|
||||
* Код шаблона выполняется для использования
|
||||
|
||||
### Как работает токенайзер
|
||||
|
||||
Объект токенайзера принимает на вход любую строчку и разбирает ее при помощи функции token_get_all(). Полученные токен складываются в массив. Каждый токен прдсатвляет из себя числовой массив из 4-х элементов:
|
||||
|
||||
* Код токена. Это либо число либо один символ.
|
||||
* Тело токена. Содержимое токена.
|
||||
* Номер строки в исходной строке
|
||||
* Пробельные символы, идущие за токеном
|
||||
|
||||
Токенайзер обладает внутренним указателем на "текущий" токен, передвигая указатель можно получить доступ к токенам через специальные функции-проверки. Почти все функции-проверки проверяют текущее значение на соответствие кода токену. Вместо кода может быть отдан код группы токенов.
|
||||
|
||||
### Как работает диспетчер тегов
|
||||
|
||||
* Проверяет, не является выражение в токенайзере [тегом ignore](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L492).
|
||||
* Проверяет, не является выражение в токенайзере [закрывающим тегом](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L499).
|
||||
* Проверяет, не является выражение в токенайзере [скалярным значением](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L566).
|
||||
* По имени тега из [списка тегов](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L140) выбирается массив и запускается [соответствующий](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom/Template.php#L582) парсер.
|
||||
* Парсер возвращает PHP код
|
||||
|
||||
### Как работают парсеры
|
||||
|
||||
Парсер всегда получает объект токенайзера. Курсор токенайзера установлен на токен с которого начинается выражение, которое должен разобрать парсер.
|
||||
Таким образом, по завершению разбора выражения, парсер должен установить курсор токенайзера на первый незнакомый ему символ.
|
||||
Для примера рассмортим парсер переменной `Fenom\Template::parseVar()`.
|
||||
В шаблоне имеется тег {$list.one.c|modifier:1.2}. В парсер будет отдан объект токенайзера `new Tokenizer('$list.one.c|modifier:1.2')` с токенами `$list` `.` `one` `.` `c` `|` `modifier` `:` `1.2`.
|
||||
Указатель курсора установлен на токен `$list`. После разбора токенов, курсор будет установлен на `|` так как это не знакомый парсеру переменных токен. Следующий парсер может быть вызван `Fenom\Template::parseModifier()`, который распарсит модификатор.
|
|
@ -0,0 +1,22 @@
|
|||
Develop
|
||||
=======
|
||||
|
||||
Если у Вас есть что обсудить или предложить создайте issue на Github или сделайте запрос на сливание.
|
||||
|
||||
По вопросам можете слать письмо на email: a.cobest@gmail.com (Русский и английские языки)
|
||||
|
||||
|
||||
## Соглашение по наименованию версий
|
||||
|
||||
Версии именуются согласно [Semantic Versioning 2.0.0](http://semver.org/).
|
||||
|
||||
## Соглашение по GIT
|
||||
|
||||
Ветка `master` содержит стабильную последнюю версию проекта.
|
||||
В ветку `master` может сливаться новая версия проекта из `develop` или исправления.
|
||||
Ветка `develop`, для разработки, содержит не стабильную версию проекта. Принимает новшества, изменения и исправления.
|
||||
|
||||
|
||||
## Принцип работы
|
||||
|
||||
Разобраться в принципе работы поможет [эта схема](schema.md).
|
|
@ -0,0 +1,120 @@
|
|||
How Fenom works
|
||||
===============
|
||||
|
||||
```
|
||||
|
||||
use Fenom;
|
||||
use Fenom\Render;
|
||||
use Fenom\Template;
|
||||
use Fenom\Tokenizer;
|
||||
|
||||
______________________________
|
||||
| |
|
||||
| Fenom::display($tpl, $var) |
|
||||
|____________________________|
|
||||
|
|
||||
| search the template
|
||||
______________|___________________________
|
||||
| Template loaded into Fenom::$_storage? |
|
||||
| Fenom::getTemplate($tpl) |
|
||||
|________________________________________|
|
||||
| |
|
||||
| yes | no
|
||||
______________|__________ |
|
||||
| Render the template | |
|
||||
| Render::display($tpl) | |
|
||||
|_______________________| |
|
||||
| |
|
||||
| (hot start) |
|
||||
| ______________________________|__________________
|
||||
| | Template already compiled and stored in cache |
|
||||
| | Fenom::getTemplate($template) |
|
||||
| |_______________________________________________|
|
||||
| | |
|
||||
| | yes | no
|
||||
| ____________|_______________ |
|
||||
| | Load template from cache | not found |
|
||||
| | Fenom::_load(...) |-------------->|
|
||||
| |__________________________| |
|
||||
| | |
|
||||
| | found |
|
||||
| ____________|___________ |
|
||||
| | Validate template | invalid |
|
||||
| | Render::isValid(...) |------------------>|
|
||||
| |______________________| |
|
||||
| | |
|
||||
| | valid |
|
||||
| ____________|____________ |
|
||||
| | Render the template | |
|
||||
|<----| Render::display(...) | |
|
||||
| |_______________________| |
|
||||
| |
|
||||
| _____________________________ ________|___________________
|
||||
| | Initialize compiler | | Compile the template |
|
||||
| | Template::load($tpl) |<-----| Fenom::compile($tpl) |
|
||||
| |___________________________| |__________________________|
|
||||
| |
|
||||
| ____________|________________
|
||||
| | Load template source |
|
||||
| | Provider::getSource($tpl) |
|
||||
| |___________________________|
|
||||
| |
|
||||
| ____________|______________
|
||||
| | Start compilation |
|
||||
| | Template::compile($tpl) |
|
||||
| |_________________________|
|
||||
| |
|
||||
| ____________|______________
|
||||
| | Search template tag |
|
||||
| | Template::compile($tpl) |<------------------------------------------------------|
|
||||
| |_________________________| |
|
||||
| | | |
|
||||
| | not found | found |
|
||||
| | _____________|_______________ _______________________________ |
|
||||
| | | Tokenize the tag's code | | Parse the tag | |
|
||||
| | | new Tokenizer($tag) |--->| Template::parseTag($tokens) | |
|
||||
| | |___________________________| |_____________________________| |
|
||||
| | | | |
|
||||
| | is tag | | is expression |
|
||||
| | _______________________________ | _______________|________________ |
|
||||
| | | Detect tag name | | | Detect expression | |
|
||||
| | | Template::parseAct($tokens) |<--- | Template::parseAct($tokens) | |
|
||||
| | | Get callback by tag name | | Parse expression | |
|
||||
| | | Fenom::getTag($tag_name) | | Template::parseExpr($tokens) | |
|
||||
| | |_____________________________| |______________________________| |
|
||||
| | | | |
|
||||
| | | found | |
|
||||
| | _______________|_______________ | |
|
||||
| | | Invoke callback | | |
|
||||
| | | Template::parseAct($tokens) | | |
|
||||
| | |_____________________________| | |
|
||||
| | | | |
|
||||
| | _______________|________________ | |
|
||||
| | | Append code to template | | |
|
||||
| | | Template::_appendCode($code) |<----------------------- |
|
||||
| | |______________________________| |
|
||||
| | | |
|
||||
| | _______________|___________ |
|
||||
| | | Finalize the tag | starts search next tag |
|
||||
| | | Template::compile($tpl) |>------------------------------------------------
|
||||
| | |_________________________|
|
||||
| |
|
||||
| __|___________________________________
|
||||
| | Store template to cache |
|
||||
| | Fenom::compile($tpl) |
|
||||
| | Store template to Fenom::$_storage |
|
||||
| | Fenom::getTemplate($tpl) |
|
||||
| |____________________________________|
|
||||
| |
|
||||
| ____________|_____________
|
||||
| | Render the template |
|
||||
| | Template::display(...) |
|
||||
| |________________________|
|
||||
| |
|
||||
| | (cold start)
|
||||
__|_________|________
|
||||
| |
|
||||
| DONE |
|
||||
|___________________|
|
||||
|
||||
```
|
|
@ -0,0 +1,281 @@
|
|||
Расширение Fenom
|
||||
================
|
||||
|
||||
# Добавление тегов
|
||||
|
||||
В шаблонизаторе принято различать два типа тегов: _компиляторы_ и _функции_.
|
||||
Компиляторы вызываются во время преобразования кода шаблона в PHP код и возвращают PHP код который будет вставлен вместо тега.
|
||||
А функции вызываются непременно в момент выполнения шаблона и возвращают непосредственно данные которые будут отображены.
|
||||
Среди тегов как и в HTML есть строчные и блоковые теги.
|
||||
|
||||
## Линейные функции
|
||||
|
||||
Примитивное добавление функции можно осуществить следующим образом:
|
||||
|
||||
```php
|
||||
$fenom->addFunction(string $function_name, callable $callback[, callable $parser]);
|
||||
```
|
||||
|
||||
В данном случае запускается стандартный парсер, который автоматически разберет аргументы тега, которые должны быть в формате HTML атрибутов и отдаст их в функцию ассоциативным массивом:
|
||||
```php
|
||||
$fenom->addFunction("some_function", function (array $params) { /* ... */ });
|
||||
```
|
||||
При необходимости можно переопределить парсер на произвольный:
|
||||
```php
|
||||
$fenom->addFunction("some_function", $some_function, function (Fenom\Tokenizer $tokenizer, Fenom\Template $template) { /* parse tag */});
|
||||
```
|
||||
Существует более простой способ добавления произвольной функции:
|
||||
|
||||
```php
|
||||
$fenom->addFunctionSmart(string $function_name, callable $callback);
|
||||
```
|
||||
|
||||
В данном случае парсер сканирует список аргументов коллбека и попробует сопоставить с аргументами тега.
|
||||
|
||||
```php
|
||||
// ... class XYCalcs ..
|
||||
public static function calc($x, $y = 5) { /* ... */}
|
||||
// ...
|
||||
$fenom->addFunctionSmart('calc', 'XYCalcs::calc');
|
||||
```
|
||||
пример выше позволяет объявить тег `{calc}` и спользовать его:
|
||||
```smarty
|
||||
{calc x=$top y=50} или {calc y=50 x=$top} вызовет XYCalcs::calc($top, 50)
|
||||
{calc x=$top} или {calc $top} вызовет XYCalcs::calc($top)
|
||||
```
|
||||
Таким образом вы успешно можете добавлять Ваши функции или методы.
|
||||
|
||||
## Блоковые функции
|
||||
|
||||
Добавление блоковой функции аналогичен добавлению строковой за исключением того что есть возможность указать парсер для закрывающего тега.
|
||||
|
||||
```php
|
||||
$fenom->addBlockFunction(string $function_name, callable $callback[, callable $parser_open[, callable $parser_close]]);
|
||||
```
|
||||
|
||||
Сам коллбек принимает первым аргументом контент между открывающим и закрывающим тегом, а вторым аргументом - ассоциативный массив из аргуметов тега:
|
||||
```php
|
||||
$fenom->addBlockFunction('some_block_function', function (array $params, $content) { /* ... */});
|
||||
```
|
||||
|
||||
## Линейный компилятор
|
||||
|
||||
Добавление строчного компилятора осуществляеться очень просто:
|
||||
|
||||
```php
|
||||
$fenom->addCompiler(string $compiler, callable $parser);
|
||||
```
|
||||
|
||||
Парсер должен принимать `Fenom\Tokenizer $tokenizer`, `Fenom\Template $template` и возвращать PHP код.
|
||||
Компилятор так же можно импортировать из класса автоматически
|
||||
|
||||
```php
|
||||
$fenom->addCompilerSmart(string $compiler, $storage);
|
||||
```
|
||||
|
||||
`$storage` может быть как классом так и объектом. В данном случае шаблонизатор будет искать метод `tag{$compiler}`, который будет взят в качестве парсера тега.
|
||||
|
||||
## Блоковый компилятор
|
||||
|
||||
Добавление блочного компилятора осуществяется двумя способами. Первый
|
||||
|
||||
```php
|
||||
$fenom->addBlockCompiler(string $compiler, array $parsers, array $tags);
|
||||
```
|
||||
|
||||
где `$parser` ассоциативный массив `["open" => parser, "close" => parser]`, сождержащий парсер на открывающий и на закрывающий тег, а `$tags` содержит список внутренних тегов в формате `["tag_name"] => parser`, которые могут быть использованы только с этим компилятором.
|
||||
Второй способ добавления парсера через импортирование из класса или объекта методов:
|
||||
|
||||
```php
|
||||
$fenom->addBlockCompilerSmart(string $compiler, $storage, array $tags, array $floats);
|
||||
```
|
||||
|
||||
# Добавление модификаторов
|
||||
|
||||
```
|
||||
$fenom->addModifier(string $modifier, callable $callback);
|
||||
```
|
||||
|
||||
* `$modifier` - название модификатора, которое будет использоваться в шаблоне
|
||||
* `$callback` - функция обратного вызова, которая будет вызвана для изменения данных
|
||||
|
||||
Например:
|
||||
|
||||
```smarty
|
||||
{$variable|my_modifier:$param1:$param2}
|
||||
```
|
||||
|
||||
```php
|
||||
$fenom->addModifier('my_modifier', function ($variable, $param1, $param2) {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
# Расширение тестового оператора
|
||||
|
||||
```php
|
||||
$fenom->addTest(string $name, string $code);
|
||||
```
|
||||
`$code` - PHP код для условия, с маркером для замены на значение или переменную.
|
||||
Например, тест на целое число `is int` можно добавить как `$fenom->addTest('int', 'is_int(%s)')`.
|
||||
В шаблоне тесты выглядит как `{$a is int}`, а после компиляции выглядит приблизительно так - `is_int($a)`.
|
||||
|
||||
# Расширение глобальной переменной
|
||||
|
||||
Fenom обладает определенным [набором глобальных переменных](../syntax.md#Системная-переменная).
|
||||
Однако их может не хватать для удобной работы и в этом случае потребуется добавить свои или переопределить/удалить существующие.
|
||||
Метод `Fenom::addAccessor(string $name, callable $parser)` позволяет добавить свой обработчик-парсер `$parser`,
|
||||
который будет вызван при встрече с глобальной переменной `$name` **во время компиляции шаблона**.
|
||||
|
||||
```php
|
||||
$fenom->addAccessor('project', function (Fenom\Tokenizer $tokens) { /* code */ });
|
||||
```
|
||||
|
||||
Указанный вторым аргументом, парсер будет вызван при встречи компилятором конструкции `$.project`.
|
||||
Парсер сам должен разобрать все токены из набора токенов `$tokens` до того момента пока не посчитает что ему их хватит для
|
||||
интерпретации. Возвращает парсер PHP код, который должен представлять значение восле выполенения, то есть его можно втавить в `if()`.
|
||||
|
||||
Через метод `Fenom::addAccessor($name, $parser)` можно переопределить уже любую другую существующую глобальную переменную.
|
||||
Метод `Fenom::removeAccessor($name)` позволяет удалить любую определенную глобальную переменную или функцию по ее имени.
|
||||
|
||||
## Готовые решения
|
||||
|
||||
Орпеделить парсер для глобальной переменной весьма трудозатратно и требует полного понимания как работают парсеры в Fenom.
|
||||
Это не удобно. Поэтому есть несколько предзаготовленных (умных) парсеров, которые берут рутину на себя, а пользователю остается указать ключевые параметры.
|
||||
|
||||
Умные парсеты добавляются через метод `Fenom::addAccessorSmart(string $name, string $accessor, string $parser)`,
|
||||
где `$name` имя глобальной переменной, `$accessor` — параметр к парсеру, `$parser` — предопределенный парсер.
|
||||
|
||||
### Доступ к свойству
|
||||
|
||||
Парсер `Fenom::ACCESSOR_PROPERTY` позволит обратится к указанному свойству шаблонизатора из шаблона.
|
||||
Параметр `$accessor` выступает как **имя свойства**:
|
||||
|
||||
```php
|
||||
$fenom->addAccessorSmart("site", "data", Fenom::ACCESSOR_PROPERTY);
|
||||
$fenom->data = [
|
||||
"domain" => 'example.ru',
|
||||
"support" => 'support@example.ru'
|
||||
];
|
||||
```
|
||||
В шаблоне появится глобальная переменная `$.site`:
|
||||
```smarty
|
||||
<div class="copyright">© <a href="//{$.site.domain}">{$.site.domain}</a></div>
|
||||
<div class="support">Support <a href="mailto:{$.site.support}">{$.site.support}</a></div>
|
||||
```
|
||||
Свойством может быть любое значение — масиив, объект и т.д.
|
||||
|
||||
### Доступ к методу
|
||||
|
||||
Парсер `Fenom::ACCESSOR_METHOD` позволит обратится к указанному методу шаблонизатора из шаблона.
|
||||
Параметр `$accessor` выступает как **имя метода**:
|
||||
```php
|
||||
$fenom->addAccessorSmart("fetch", "fetch", Fenom::ACCESSOR_METHOD);
|
||||
```
|
||||
В шаблоне появится глобальная функция `$.fetch`:
|
||||
```smarty
|
||||
{set $menu = $.fetch("site/menu.tpl")} {* $menu = $fenom->fetch("site/menu.tpl") *}
|
||||
```
|
||||
Шаблонизатор не проверят количество и тип параметров которые передает в метод.
|
||||
|
||||
### Доступ к значению
|
||||
|
||||
Парсер `Fenom::ACCESSOR_VAR` позволит обратится к указанному значению из шаблона.
|
||||
Параметр `$accessor` выступает как **PHP выражение**, описывающее значение:
|
||||
```php
|
||||
$fenom->addAccessorSmart("storage", "App::getInstance()->storage", Fenom::ACCESSOR_VAR);
|
||||
```
|
||||
В шаблоне появится глобальная переменная `$.storage`:
|
||||
```smarty
|
||||
{set $st = $.storage.di.stamp} {* $st = App::getInstance()->storage['di']['stamp'] *}
|
||||
```
|
||||
|
||||
### Доступ к callable
|
||||
|
||||
Парсер `Fenom::ACCESSOR_CALL` позволит вызвать указанную финкцию или метод из шаблона.
|
||||
Параметр `$accessor` выступает как **PHP выражение**, описывающее название функции или метод:
|
||||
```php
|
||||
$fenom->addAccessorSmart("di", "App::getInstance()->di->get", Fenom::ACCESSOR_CALL);
|
||||
```
|
||||
`App::getInstance()->di->get` доллжно быть callable, то есть
|
||||
```php
|
||||
is_callable([App::getInstance()->di, "get"]) === true;
|
||||
```
|
||||
В шаблоне появится глобальная переменная `$.di`:
|
||||
```smarty
|
||||
{set $st = $.di("stamp")} {* $st = App::getInstance()->di->get("stamp") *}
|
||||
```
|
||||
Шаблонизатор не проверят количество и тип параметров которые передает в метод или функцию.
|
||||
|
||||
# Источники шаблонов
|
||||
|
||||
Шаблоны можно получать из самых разных источников.
|
||||
Когда вы отображаете или вызываете шаблон, либо когда вы подключаете один шаблон к другому, вы указываете источник,
|
||||
вместе с соответствующим путём и названием шаблона. Если источник явно не задан, то используется источник `Fenom\Provider`,
|
||||
который считывает шаблоны из указанной директории.
|
||||
|
||||
Источник шаблонов должен реализовать интерфейс `Fenom\ProviderInterface`.
|
||||
Используйте метод `$fenom->setProvider(...)` что бы добавить источник в шаблонизатор, указав название источника и, если есть необходимость,
|
||||
задать директорию кеша для шаблонов из этого источника. Рассмотрим на примере, реализуем источник шаблонов из базы данных.
|
||||
|
||||
Создадим источник:
|
||||
|
||||
```php
|
||||
|
||||
class DbProvider implements Fenom\ProviderInterface {
|
||||
// ...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Добавляем источник, указав удобное имя.
|
||||
|
||||
```php
|
||||
|
||||
$provider = new DbProvider();
|
||||
$fenom->setProvider("db", $provider, "/tmp/cached/db");
|
||||
```
|
||||
|
||||
Теперь источник можно использовать.
|
||||
|
||||
```php
|
||||
$fenom->display("db:index.tpl", $vars);
|
||||
```
|
||||
|
||||
```smarty
|
||||
{include "db:menu.tpl"}
|
||||
```
|
||||
|
||||
# Расширение кеша (эксперементальное)
|
||||
|
||||
Изначально Fenom не рассчитывался на то что кеш скомпиленых шаблонов может располагаться не на файловой системе.
|
||||
Однако, в теории, есть возможность реализовать свое кеширование для скомпиленых шаблонов без переопределения шаблонизатора.
|
||||
Речь идет о своем протоколе, отличным от `file://`, который [можно определить](http://php.net/manual/en/class.streamwrapper.php) в PHP.
|
||||
|
||||
Ваш протокол должен иметь класс реализации как указано в документации [Stream Wrapper](http://www.php.net/manual/en/class.streamwrapper.php).
|
||||
Класс протокола может иметь не все указанные в документации методы. Вот список методов, необходимых шаблонизатору:
|
||||
|
||||
* [CacheStreamWrapper::stream_open](http://www.php.net/manual/en/streamwrapper.stream-open.php)
|
||||
* [CacheStreamWrapper::stream_write](http://www.php.net/manual/en/streamwrapper.stream-write.php)
|
||||
* [CacheStreamWrapper::stream_close](http://www.php.net/manual/en/streamwrapper.stream-close.php)
|
||||
* [CacheStreamWrapper::rename](http://www.php.net/manual/en/streamwrapper.rename.php)
|
||||
|
||||
Для работы через `include`:
|
||||
|
||||
* [CacheStreamWrapper::stream_stat](http://www.php.net/manual/en/streamwrapper.stream-stat.php)
|
||||
* [CacheStreamWrapper::stream_read](http://www.php.net/manual/en/streamwrapper.stream-read.php)
|
||||
* [CacheStreamWrapper::stream_eof](http://www.php.net/manual/en/streamwrapper.stream-eof.php)
|
||||
|
||||
**Note**
|
||||
(On 2014-05-13) Zend OpCacher кроме `file://` и `phar://` не поддерживает другие протоколы.
|
||||
|
||||
Пример работы кеша
|
||||
|
||||
```php
|
||||
$this->setCacheDir("redis://hash/compiled/");
|
||||
```
|
||||
|
||||
* `$cache = fopen("redis://hash/compiled/XnsbfeDnrd.php", "w");`
|
||||
* `fwrite($cache, "... <template content> ...");`
|
||||
* `fclose($cache);`
|
||||
* `rename("redis://hash/compiled/XnsbfeDnrd.php", "redis://hash/compiled/main.php");`
|
|
@ -0,0 +1,9 @@
|
|||
Extensions
|
||||
==========
|
||||
|
||||
* [Extra pack](https://github.com/bzick/fenom-extra) of add-ons for Fenom template engine.
|
||||
* Tools for static files (css, js).
|
||||
* Global variables
|
||||
* Allow more hooks for extending
|
||||
* Add variable container
|
||||
* You can only use the necessary add-ons
|
|
@ -0,0 +1,90 @@
|
|||
Tags [RU]
|
||||
=========
|
||||
|
||||
В шаблонизаторе принято различать два типа тегов: _компиляторы_ и _функции_.
|
||||
Компиляторы вызываются во время преобразования кода шаблона в PHP код и возвращяю PHP код который будет вставлен вместо тега.
|
||||
А функции вызываются непременно в момент выполнения шаблона и возвращают непосредственно данные которые будут отображены.
|
||||
Среди тегов как и в HTML есть строчные и блоковые теги.
|
||||
|
||||
## Inline function
|
||||
|
||||
Примитивное добавление функции можно осуществить следующим образом:
|
||||
|
||||
```php
|
||||
$fenom->addFunction(string $function_name, callable $callback[, callable $parser]);
|
||||
```
|
||||
|
||||
В данном случае запускается стандартный парсер, который автоматически разберет аргументы тега, которые должны быть в формате HTML аттрибутов и отдаст их в функцию ассоциативным массивом:
|
||||
```php
|
||||
$fenom->addFunction("some_function", function (array $params) { /* ... */ });
|
||||
```
|
||||
При необходимости можно переопределить парсер на произвольный:
|
||||
```php
|
||||
$fenom->addFunction("some_function", $some_function, function (Fenom\Tokenizer $tokenizer, Fenom\Template $template) { /* parse tag */});
|
||||
```
|
||||
Существует более простой способ добавления произвольной функции:
|
||||
|
||||
```php
|
||||
$fenom->addFunctionSmarty(string $function_name, callable $callback);
|
||||
```
|
||||
|
||||
В данном случае парсер сканирует список аргументов коллбека и попробует сопоставить с аргументами тега.
|
||||
|
||||
```php
|
||||
// ... class XYCalcs ..
|
||||
public static function calc($x, $y = 5) { /* ... */}
|
||||
// ...
|
||||
$fenom->addFunctionSmart('calc', 'XYCalcs::calc');
|
||||
```
|
||||
then
|
||||
```smarty
|
||||
{calc x=$top y=50} or {calc y=50 x=$top} is XYCalcs::calc($top, 50)
|
||||
{calc x=$top} or {calc $top} is XYCalcs::calc($top)
|
||||
```
|
||||
Таким образом вы успешно можете добавлять Ваши функции или методы.
|
||||
|
||||
## Block function
|
||||
|
||||
Добавление блоковой функции аналогичен добавлению строковой за исключением того что есть возможность указать парсер для закрывающего тега.
|
||||
|
||||
```php
|
||||
$fenom->addBlockFunction(string $function_name, callable $callback[, callable $parser_open[, callable $parser_close]]);
|
||||
```
|
||||
|
||||
Сам коллбек принимает первым аргументом контент между открывающим и закрывающим тегом, а вторым аргументом - ассоциативный массив из аргуметов тега:
|
||||
```php
|
||||
$fenom->addBlockFunction('some_block_function', function ($content, array $params) { /* ... */});
|
||||
```
|
||||
|
||||
## Inline compiler
|
||||
|
||||
Добавление строчного компилятора осуществляеться очень просто:
|
||||
|
||||
```php
|
||||
$fenom->addCompiler(string $compiler, callable $parser);
|
||||
```
|
||||
|
||||
Парсер должен принимать `Fenom\Tokenizer $tokenizer`, `Fenom\Template $template` и возвращать PHP код.
|
||||
Компилятор так же можно импортировать из класса автоматически
|
||||
|
||||
```php
|
||||
$fenom->addCompilerSmart(string $compiler, $storage);
|
||||
```
|
||||
|
||||
`$storage` может быть как классом так и объектом. В данном случае шаблонизатор будет искать метод `tag{$compiler}`, который будет взят в качестве парсера тега.
|
||||
|
||||
## Block compiler
|
||||
|
||||
Добавление блочного компилятора осуществяется двумя способами. Первый
|
||||
|
||||
```php
|
||||
$fenom->addBlockCompiler(string $compiler, array $parsers, array $tags);
|
||||
```
|
||||
|
||||
где `$parser` ассоциативный массив `["open" => parser, "close" => parser]`, сождержащий парсер на открывающий и на закрывающий тег, а `$tags` содержит список внутренних тегов в формате `["tag_name"] => parser`, которые могут быть использованы только с этим компилятором.
|
||||
Второй способ добавления парсера через импортирование из класса или объекта методов:
|
||||
|
||||
```php
|
||||
$fenom->addBlockCompilerSmart(string $compiler, $storage, array $tags, array $floats);
|
||||
```
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
Наследование шаблонов
|
||||
=====================
|
||||
|
||||
Документации пока нет, [почитайте на хабре](http://habrahabr.ru/post/169525/) пока
|
|
@ -0,0 +1,63 @@
|
|||
Модификатор date_format
|
||||
====================
|
||||
|
||||
Форматирует дату согласно указанному формату [strftime()](http://docs.php.net/ru/strftime).
|
||||
Даты могут быть переданы в виде временных меток unix, временных меток mysql или в виде любой строки, содержащей день,
|
||||
месяц и год, которую может обработать функция [strftime()](http://docs.php.net/ru/strftime).
|
||||
|
||||
```smarty
|
||||
{$date|date_format:$format = `%b %e, %Y`}
|
||||
```
|
||||
|
||||
Формат по умолчанию: `%b %e, %Y`.
|
||||
|
||||
```smarty
|
||||
{var $ts = time()}
|
||||
|
||||
{$ts|date_format:"%Y/%m/%d %H:%M:%S"} выведет 2013/02/08 21:01:43
|
||||
{$ts|date_format:"-1 day"} выведет вчерашний день, например 2013/02/07 21:01:43
|
||||
|
||||
{var $date = "2008-12-08"}
|
||||
|
||||
{$ts|date_format:"%Y/%m/%d %H:%M:%S"} выведет 2008/12/08 00:00:00
|
||||
```
|
||||
|
||||
[Конверсионные указатели](http://docs.php.net/ru/strftime#refsect1-function.strftime-parameters) в модификаторе **date_format**:
|
||||
|
||||
* %a - сокращенное название дня недели, в зависимости от текущей локали
|
||||
* %A - полное название дня недели, в зависимости от текущей локали
|
||||
* %b - сокращенное название месяца, в зависимости от текущей локали
|
||||
* %B - полное название месяца, в зависимости от текущей локали
|
||||
* %c - формат даты и времени по умолчанию для текущей локали
|
||||
* %C - номер века (год, деленный на 100, представленный в виде целого в промежутке от 00 до 99)
|
||||
* %d - день месяца в десятичном формате (от 01 до 31)
|
||||
* %D - синоним %m/%d/%y
|
||||
* %e - день месяца в десятичном формате без ведущего нуля (от 1 до 31)
|
||||
* %g - Week-based year within century [00,99]
|
||||
* %G - Week-based year, including the century [0000,9999]
|
||||
* %h - синоним %b
|
||||
* %H - часы по 24-часовым часам (от 00 до 23)
|
||||
* %I - часы по 12-часовым часам (от 01 до 12)
|
||||
* %j - день года (от 001 до 366)
|
||||
* %k - часы по 24-часовым часам без ведущего нуля (от 0 до 23)
|
||||
* %l - часы по 12-часовым часам без ведущего нуля (от 1 до 12)
|
||||
* %m - номер месяца (от 01 до 12)
|
||||
* %M - минуты
|
||||
* %n - символ новой строки
|
||||
* %p - `am' или `pm', в зависимости от заданного формата времени и текущей локали.
|
||||
* %r - time in a.m. and p.m. notation
|
||||
* %R - time in 24 hour notation
|
||||
* %S - секунды
|
||||
* %t - символ табуляции
|
||||
* %T - время в формате %H:%M:%S
|
||||
* %u - номер дня недели [1,7], где 1-ый день - понедельник
|
||||
* %U - номер недели в году, считая первое воскресенья года первым днем первой недели
|
||||
* %V - номер недели в году (по ISO 8601:1988) в диапазоне от 01 до 53, где первая неделя та, у которой хотя бы 4 дня находятся в данном году. Понедельник считается первым днем недели.
|
||||
* %w - номер дня недели, где 0 - воскресенье
|
||||
* %W - номер недели в году, считаю первый понедельник первым днем первой недели.
|
||||
* %x - предпочтительное представление даты для текущих настроек locale без времени
|
||||
* %X - предпочтительное представление времени для текущих настроек locale без даты
|
||||
* %y - год в виде десятичного числа без века (от 00 до 99)
|
||||
* %Y - год в виде десятичного числа включая век
|
||||
* %Z - часовой пояс или имя или сокращение
|
||||
* %% - буквальный символ `%'
|
|
@ -0,0 +1,18 @@
|
|||
Модификатор ematch
|
||||
==============
|
||||
|
||||
Выполняет проверку на соответствие регулярному выражению.
|
||||
[Подробнее](http://www.php.net/manual/ru/reference.pcre.pattern.syntax.php) о регулярных выражениях.
|
||||
|
||||
|
||||
```
|
||||
{$string|ematch:$pattern}
|
||||
```
|
||||
|
||||
Ищет в заданном тексте `$subject` совпадения с шаблоном `$pattern`.
|
||||
|
||||
```smarty
|
||||
{if $color|ematch:'/^(.*?)gr[ae]y$/i'}
|
||||
какой-то оттенок серого ...
|
||||
{/if}
|
||||
```
|
|
@ -0,0 +1,25 @@
|
|||
Модификатор ereplace
|
||||
=================
|
||||
|
||||
Выполняет поиск и замену по регулярному выражению.
|
||||
[Подробнее](http://www.php.net/manual/ru/reference.pcre.pattern.syntax.php) о регулярных выражениях.
|
||||
|
||||
```
|
||||
{$string|ereplace:$pattern:$replacement}
|
||||
```
|
||||
|
||||
Выполняет поиск совпадений в строке `$subject` с шаблоном pattern и заменяет их на replacement.
|
||||
|
||||
`$replacement` может содержать ссылки вида `\n`, `$n` или `${n}`, причем последний вариант предпочтительней.
|
||||
Каждая такая ссылка будет заменена на подстроку, соответствующую n-ой подмаске. n может принимать значения от 0 до 99,
|
||||
причем ссылка `\0` (либо $0) соответствует вхождению всего шаблона.
|
||||
Подмаски нумеруются слева направо, начиная с единицы. Для использования обратного слэша, его необходимо продублировать.
|
||||
|
||||
|
||||
```smarty
|
||||
{var $string = 'April 15, 2014'}
|
||||
|
||||
{$string|ereplace:'/(\w+) (\d+), (\d+)/i':'${1}1, $3'} {* April1, 2014 *}
|
||||
```
|
||||
|
||||
**Замечание:** воизбежание скрытых ошибок при выполнении сущностей регулярные выражения стоит помещать в одинарные кавычки.
|
|
@ -0,0 +1,19 @@
|
|||
Модификатор escape
|
||||
===============
|
||||
|
||||
Используется для кодирования или экранирования спецсимволов по алгоритмам экранирования HTML, URL'ов и javascript.
|
||||
По умолчанию активирован режим экранирования HTML.
|
||||
|
||||
```smarty
|
||||
{$text|escape:$type = 'html':$charset = 'UTF8'}
|
||||
```
|
||||
|
||||
Модификатор поддерживает несколько режимов работы
|
||||
|
||||
* `html`: экранирует HTML сущности в строке.
|
||||
* `url`: экранирует строку для использования в URL.
|
||||
* `js`: экранирует строку для использования в JavaScript.
|
||||
|
||||
Модификатор `e` является псевданимом модификатора от `escape`.
|
||||
|
||||
Параметр `$charset` указывает кодировку для режима `html`.
|
|
@ -0,0 +1,19 @@
|
|||
Модификатор esplit
|
||||
===============
|
||||
|
||||
Разбивает строку по регулярному выражению.
|
||||
[Подробнее](http://www.php.net/manual/ru/reference.pcre.pattern.syntax.php) о регулярных выражениях.
|
||||
|
||||
```
|
||||
{$string|esplit:$pattern = '/,\s*/'}
|
||||
```
|
||||
|
||||
По умолчанию модификатор разбивает строку по запятой с возможнымиы проблеами
|
||||
|
||||
```smarty
|
||||
{var $fruits1 = "banana, apple, pear"|esplit}
|
||||
$fruits1 — массив ["banana", "apple", "pear"]
|
||||
|
||||
{var $fruits2 = "banana; apple; pear"|esplit:'/;\s/'} is ["banana", "apple", "pear"]
|
||||
$fruits2 — массив ["banana", "apple", "pear"]
|
||||
```
|
|
@ -0,0 +1,12 @@
|
|||
Модификатор in
|
||||
===========
|
||||
|
||||
|
||||
|
||||
Модификатор является реализацией оператора содержания [in](../operators.md#Оператор-содержания).
|
||||
|
||||
```smarty
|
||||
{if $number|in:[1, 3, 42]}
|
||||
...
|
||||
{/if}
|
||||
```
|
|
@ -0,0 +1,16 @@
|
|||
Модификатор split
|
||||
==============
|
||||
|
||||
Объединяет элементы массива в строку.
|
||||
|
||||
```
|
||||
{$array|join:$delimiter = ","}
|
||||
```
|
||||
|
||||
Объединяет элементы массива с помощью строки `$delimiter`.
|
||||
|
||||
```smarty
|
||||
{var $fruits1 = ["banana", "apple", "pear"]}
|
||||
{$fruits1|join} выведет banana, apple, pear
|
||||
{$fruits1|join:" is not "} выведет banana is not apple is not pear
|
||||
```
|
|
@ -0,0 +1,10 @@
|
|||
Модификатор length
|
||||
===============
|
||||
|
||||
Модификатор возвращает количество элементов массива, итератора или символов в строке (работает с UTF8).
|
||||
|
||||
```smarty
|
||||
{if $images|length > 5}
|
||||
to many images
|
||||
{/if}
|
||||
```
|
|
@ -0,0 +1,13 @@
|
|||
Модификатор lower
|
||||
==============
|
||||
|
||||
Переводит строку в нижний регистр. Является эквивалентом функции PHP [strtolower()](http://docs.php.net/ru/lower).
|
||||
Имеет псевданим `low`.
|
||||
|
||||
```smarty
|
||||
{set $name = "Bzick"}
|
||||
|
||||
{$name} выведет Bzick
|
||||
{$name|lower} выведет bzick
|
||||
{$name|low} выведет bzick
|
||||
```
|
|
@ -0,0 +1,29 @@
|
|||
Модификатор match
|
||||
=================
|
||||
|
||||
Проверяет совпадение строки с паттерном.
|
||||
Среднестатистический пользователь знаком с подстановками оболочки, как минимум с самыми простыми из них - `?` и `*`,
|
||||
так что использование `match` вместо `ematch` для поиска в пользовательской части сайта может быть намного удобнее для пользователей,
|
||||
не являющихся программистами.
|
||||
|
||||
|
||||
```
|
||||
{$string|match:$pattern}
|
||||
```
|
||||
|
||||
Специальные символы:
|
||||
|
||||
* `?` — соответствие одному или нулю любых символов. `?at` соответствует `Cat`, `cat`, `Bat` или `bat`.
|
||||
* `*` — соответствие любому количеству символов. `Law*` соответствует `Law`, `Laws`, или `Lawyer`.
|
||||
* `[characters]` — соответствие символа группе символов. `[CB]at` соответствует `Cat` или `Bat`, но не `cat`, `rat` или `bat`.
|
||||
* `\` - экрнирующийсимвол. `Law\*` будет соответвовать только `Law*`
|
||||
|
||||
|
||||
```smarty
|
||||
{if $color|match:"*gr[ae]y"}
|
||||
какой-то оттенок серого
|
||||
{/if}
|
||||
```
|
||||
|
||||
**Замечание:**
|
||||
максимальная длинна проверяемой строки не должна превышать 4096 символов.
|
|
@ -0,0 +1,14 @@
|
|||
Модификатор replace
|
||||
================
|
||||
|
||||
Заменяет все вхождения строки поиска на строку замены
|
||||
|
||||
```
|
||||
{$string|replace:$search:$replace}
|
||||
```
|
||||
|
||||
Этот модификатор возвращает строку, в котором все вхождения `$search` в `$subject` заменены на `$replace`.
|
||||
|
||||
```smarty
|
||||
{$fruits|replace:"pear":"orange"}
|
||||
```
|
|
@ -0,0 +1,18 @@
|
|||
Модификатор split
|
||||
==============
|
||||
|
||||
Разбивает строку с помощью разделителя
|
||||
|
||||
```
|
||||
{$string|split:$delimiter = ","}
|
||||
```
|
||||
|
||||
Возвращает массив строк, полученных разбиением строки с использованием `$delimiter` в качестве разделителя.
|
||||
|
||||
```smarty
|
||||
{var $fruits1 = "banana,apple,pear"|split}
|
||||
$fruits1 is array ["banana", "apple", "pear"]
|
||||
|
||||
{var $fruits2 = "banana,apple,pear"|split:',apple,'}
|
||||
$fruits2 is array ["banana", "pear"]
|
||||
```
|
|
@ -0,0 +1,27 @@
|
|||
Модификатор strip
|
||||
==============
|
||||
|
||||
Заменяет все повторяющиеся пробелы, переводы строк и символы табуляции одним пробелом.
|
||||
|
||||
This replaces all repeated spaces and tabs with a single space, or with the supplied string.
|
||||
|
||||
```smarty
|
||||
{" one two "|strip}
|
||||
```
|
||||
Результат обработки
|
||||
```
|
||||
one two
|
||||
```
|
||||
|
||||
Опционально указывается флаг мультистрочности: `true` - тку же срезать переносы строк, `false` - срезать все кроме переносов строк.
|
||||
|
||||
```smarty
|
||||
{" multi
|
||||
line
|
||||
text "|strip:true}
|
||||
```
|
||||
|
||||
Результат обработки
|
||||
```
|
||||
multi line text
|
||||
```
|
|
@ -0,0 +1,23 @@
|
|||
Модификатор truncate
|
||||
=================
|
||||
|
||||
Обрезает переменную до определенной длинны, по умолчанию - 80 символов.
|
||||
В качестве необязательного второго параметра, вы можете передать строку текста, которая будет отображатся в конце обрезанной переменной. Символы этой строки не включаются в общую длинну обрезаемой строки. По умолчанию, truncate попытается обрезать строку в промежутке между словами. Если вы хотите обрезать строку строго на указаной длинне, передайте в третий необязательный параметр значение true.
|
||||
|
||||
```smarty
|
||||
{$long_string|truncate:$length:$etc:$by_words:$middle}
|
||||
```
|
||||
|
||||
* `$length`, обязателен. Определяет максимальную длинну обрезаемой строки.
|
||||
* `$etc`, по умолчанию `...`. Текстовая строка, которая заменяет обрезанный текст. Её длинна НЕ включена в максимальную длинну обрезаемой строки.
|
||||
* `$by_word`, по умолчанию **FALSE**. Определяет, обрезать ли строку в промежутке между словами (true) или строго на указаной длинне (false).
|
||||
* `$middle`, по умолчанию **FALSE**. Определяет, нужно ли обрезать строку в конце (false) или в середине строки (true).
|
||||
|
||||
```smarty
|
||||
{var $str = "very very long string"}
|
||||
|
||||
{$str|truncate:10:" read more..."} output: very very read more...
|
||||
{$str|truncate:5:" ... ":true:true} output: very ... string
|
||||
```
|
||||
|
||||
Модификатор работает с unicode без дополнительных расширений.
|
|
@ -0,0 +1,9 @@
|
|||
Модификатор unescape
|
||||
=================
|
||||
|
||||
Модификато `unescape` является обратным действием модификатора `escape`. Так же имеет режимы `html`, `js` and `URI`.
|
||||
|
||||
```smarty
|
||||
{$text|unescape:$type = 'html'}
|
||||
```
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
Модификатор upper
|
||||
==============
|
||||
|
||||
Переводит строку в верхний регистр. Является эквивалентом функции PHP [strtoupper()](http://docs.php.net/ru/strtoupper).
|
||||
Имеет псевдоним `up`.
|
||||
|
||||
```smarty
|
||||
{var $name = "Bzick"}
|
||||
|
||||
{$name} выводит Bzick
|
||||
{$name|upper} выводит BZICK
|
||||
{$name|up} выводит BZICK
|
||||
```
|
|
@ -0,0 +1,309 @@
|
|||
Операторы
|
||||
=========
|
||||
|
||||
### Арифметические операторы
|
||||
|
||||
Все же помнят арифметику?
|
||||
|
||||
* `-$a` - отрицание знака, смена знака `$a`.
|
||||
* `$a + $b` - сложение, сумма `$a` и `$b`.
|
||||
* `$a - $b` - вычитание, разность `$a` и `$b`.
|
||||
* `$a * $b` - умножение, произведение `$a` и `$b`.
|
||||
* `$a / $b` - деление, частное от деления `$a` на `$b`.
|
||||
* `$a % $b` - деление по модулю, целочисленный остаток от деления `$a` на `$b`.
|
||||
|
||||
```smarty
|
||||
{$a + $b * $c/$d - $e*5 + 1e3}
|
||||
```
|
||||
|
||||
### Логические операторы
|
||||
|
||||
* `$a || $b` - логичесое ИЛИ, TRUE если или `$a`, или `$b` TRUE.
|
||||
* `$a && $b` - лигическое И, TRUE если и `$a`, и `$b` TRUE.
|
||||
* `!$a` - отрицание, TRUE если `$a` не TRUE.
|
||||
* `$a or $b` - логическое ИЛИ, TRUE если или `$a`, или `$b` TRUE.
|
||||
* `$a and $b` - логическое И, TRUE если и `$a`, и `$b` TRUE.
|
||||
* `$a xor $b` - исключающее или, TRUE если `$a`, или `$b` TRUE, но не оба.
|
||||
|
||||
```smarty
|
||||
{if $b && $c} ... {/if}
|
||||
```
|
||||
|
||||
Смысл двух разных вариантов для операторов `and` и `or` в том, что они работают с различными приоритетами.
|
||||
|
||||
### Операторы сравнения
|
||||
|
||||
Операторы сравнения, как это видно из их названия, позволяют сравнивать между собой два значения.
|
||||
|
||||
* `$a < $b` - меньше, TRUE если `$a` строго меньше `$b`.
|
||||
* `$a > $b` - больше, TRUE если `$a` строго больше `$b`.
|
||||
* `$a <= $b` - меньше или равно, TRUE если `$a` меньше или равно `$b`.
|
||||
* `$a >= $b` - больше или равно, TRUE если `$a` больше или равно `$b`.
|
||||
* `$a == $b` - равно, TRUE если `$a` равно `$b` после преобразования типов.
|
||||
* `$a === $b` - тождественно равно, TRUE если `$a` равно `$b` и имеет тот же тип.
|
||||
* `$a !== $b` - тождественно не равно, TRUE если `$a` не равно `$b` или они разных типов.
|
||||
* `$a != $b` - не равно, TRUE если `$a` не равно `$b` после преобразования типов.
|
||||
* `$a <> $b` - не равно, TRUE если `$a` не равно `$b` после преобразования типов.
|
||||
|
||||
```smarty
|
||||
{if $b >= 5} ... {/if}
|
||||
```
|
||||
|
||||
В случае, если вы сравниваете число со строкой или две строки, содержащие числа, каждая строка будет преобразована в число, и сравниваться они будут как числа.
|
||||
|
||||
```smarty
|
||||
{if 0 == "a"} {* 0 == 0 -> true *} {/if}
|
||||
{if "1" == "01"} {* 1 == 1 -> true *} {/if}
|
||||
{if "10" == "1e1"} {* 10 == 10 -> true *} {/if}
|
||||
{if 100 == "1e2"} {* 100 == 100 -> true *} {/if}
|
||||
```
|
||||
|
||||
Преобразование типов не происходит при использовании `===` или `!==` так как в этом случае кроме самих значений сравниваются еще и типы.
|
||||
|
||||
**Таблица сравнения различных типов:**
|
||||
|
||||
| Тип операнда 1 | Тип операнда 2 | Результат |
|
||||
|-------------------|-------------------|-----------|
|
||||
| null или строка | строка | NULL преобразуется в "", числовое или лексическое сравнение |
|
||||
| булев или null | что угодно | Преобразуется в bool, FALSE < TRUE |
|
||||
| объект | объект | Встроенные классы могут определять свои собственные правила сравнения, объекты разных классов не сравниваются, объекты одного класса - сравниваются свойства тем же способом, что и в массивах |
|
||||
| строка или число | строка или число | Строки переводятся в числа, обычная математика |
|
||||
| массив | массив | Массивы с меньшим числом элементов считаются меньше, если ключ из первого операнда не найден во втором операнде - массивы не могут сравниваться, иначе идет сравнение соответствующих значений |
|
||||
| объект | что угодно | object всегда больше |
|
||||
| массим | что угодно | array всегда больше |
|
||||
|
||||
|
||||
### Побитовые операторы
|
||||
|
||||
Побитовые операторы позволяют считывать и устанавливать конкретные биты целых чисел.
|
||||
|
||||
* `$a | $b` - битовое ИЛИ, устанавливаются те биты, которые установлены в `$a` или в `$b`.
|
||||
* `$a & $b` - битовое И, устанавливаются только те биты, которые установлены и в `$a`, и в `$b`.
|
||||
* `$a ^ $b` - битовое исключающее ИЛИ, устанавливаются только те биты, которые установлены либо только в `$a`, либо только в `$b`, но не в обоих одновременно.
|
||||
* `~$a` - битовое отрицание, устанавливаются те биты, которые не установлены в `$a`, и наоборот.
|
||||
* `$a << $b` - битовый сдвиг влево, все биты переменной `$a` сдвигаются на `$b` позиций влево (каждая позиция подразумевает "умножение на 2")
|
||||
* `$a >> $b` - битовый сдвиг вправо, все биты переменной `$a` сдвигаются на `$b` позиций вправо (каждая позиция подразумевает "деление на 2")
|
||||
|
||||
```smarty
|
||||
{if $a & 1} {var $b = 4 | $flags} {/if}
|
||||
```
|
||||
|
||||
### Оператор присваивания
|
||||
|
||||
Базовый оператор присваивания обозначается как `=`. На первый взгляд может показаться, что это оператор "равно".
|
||||
На самом деле это не так. В действительности, оператор присваивания означает, что левый операнд получает значение правого выражения,
|
||||
(т.е. устанавливается значением).
|
||||
|
||||
В дополнение к базовому оператору присваивания имеются "комбинированные операторы" для всех бинарных арифметических операций и строковых операций,
|
||||
которые позволяют использовать некоторое значение в выражении, а затем установить его как результат данного выражения.
|
||||
То есть выражение `$a = $a + 2` может быть записано как `$a += 2`.
|
||||
|
||||
* `$a = $b` - присвоение
|
||||
* `$a += $b` - присвоение с добалением.
|
||||
* `$a -= $b` - присвоение с вычитанием.
|
||||
* `$a *= $b` - присвоение с умножением.
|
||||
* `$a /= $b` - присвоение с делением.
|
||||
* `$a %= $b` - присвоение с делением по модулю.
|
||||
* `$a &= $b` - присвоение с битовыйм И.
|
||||
* `$a |= $b` - присвоение с битовыйм ИЛИ.
|
||||
* `$a ^= $b` - присвоение с битовыйм исключением ИЛИ
|
||||
* `$a <<= $b` - присвоение с битовым сдвигом влево.
|
||||
* `$a >>= $b` - присвоение с битовым сдвигом врпаво.
|
||||
|
||||
|
||||
```smarty
|
||||
{set $b |= $flags}
|
||||
```
|
||||
|
||||
### Операторы инкремента и декремента
|
||||
|
||||
Fenom поддерживает префиксные и постфиксные операторы инкремента и декремента в стиле PHP или C.
|
||||
|
||||
**Замечание:**
|
||||
Операторы инкремента/декремента не влияют на булевы значения. Декремент NULL также не даст никакого эффекта, однако инкремент даст значение 1.
|
||||
|
||||
* `++$a` - префиксный инкремент, увеличивает $a на единицу, затем возвращает значение $a.
|
||||
* `$a++` - постфиксный инкремент, возвращает значение $a, затем увеличивает $a на единицу.
|
||||
* `--$a` - префиксный декремент, уменьшает $a на единицу, затем возвращает значение $a.
|
||||
* `$a--` - постфиксный декремент, возвращает значение $a, затем уменьшает $a на единицу.
|
||||
|
||||
### Строковые операторы
|
||||
|
||||
Оператор объединения `~` возвращает строку, представляющую собой соединение левого и правого аргумента.
|
||||
|
||||
* `$a ~ $b` - возвращает результат объединения сток `$a` и `$b`
|
||||
* `$a ~~ $b` - возвращает результат объединения сток `$a` и `$b` через пробел
|
||||
* `$a ~= $b` - присвоение с объединением
|
||||
|
||||
Примеры
|
||||
|
||||
```smarty
|
||||
{"A" ~ "B"} -> AB
|
||||
|
||||
{"A" ~~ "B"} -> A B
|
||||
|
||||
{add $v = "A"}
|
||||
{set $v ~= "B"}
|
||||
{$v} -> AB
|
||||
```
|
||||
|
||||
### Оператор интервала
|
||||
|
||||
Оператор `..` позволяет создать массив данных, не выходящих за указанные пределы.
|
||||
|
||||
```smarty
|
||||
{set $a = 1..4}
|
||||
```
|
||||
|
||||
создаст массив `[1,2,3,4]`
|
||||
|
||||
```smarty
|
||||
{set $a = 'a'..'f'}
|
||||
```
|
||||
|
||||
создаст массив `['a','b','c','d','e','f']`
|
||||
|
||||
```smarty
|
||||
{set $a = 'a'|up..'f'|up}
|
||||
```
|
||||
|
||||
создаст массив `['A','B','C','D','E','F']`
|
||||
|
||||
```smarty
|
||||
{set $a = $min..$max}
|
||||
```
|
||||
|
||||
создаст массив из значений где первый (минимальный) элемент будет иметь значение `$min`,
|
||||
а максимальный (последний) элемент будет иметь значение `$max`
|
||||
|
||||
**Замечание:**
|
||||
ограничения должны быть одного типа, интервал `1..'f'` преобразует `f` в `0` и будет сгенерировано `[1,0]`
|
||||
|
||||
|
||||
### Тернарные операторы
|
||||
|
||||
Еще одним условным оператором являются тернарные операторы `?:` и `!:`.
|
||||
Выражения `(expr1) ? (expr2) : (expr3)` и `(expr1) ! (expr2) : (expr3)` интерпретируется как `expr2`, если `expr1` имеет значение TRUE, или как `expr3` если `expr1` имеет значение FALSE.
|
||||
|
||||
Тернарый оператор `?:` проверяет условие `expr1` на не "пустое" значение, то есть `expr1` при конвертирование в булевое значение должен вернуть TRUE.
|
||||
Следующие значения воспринимаются как пустые:
|
||||
|
||||
* "" (пустая строка)
|
||||
* 0 (целое число)
|
||||
* 0.0 (дробное число)
|
||||
* "0" (строка)
|
||||
* NULL
|
||||
* FALSE
|
||||
* array() (пустой массив)
|
||||
* переменная не объявлена
|
||||
* элемента массива не существует
|
||||
* свойство объекта не существует
|
||||
|
||||
```smarty
|
||||
{$request.action ? $request.action : 'default'}
|
||||
```
|
||||
|
||||
Пример выше стоит интерпретировать так: если `$request.action` не пустое то вернуть `$request.action` иначе вернуть `default`.
|
||||
Приведенный пример можно записать в упрощенном формате:
|
||||
```smarty
|
||||
{$request.action ?: 'default'}
|
||||
```
|
||||
|
||||
Тернарый оператор `?:` проверяет условие `expr1` на существование и относится больше к работе с переменными,
|
||||
то есть переменная в выражении `expr1` должна существовать даже если она "пустая", но не NULL.
|
||||
Данный оператор не имеет значения если `expr1` функция или метод, так как в этом случае всегда будет TRUE.
|
||||
|
||||
```smarty
|
||||
{$request.action ! $request.action : 'default'}
|
||||
```
|
||||
Пример выше стоит интерпретировать так: если переменна я `$request` существует, является массивом и существует ключ `$request.action` то вернуть `$request.action` иначе вернуть `default`.
|
||||
Приведенный пример можно записать в упрощенном формате:
|
||||
```smarty
|
||||
{$request.action !: 'default'}
|
||||
```
|
||||
|
||||
Как видно, оператор `:?` более расширенный чем `:!` и включает в себя функциональность оператора `!:`.
|
||||
|
||||
Для упрощения понимания можно подвести итог:
|
||||
|
||||
* `$a ? $b : $c` - вернет `$b` если `$a` не пустое, иначе вернет `$c`.
|
||||
* `$a ! $b : $c` - вернет `$b` если `$a` существует, иначе вернет `$c`.
|
||||
* `$a ?: $b` - вернет `$a` если `$a` не пустое, иначе вернет `$b`.
|
||||
* `$a !: $b` - вернет `$a` если `$a` существует, иначе вернет `$b`.
|
||||
|
||||
```smarty
|
||||
{var $a = true}
|
||||
{$a ? 5 : 10} {* вернет 5 *}
|
||||
{var $a = false}
|
||||
{$a ? 5 : 10} {* вернет 10 *}
|
||||
```
|
||||
|
||||
### Операторы проверки
|
||||
|
||||
Оператор проверки это упрощенный тернарный оператор от которого осталась только часть проверки без возвращаемых вариантов.
|
||||
Суть операторов — быстро произвести проверку на не пустое значение и существование пременной.
|
||||
|
||||
* `$a?` - вернет `TRUE` если `$a` не пустое
|
||||
* `$a!` - вернет `TRUE` если `$a` существует
|
||||
|
||||
```smarty
|
||||
{if $a?} {* вместо {if !empty($a)} *}
|
||||
{if $a!} {* вместо {if isset($a)} *}
|
||||
```
|
||||
|
||||
### Оператор тестирования
|
||||
|
||||
Оператор `is` производит тесты над переменными или выражением. Левый операнд считается тестируемым, а правый операнд — название теста:
|
||||
|
||||
```smarty
|
||||
{* проверка переменной на не четность *}
|
||||
|
||||
{$a is odd}
|
||||
```
|
||||
|
||||
Результат тестирования может быть инвертирован с помощью `is not` оператора:
|
||||
|
||||
```smarty
|
||||
{* проверяем переменную что ее значение не является числом *}
|
||||
|
||||
{$a is not integer}
|
||||
```
|
||||
|
||||
Список допустимых тестов:
|
||||
|
||||
* `$a is integer` - тестирует перменную на тип. Тестом может быть
|
||||
* `int`, `integer` — целое число
|
||||
* `bool`, `boolean` — булево значение
|
||||
* `float`, `double`, `decimal` - дробное число
|
||||
* `array` — массив
|
||||
* `object` — объект
|
||||
* `scalar` — скалярное значение (не массив и не объект)
|
||||
* `string` — строка
|
||||
* `callback`, `callable` — функция
|
||||
* `number`, `numeric` — число, в общем понимании
|
||||
* `$a is iterable` - тестирует переменную на возможность итеративного обхода (для `foreach`).
|
||||
* `$a is template` - переменная `$a` содержит название существующего шаблона.
|
||||
* `$a is empty` - переменная пустая.
|
||||
* `$a is set` - переменная существует.
|
||||
* `$a is even` - переменная `$a` имеет четное значение.
|
||||
* `$a is odd` - переменная `$a` имеет не четное значение.
|
||||
* `$a is MyClass` или `$a is \MyClass` - переменная `$a` является сущностью класса `MyClass`
|
||||
* `$a is $b` - `$a` тождественна `$b`
|
||||
|
||||
### Оператор присутствия
|
||||
|
||||
Оператор `in` проверяет присутствие скалярного значения слева в массиве или строке справа.
|
||||
Результат тестирования может быть инвертирован с помощью `not ni` оператора.
|
||||
|
||||
* `$a in list $b` - значение `$a` содержится в массиве значений `$b`
|
||||
* `$a in keys $b` - массив `$b` имеет ключ `$a`
|
||||
* `$a in string $b` - значение `$a` содержится в `$b` как подстрока.
|
||||
* `$a in $b` - значение `$a` содержится в `$b`, где `$b` может быть строкой, обычным или ассоциативным массивом.
|
||||
Этот вариант долгий так как требуется проверить типы переменной `$b`.
|
||||
Однако если вместо $b явно задан массив или строка то оператор сам адаптируется для быстрого поиска.
|
||||
|
||||
```smarty
|
||||
{'df' in 'abcdefg'}
|
||||
{5 in [1, 5, 25, 125]}
|
||||
{99 in keys [1, 5, 25, 99 => 125]}
|
||||
```
|
|
@ -0,0 +1,103 @@
|
|||
Документация
|
||||
=============
|
||||
|
||||
<!--img style="float:right" src="https://ficbook.net/images/user_avatars/avatar_%D0%93%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%80-%D0%9D%D0%B0%D1%86%D0%B8_1382414316.jpg" alt="grammar nazi required"-->
|
||||
|
||||
**Внимание! Документация в режиме беты, тексты могут содержать опечатки**
|
||||
|
||||
### Fenom
|
||||
|
||||
* [Быстрый старт](./start.md)
|
||||
* [Адаптеры для фрейморков](./adapters.md)
|
||||
* [Разработка Fenom](./dev/readme.md)
|
||||
* [Настройки](./configuration.md)
|
||||
* [Синтаксис](./syntax.md)
|
||||
* [Переменные](./syntax.md#Переменные)
|
||||
* [Значения](./syntax.md#Скалярные-значения)
|
||||
* [Массивы](./syntax.md#Массивы)
|
||||
* [Операторы](./operators.md)
|
||||
* [Модификаторы](./syntax.md#Модификаторы)
|
||||
* [Теги](./syntax.md#Теги)
|
||||
* [Параметры тегов](./syntax.md#Параметры-тегов)
|
||||
|
||||
***
|
||||
|
||||
### Теги
|
||||
|
||||
[Использование](./syntax.md#Теги) тегов.
|
||||
|
||||
* [set](./tags/set.md), [add](./tags/set.md#add) и [var](./tags/set.md#var) — определение значения переменной
|
||||
* [if](./tags/if.md), [elseif](./tags/if.md#elseif) и [else](./tags/if.md#else) — условный оператор
|
||||
* [foreach](./tags/foreach.md), [foreachelse](./tags/foreach.md#foreachelse),
|
||||
[break](./tags/foreach.md#break) и [continue](./tags/foreach.md#continue) — перебор элементов массива или объекта
|
||||
* [switch](./tags/switch.md) и [case](./tags/switch.md#case) — групповой условный оператор
|
||||
* [cycle](./tags/cycle.md) — циклицеский перебор массива значений
|
||||
* [include](./tags/include.md), [insert](./tags/include.md#insert) — вставляет и исполняет указанный шаблон
|
||||
* [extends](./tags/extends.md), [use](./tags/extends.md#use),
|
||||
[block](./tags/extends.md#block), [parent](./tags/extends.md#parent) и
|
||||
[paste](./tags/extends.md#paste) — [наследование](./inheritance.md) шаблонов
|
||||
* [filter](./tags/filter.md) — применение модификаторов к фрагменту шаблона
|
||||
* [ignore](./tags/ignore.md) — игнорирование тегов Fenom
|
||||
* [macro](./tags/macro.md) и [import](./tags/macro.md#macro) — пользовательские функции шаблонов
|
||||
* [autoescape](./tags/autoescape.md) — экранирует фрагмент шаблона
|
||||
* [raw](./tags/raw.md) — отключает экранирование фрагмента шаблона
|
||||
* [unset](./tags/unset.md) — удаляет переменные
|
||||
* или [добавьте](./ext/extend.md#Добавление-тегов) свои
|
||||
|
||||
Устаревшие теги
|
||||
|
||||
* [for](./tags/for.md), `forelse`, `break` and `continue` — цикл
|
||||
|
||||
***
|
||||
|
||||
### Модификаторы
|
||||
|
||||
[Использование](./syntax.md#modifiers) модификаторов.
|
||||
|
||||
* [upper](./mods/upper.md) aka `up` — конвертирование строки в верхний регистр
|
||||
* [lower](./mods/lower.md) aka `low` — конвертирование строки в нижний регистр
|
||||
* [date_format](./mods/date_format.md) - форматирует дату, штамп времени через strftime() функцию
|
||||
* [date](./mods/date.md) - форматирует дату, штамп времени через date() функцию
|
||||
* [truncate](./mods/truncate.md) — обрезает текст до указанной длины
|
||||
* [escape](./mods/escape.md) aka `e` — экранирует строку
|
||||
* [unescape](./mods/unescape.md) — убирает экранирование строки
|
||||
* [strip](./mods/strip.md) — удаляет лишние пробелы
|
||||
* [length](./mods/length.md) — подсчитывает длину строки, массива, объекта
|
||||
* [in](./mods/in.md) — проверяет наличие значения в массиве
|
||||
* [match](./mods/match.md) — проверяет соответствие паттерну
|
||||
* [ematch](./mods/ematch.md) — проверяет соответствие регулярному выражению
|
||||
* [replace](./mods/replace.md) — заменяет все вхождения подстроки на строку замену
|
||||
* [ereplace](./mods/ereplace.md) — заменяет все соответсвия регулярному выражению на строку замену.
|
||||
* [split](./mods/split.md) — разбивает строку по подстроке
|
||||
* [esplit](./mods/esplit.md) — разбивает строку по регулярному выражению
|
||||
* [join](./mods/join.md) — объединяет массив в строку
|
||||
* так же разрешены функции: `json_encode`, `json_decode`, `count`, `is_string`, `is_array`, `is_numeric`, `is_int`, `is_object`,
|
||||
`strtotime`, `gettype`, `is_double`, `ip2long`, `long2ip`, `strip_tags`, `nl2br`
|
||||
* или [добавьте](./ext/extend.md#Добавление-модификаторов) свои
|
||||
|
||||
***
|
||||
|
||||
### Операторы
|
||||
|
||||
* [Арифметические операторы](./operators.md#Арифметические-операторы) — `+`, `-`, `*`, `/`, `%`
|
||||
* [Логические операторы](./operators.md#Логические-операторы) — `||`, `&&`, `!$var`, `and`, `or`, `xor`
|
||||
* [Операторы сравнения](./operators.md#Операторы-сравнения) — `>`, `>=`, `<`, `<=`, `==`, `!=`, `!==`, `<>`
|
||||
* [Битовые операторы](./operators.md#Битовые-операторы) — `|`, `&`, `^`, `~$var`, `>>`, `<<`
|
||||
* [Операторы присвоения](./operators.md#Операторы-присвоения) — `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `|=`, `^=`, `>>=`, `<<=`
|
||||
* [Строковые операторы](./operators.md#Строковые-операторы) — `$str1 ~ $str2`, `$str1 ~~ $str2`, `$str1 ~= $str2`
|
||||
* [Тернарные операторы](./operators.md#Тернарные-операторы) — `$a ? $b : $c`, `$a ! $b : $c`, `$a ?: $c`, `$a !: $c`
|
||||
* [Проверяющие операторы](./operators.md#Проверяющие-операторы) — `$var?`, `$var!`
|
||||
* [Оператор тестирования](./operators.md#Оператор-тестирования) — `is`, `is not`
|
||||
* [Оператор содержания](./operators.md#Оператор-содержания) — `in`, `not in`
|
||||
|
||||
***
|
||||
|
||||
### Расширение
|
||||
|
||||
* [Источники шаблонов](./ext/extend.md#Источники-шаблонов)
|
||||
* [Добавление модификаторов](./ext/extend.md#Добавление-модификаторов)
|
||||
* [Добавление тегов](./ext/extend.md#Добавление-тегов)
|
||||
* [Расширение тестового оператора](./ext/extend.md#Расширение-тестового-оператора)
|
||||
* [Расширение глобальной переменной](./ext/extend.md#Расширение-глобальной-переменной)
|
||||
* [Расширение Fenom](./ext/extend.md)
|
||||
* [Add-ons](./ext/extensions.md)
|
|
@ -0,0 +1,110 @@
|
|||
Быстрый старт
|
||||
=============
|
||||
|
||||
## Установка Fenom
|
||||
|
||||
### Composer
|
||||
|
||||
Fenom зарегистрирован на [packagist.org](https://packagist.org/) как пакет [fenom/fenom](https://packagist.org/packages/fenom/fenom).
|
||||
Что бы установить Fenom через composer пропишите в `composer.json` списке пакетов:
|
||||
```json
|
||||
{
|
||||
"require": {
|
||||
"fenom/fenom": "2.*"
|
||||
}
|
||||
}
|
||||
```
|
||||
и обновите зависимости: `composer update`.
|
||||
|
||||
### Произвольная подгрузка
|
||||
|
||||
Клонируйте Fenom в любую директорию Вашего проекта: `git clone https://github.com/bzick/fenom.git`. Рекомендуется использовать последнюю версию.
|
||||
Для загрузки классов Fenom использует [psr-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md#autoloading-standard) стандарт.
|
||||
Таким образом вы можете:
|
||||
* использовать Ваш автозагрузчик, который понимает `psr-0` формат для загрузки классов Fenom из директории `src/` с пространством имен `Fenom`.
|
||||
* или использовать встроенный автозагрузчик Fenom: `Fenom::registerAutoload();` для загрузки самого себя.
|
||||
|
||||
Так же вы можете использовать встроенный в Fenom автозагрузчик для загрузки других классов в `psr-0` формате:
|
||||
```php
|
||||
Fenom::registerAutoload(PROJECT_DIR."/classes");
|
||||
```
|
||||
|
||||
## Настройка Fenom
|
||||
|
||||
Есть два варианта инициировать объект шаблонизатора: через `new` оператор и фабрику.
|
||||
Пример создания Fenom через фабрику:
|
||||
```php
|
||||
$fenom = Fenom::factory('/path/to/templates', '/path/to/compiled/template', $options);
|
||||
```
|
||||
Пример создания Fenom через оператор `new`:
|
||||
```php
|
||||
$fenom = new Fenom(new Fenom\Provider('/path/to/templates'));
|
||||
$fenom->setCompileDir('/path/to/template/cache');
|
||||
$fenom->setOptions($options);
|
||||
```
|
||||
|
||||
* `/path/to/templates` — директория в которой хранятся шаблоны.
|
||||
* `/path/to/template/cache` — директория в которую Fenom будет сохранять PHP-кеш шаблонов
|
||||
* `$options` - битовая маска или массив [параметров](./configuration.md).
|
||||
|
||||
### Использование
|
||||
|
||||
Что бы отобразить шаблон на экран используйте метод `display`:
|
||||
|
||||
```php
|
||||
// $fenom->display(string $template, array $variables) : void
|
||||
|
||||
$fenom->display("template/name.tpl", $vars);
|
||||
```
|
||||
|
||||
Метод найдет шаблон `template/name.tpl` отрисует его в `stdout`, подставляя переменные из массива `$vars`.
|
||||
|
||||
Метод `fetch` возвращает вывод шаблона вместо его отображения на экран.
|
||||
```php
|
||||
// $fenom->fetch(string $template, array $variables) : string
|
||||
|
||||
$result = $fenom->fetch("template/name.tpl", $vars);
|
||||
```
|
||||
|
||||
Для вывода большого количества данных можно использовать поток
|
||||
|
||||
```php
|
||||
// $fenom->pipe(string $template, array $variables, callable $callback, int $chunk_size) : void
|
||||
|
||||
$fenom->pipe(
|
||||
"template/sitemap.tpl",
|
||||
$vars,
|
||||
$callback = [new SplFileObject("compress.zlib:///tmp/sitemap.xml.gz", "w"), "fwrite"], // поток с архивацией в файл /tmp/sitemap.xml.gz
|
||||
1e6 // размер куска данных в байтах
|
||||
);
|
||||
```
|
||||
|
||||
Поток позволяет обрабатывать большой результат по кускам, размер куска указывается в байтах аргументом `$chunk_size`.
|
||||
Каждый кусок передается в `$callback` для обработки или вывода.
|
||||
|
||||
<!--
|
||||
## Пример простого приложения
|
||||
|
||||
```
|
||||
App/ (ROOT_DIR)
|
||||
┠─ configs/ (файлы конфигурации приложения)
|
||||
┠─ src/ (классы приложения)
|
||||
┠─ templates/ (шаблоны приложения)
|
||||
┠─ public/ (DOCUMENT_ROOT)
|
||||
┃ ┠─ static/ (папка со статикой)
|
||||
┃ ┖─ index.php (скрипт обработки всех динамических запросов)
|
||||
┠─ tmp/ (папка доступная для записи web-серверу для хранения временных файлов)
|
||||
┃ ┖─ compiled/ (кеша шаблонов)
|
||||
┠─ vendor/ (строронние бибилиотеки)
|
||||
┖─ composer.json (описание зависимостей для composer)
|
||||
```
|
||||
|
||||
`index.php`:
|
||||
```php
|
||||
define('ROOT_DIR', dirname(__DIR__));
|
||||
|
||||
$fenom = Fenom::factory(ROOT_DIR.'/templates', ROOT_DIR.'/cache', Fenom::FORCE_VERIFY | Fenom::AUTO_RELOAD);
|
||||
|
||||
|
||||
```
|
||||
-->
|
|
@ -0,0 +1,451 @@
|
|||
Синтаксис
|
||||
=========
|
||||
|
||||
По синтаксису шаблона Fenom похож на [Smarty](http://www.smarty.net/), но обладает рядом улучшений.
|
||||
Все теги шаблонизатора заключаются в фигурные скобки: `{` — открытие тега и `}` — закрытие тега.
|
||||
|
||||
**Замечание**
|
||||
Хоть Fenom и позаимствовал синтаксис Smarty, но он не заимствовал теги Smarty как есть.
|
||||
Однако некоторые теги очень похожи. Но не все так плохо, Fenom имеет набор [дополнений](https://github.com/bzick/fenom-extra)
|
||||
которые могут сделать Fenom более похожим на Smarty, чтобы переход был мягче.
|
||||
|
||||
## Переменные
|
||||
|
||||
Переменные могут быть выведены на экран или могут быть использованы для функций, атрибутов, модификаторов внутри сложных выражений и т.д.
|
||||
Переменные в Fenom представлены знаком доллара с последующим именем переменной. Имя переменной чувствительно к регистру.
|
||||
Правильное имя переменной должно начинаться с буквы или символа подчеркивания и состоять из букв, цифр и символов подчеркивания в любом количестве.
|
||||
|
||||
### Использование переменных
|
||||
|
||||
Следующий пример использует простые переменные `$user_id` и `$user_name` для формирования приветственного сообщения.
|
||||
|
||||
```smarty
|
||||
<div class="user">Hello, <a href="/users/{$user_id}">{$user_name}</a>.</div>
|
||||
```
|
||||
|
||||
Пример выведет следующий HTML код:
|
||||
|
||||
```html
|
||||
<div class="user">Hello, <a href="/users/17">Bzick</a>.</div>
|
||||
```
|
||||
|
||||
Переменные могут быть массивом. В этом случае обращение по ключу происходит через оператор `.` или, как в PHP, через операторы `[` и `]`
|
||||
```smarty
|
||||
<div class="user">Hello, <a href="/users/{$user.id}">{$user.name}</a>.</div>
|
||||
```
|
||||
`{$user.id}` и `{$user['id']}` это одно и то же:
|
||||
```smarty
|
||||
<div class="user">Hello, <a href="/users/{$user['id']}">{$user['name']}</a>.</div>
|
||||
```
|
||||
|
||||
В случае объекта, доступ к его свойствам осущесвляется так как и в PHP — через оператор `->`:
|
||||
```smarty
|
||||
<div class="user">Hello, <a href="/users/{$user->id}">{$user->name}</a>.</div>
|
||||
```
|
||||
|
||||
Методы, как и свойства можно вызвать через оператор `->`, передав в метод любые рагументы:
|
||||
```smarty
|
||||
<div class="user">Hello, <a href="/users/{$user->getId()}">{$user->getName()}</a>.</div>
|
||||
```
|
||||
|
||||
**Note**
|
||||
Будте осторожны, Fenom не проверяет наличие метода в классе перед вызовом.
|
||||
Что бы избежать фатальной ошибки определите метод `__call` у класса объекта.
|
||||
Вызов методов в шаблоне можно вообще выключить в [настройках](./configuration.md).
|
||||
|
||||
Ниже приведены комбинированые примеры работы с переменными:
|
||||
|
||||
```smarty
|
||||
{$foo.bar.baz}
|
||||
{$foo.$bar.$baz}
|
||||
{$foo[5].baz}
|
||||
{$foo[5].$baz}
|
||||
{$foo.bar.baz[4]}
|
||||
{$foo[ $bar.baz ]}
|
||||
{$foo[5]}
|
||||
{$foo.5}
|
||||
{$foo.bar}
|
||||
{$foo.'bar'}
|
||||
{$foo."bar"}
|
||||
{$foo['bar']}
|
||||
{$foo["bar"]}
|
||||
{$foo.$bar}
|
||||
{$foo[$bar]}
|
||||
{$foo->bar}
|
||||
{$foo->bar.buz}
|
||||
{$foo->bar.buz[ $bar->getId("user") ]}
|
||||
{$foo->bar(5)->buz(5.5)}
|
||||
```
|
||||
|
||||
### Системная переменная
|
||||
|
||||
Безымянная системная переменная начинается с `$.` и предоставляет доступ к глобальным системным переменным и системной информации:
|
||||
|
||||
* `$.env` — массив `$_ENV`.
|
||||
* `$.get` — массив `$_GET`.
|
||||
* `$.post` — массив `$_POST`.
|
||||
* `$.files` — массив `$_FILES`.
|
||||
* `$.cookie` — массив `$_COOKIE`.
|
||||
* `$.server` — массив `$_SERVER`.
|
||||
* `$.session` — массив `$_SESSION`.
|
||||
* `$.globals` — массив `$GLOBALS`.
|
||||
* `$.request` — массив `$_REQUEST`.
|
||||
* `$.tpl.name` возвращает текущее название шаблона.
|
||||
* `$.tpl.basename` возвращает текущее название шаблона без схемы.
|
||||
* `$.tpl.scm` возвращает схему шаблона.
|
||||
* `$.tpl.options` возвращает параметры шбалона в виде целого числа.
|
||||
* `$.tpl.depends` возвращает массив шаблонов, на которые ссылается текущий шаблон.
|
||||
* `$.tpl.time` возвращает штамп времени, когда шаблон последний раз менялся
|
||||
* `$.version` возвращает версию Fenom.
|
||||
* `$.const` обращение к PHP константе: `$.const.PHP_EOL` обращение к константе `PHP_EOL`. Поддерживается пространство имен
|
||||
которое разделяется через точку: `$.const.Storage.FS::DIR_SEPARATOR` обращение к PHP константе `Storage\FS::DIR_SEPARATOR`
|
||||
если такой константы нет будет взята константа `Storage\FS\DIR_SEPARATOR`.
|
||||
* `$.call` обращение к статическому методу. `$.call.Storage.FS::put($filename, $data)` обращение к методу `Storage\FS::put($filename, $data)`.
|
||||
Настройка `disable_call` отключает возможность обращения к `$.call`. Так же можно ограничить и указать список доступных к вызову классов и функций.
|
||||
* `$.block` проверка на существование блоков которые были определены до момента обращения к акцессору. Например, `{$.blocks.BLOCK_NAME}`.
|
||||
* так же вы можете [добавить](./ext/extend.md#Расширение-глобальной-переменной) свои или [удалить](./ext/extend.md#Расширение-глобальной-переменной) существующие системные переменные и функции
|
||||
|
||||
|
||||
## Скалярные значения
|
||||
|
||||
### Строки
|
||||
|
||||
Строка может быть определена двумя различными способами: двойные кавычки (`"string"`) и одинарные кавычки (`'string'`).
|
||||
|
||||
#### Двойные кавычки
|
||||
|
||||
Если строка заключена в двойные кавычки `"`, Fenom распознает большее количество управляющих последовательностей для специальных символов:
|
||||
|
||||
| Последовательность | Значение |
|
||||
|---------------------|----------|
|
||||
| `\n` | новая строка (LF или 0x0A (10) в ASCII)
|
||||
| `\r` | возврат каретки (CR или 0x0D (13) в ASCII)
|
||||
| `\t` | горизонтальная табуляция (HT или 0x09 (9) в ASCII)
|
||||
| `\v` | вертикальная табуляция (VT или 0x0B (11) в ASCII)
|
||||
| `\f` | подача страницы (FF или 0x0C (12) в ASCII)
|
||||
| `\\` | обратная косая черта
|
||||
| `\$` | знак доллара
|
||||
| `\"` | двойная кавычка
|
||||
| `\[0-7]{1,3}` | последовательность символов, соответствующая регулярному выражению символа в восьмеричной системе счисления
|
||||
| `\x[0-9A-Fa-f]{1,2}`| последовательность символов, соответствующая регулярному выражению символа в шестнадцатеричной системе счисления
|
||||
|
||||
Но самым важным свойством строк в двойных кавычках является обработка переменных.
|
||||
Существует два типа синтаксиса: простой и сложный. Простой синтаксис более легок и удобен.
|
||||
Он дает возможность обработки переменной, значения массива или свойства объекта с минимумом усилий.
|
||||
Сложный синтаксис может быть определен по фигурным скобкам, окружающим выражение.
|
||||
|
||||
##### Простой синтаксис
|
||||
|
||||
Если Fenom встречает знак доллара ($), он захватывает так много символов, сколько возможно, чтобы сформировать правильное имя переменной.
|
||||
Если вы хотите точно определить конец имени, заключайте имя переменной в фигурные скобки.
|
||||
|
||||
```smarty
|
||||
{"Hi, $username!"} выведет "Hi, Username!"
|
||||
```
|
||||
|
||||
Для чего-либо более сложного, используйте сложный синтаксис.
|
||||
|
||||
##### Сложный синтаксис
|
||||
|
||||
Он называется сложным не потому, что труден в понимании, а потому что позволяет использовать сложные выражения.
|
||||
Любая скалярная переменная, элемент массива или свойство объекта, отображаемое в строку, может быть представлена в строке этим синтаксисом.
|
||||
Просто запишите выражение так же, как и вне строки, а затем заключите его в `{` и `}`.
|
||||
Поскольку `{` не может быть экранирован, этот синтаксис будет распознаваться только когда `$` следует непосредственно за `{`.
|
||||
Используйте `{\$`, чтобы напечатать `{$`. Несколько поясняющих примеров:
|
||||
|
||||
```smarty
|
||||
{"Hi, {$user.name}!"} выводит: Hi, Username!
|
||||
{"Hi, {$user->name}!"} выводит: Hi, Username!
|
||||
{"Hi, {$user->getName()}!"} выводит: Hi, Username!
|
||||
{"Hi, {\$user->name}!"} выводит: Hi, {$user->name}!
|
||||
```
|
||||
|
||||
Допускаются также различные операции и модификаторы:
|
||||
|
||||
```smarty
|
||||
{"Hi, {$user.name|up}!"} выводит: Hi, USERNAME!
|
||||
{"Hi, {$user.name|up ~ " (admin)"}!"} выводит: Hi, USERNAME (admin)!
|
||||
```
|
||||
|
||||
#### Одинарные кавычки
|
||||
|
||||
Простейший способ определить строку - это заключить ее в одинарные кавычки (символ `'`).
|
||||
|
||||
Чтобы использовать одинарную кавычку внутри строки, проэкранируйте ее обратной косой чертой `\`.
|
||||
Если необходимо написать саму обратную косую черту, продублируйте ее `\\`.
|
||||
Все остальные случаи применения обратной косой черты будут интерпретированы как обычные символы:
|
||||
это означает, что если вы попытаетесь использовать другие управляющие последовательности, такие как `\r` или `\n`, они будут выведены как есть вместо какого-либо особого поведения.
|
||||
|
||||
```smarty
|
||||
{'Hi, $foo'} выводит 'Hi, $foo'
|
||||
{'Hi, {$foo}'} выводит 'Hi, {$foo}'
|
||||
{'Hi, {$user.name}'} выводит 'Hi, {$user.name}'
|
||||
{'Hi, {$user.name|up}'} выводит "Hi, {$user.name|up}"
|
||||
```
|
||||
|
||||
### Целые числа
|
||||
|
||||
Целые числа могут быть указаны в десятичной (основание 10), шестнадцатеричной (основание 16),
|
||||
восьмеричной (основание 8) или двоичной (основание 2) системе счисления, с необязательным предшествующим знаком (`-` или `+`).
|
||||
|
||||
Для записи в восьмеричной системе счисления, необходимо поставить пред числом 0 (ноль).
|
||||
Для записи в шестнадцатеричной системе счисления, необходимо поставить перед числом 0x.
|
||||
Для записи в двоичной системе счисления, необходимо поставить перед числом 0b
|
||||
|
||||
```smarty
|
||||
{var $a = 1234} десятичное число
|
||||
{var $a = -123} отрицательное число
|
||||
{var $a = 0123} восьмеричное число (эквивалентно 83 в десятичной системе)
|
||||
{var $a = 0x1A} шестнадцатеричное число (эквивалентно 26 в десятичной системе)
|
||||
{var $a = 0b11111111} двоичное число (эквивалентно 255 в десятичной системе)
|
||||
```
|
||||
|
||||
**Замечение**
|
||||
Двоичная запись числа (`0b1011011`) не доступна на старых версиях PHP — 5.3 или ниже.
|
||||
Попытка исользовать на старых версия PHP приведет к исключению при компиляциях.
|
||||
|
||||
**Замечение**
|
||||
Размер целого числа зависит от платформы, хотя, как правило, максимальное значение примерно равно 2 миллиардам (это 32-битное знаковое).
|
||||
64-битные платформы обычно имеют максимальное значение около 9223372036854775807.
|
||||
|
||||
**Предупреждение**
|
||||
Если в восьмеричном целом числе будет обнаружена неверная цифра (например, 8 или 9), оставшаяся часть числа будет проигнорирована.
|
||||
|
||||
### Числа с плавающей точкой
|
||||
|
||||
Числа с плавающей точкой (также известные как "float", "double", или "real") могут быть определены следующими синтаксисами:
|
||||
|
||||
```smarty
|
||||
{var $a = 1.234}
|
||||
{var $b = 1.2e3}
|
||||
{var $c = 7E-10}
|
||||
```
|
||||
|
||||
### Булев тип
|
||||
|
||||
Это простейший тип. Булевое выражает истинность значения. Он может быть либо TRUE либо FALSE.
|
||||
Для указания булевого значения, используйте ключевое слово TRUE или FALSE. Оба регистро-независимы.
|
||||
|
||||
```smarty
|
||||
{set $a = true}
|
||||
```
|
||||
|
||||
### NULL
|
||||
|
||||
Специальное значение NULL представляет собой переменную без значения. NULL - это единственно возможное значение типа null.
|
||||
|
||||
Обычно возникают путаницы между NULL и FALSE, так как по роли они похожи, но разлицаются по принципу:
|
||||
NULL - это отсутствие присутствия, а FALSE - присутствие отсутствия.
|
||||
|
||||
### Операции
|
||||
|
||||
Как и любой другой язык программирования/шаблонизации, Fenom поддерживает множество различных операторов:
|
||||
|
||||
* Арифметические операторы — `+`, `-`, `*`, `/`, `%`
|
||||
* Логические операторы — `||`, `&&`, `!$var`, `and`, `or`, `xor`
|
||||
* Операторы сравнения — `>`, `>=`, `<`, `<=`, `==`, `!=`, `!==`, `<>`
|
||||
* Битовые операторы — `|`, `&`, `^`, `~$var`, `>>`, `<<`
|
||||
* Операторы присвоения — `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `|=`, `^=`, `>>=`, `<<=`
|
||||
* Строковый оператор — `$str1 ~ $str2`
|
||||
* Тернарные операторы — `$a ? $b : $c`, `$a ! $b : $c`, `$a ?: $c`, `$a !: $c`
|
||||
* Проверяющие операторы — `$var?`, `$var!`
|
||||
* Оператор тестирование — `is`, `is not`
|
||||
* Оператор содержания — `in`, `not in`
|
||||
|
||||
Подробнее об [операторах](./operators.md).
|
||||
|
||||
## Массивы
|
||||
|
||||
Массив (тип array) может быть создан конструкцией `[]`. В качестве параметров она принимает любое количество разделенных запятыми пар `key => value` (`ключ => значение`).
|
||||
```
|
||||
[
|
||||
key => value,
|
||||
key2 => value2,
|
||||
key3 => value3,
|
||||
...
|
||||
]
|
||||
```
|
||||
Запятая после последнего элемента массива необязательна и может быть опущена.
|
||||
Обычно это делается для однострочных массивов, т.е. `[1, 2]` предпочтительней `[1, 2, ]`.
|
||||
Для многострочных массивов с другой стороны обычно используется завершающая запятая, так как позволяет легче добавлять новые элементы в конец массива.
|
||||
|
||||
```smarty
|
||||
{set $array = [
|
||||
"foo" => "bar",
|
||||
"bar" => "foo",
|
||||
]}
|
||||
```
|
||||
|
||||
`key` может быть либо целым числом, либо строкой. `value` может быть любого типа.
|
||||
|
||||
Дополнительно с ключом key будут сделаны следующие преобразования:
|
||||
|
||||
* Строки, содержащие целое число будут преобразованы к числу. Например, ключ со значением `"8"` будет в действительности сохранен со значением `8`. С другой стороны, значение `"08"` не будет преобразовано, так как оно не является корректным десятичным целым.
|
||||
* Числа с плавающей точкой также будут преобразованы к числу, т.е. дробная часть будет отброшена. Например, ключ со значением `8.7` будет в действительности сохранен со значением `8`.
|
||||
* Булев также преобразовываются к целому числу. Например, ключ со значением `true` будет сохранен со значением `1` и ключ со значением `false` будет сохранен со значением `0`.
|
||||
* NULL будет преобразован к пустой строке. Например, ключ со значением `null` будет в действительности сохранен со значением `""`.
|
||||
* Массивы (тип array) и объекты (тип object) не могут использоваться в качестве ключей. При подобном использовании будет генерироваться предупреждение: Недопустимый тип смещения (Illegal offset type).
|
||||
|
||||
Если несколько элементов в объявлении массива используют одинаковый ключ, то только последний будет использоваться, а все другие будут перезаписаны.
|
||||
|
||||
Параметр `key` является необязательным. Если он не указан, Fenom будет использовать предыдущее наибольшее значение целочисленного ключа, увеличенное на 1.
|
||||
|
||||
Существующий массив может быть изменен явной установкой значений в нем.
|
||||
Это выполняется присвоением значений массиву с указанием в скобках ключа или после точки.
|
||||
Кроме того, используя скобки, вы можете опустить ключ.
|
||||
|
||||
```smarty
|
||||
{set $arr.key = value}
|
||||
{set $arr[] = value} {* будет взят максимальный целочисленый ключ, увеличенный на 1 *}
|
||||
```
|
||||
|
||||
Если массив `$arr` еще не существует, он будет создан. Таким образом, это еще один способ определить массив.
|
||||
Однако такой способ применять не рекомендуется, так как если переменная `$arr` уже содержит некоторое значение (например, строку),
|
||||
то это значение останется на месте и `[]` может на самом деле означать доступ к символу в строке. Лучше инициализировать переменную путем явного присваивания значения.
|
||||
|
||||
## Константы
|
||||
|
||||
Константы - это идентификаторы (имена) простых значений, определенные в PHP.
|
||||
Исходя из их названия, нетрудно понять, что их значение не может изменяться в ходе выполнения шаблона.
|
||||
Имена констант чувствительны к регистру. По принятому соглашению, имена констант всегда пишутся в верхнем регистре.
|
||||
Константы доступны из любого шаблона через глобальную переменную {$.const.*}: `{$.const.PHP_EOL}`.
|
||||
В шаблоне определить константу нельзя.
|
||||
|
||||
## PHP функции и методы
|
||||
|
||||
Fenom предоставляет возможноть обращаться к функиям и методам самого PHP. Использование их в шаблонах не рекомендуется.
|
||||
Используя системную переменную `$.php` можно вызвать любую функцию или метод в шаблоне:
|
||||
|
||||
```smarty
|
||||
{$.php.some_function($a, $b, $c)}
|
||||
```
|
||||
Метод вызывается иначе
|
||||
|
||||
```smarty
|
||||
{$.php.MyClass::method($a, $b, $c)}
|
||||
```
|
||||
|
||||
пространство имен указывается перед функций или классом, разделяя точкой вместо обратного слеша:
|
||||
|
||||
```smarty
|
||||
{$.php.My.NS.some_function($a, $b, $c)}
|
||||
{$.php.My.NS.MyClass::method($a, $b, $c)}
|
||||
```
|
||||
|
||||
Вызов функции и методов можно выключить настройкой `???` или ограничить.
|
||||
|
||||
## Модификаторы
|
||||
|
||||
Модификаторы переменных могут быть применены к переменным, пользовательским функциям или строкам.
|
||||
Для их применения надо после модифицируемого значения указать символ `|` (вертикальная черта) и название модификатора.
|
||||
Так же модификаторы могут принимать параметры, которые влияют на их поведение.
|
||||
Эти параметры следуют за названием модификатора и разделяются `:` (двоеточием).
|
||||
Кроме того, по умолчанию все функции PHP могут быть использованы в качестве модификаторов (что можно отключить в настройках) и модификаторы можно комбинировать.
|
||||
|
||||
```smarty
|
||||
{var $foo="User"}
|
||||
{$foo|upper} выведет "USER"
|
||||
{$foo|lower} выведет "user"
|
||||
{"{$foo|lower}"} выведет "user"
|
||||
{"User"|lower}} выведет "user"
|
||||
{$looong_text|truncate:80:"..."} обрежет текст до 80 символов и добавит символы "..."
|
||||
{$looong_text|lower|truncate:$settings.count:$settings.etc}
|
||||
{set $foo="User"|upper} значение переменной $foo будет "USER"
|
||||
```
|
||||
|
||||
## Теги
|
||||
|
||||
Все сущности шаблона можно разделить на две группы:
|
||||
|
||||
* заполнитель (placeholder) — вывод переменной в шаблоне, например `{$name}`
|
||||
* тег — конструкция, выполняющаяя некоторые действия, которая выглядит как именованный заполнитель (placeholder), например `{include $name}`
|
||||
|
||||
Теги также можно разделить на две группы:
|
||||
|
||||
* Функции. Тег функции вызывает пользовательскую во время выполнения шаблона, результат функции будет выведен вместо тега.
|
||||
Пользовательские функции являются дополнительными и могут быть индивидуальными. Они могут быть изменены по вашему желанию, также вы можете создать новые.
|
||||
* Компиляторы. В отличии от функций компиляторы вызываются во время компиляции шаблона и возвращают PHP код, который описывает некоторое действие.
|
||||
Компиляторы и формируют основные конструкции типа `if`, `foreach` и т.д.
|
||||
|
||||
### Игнорирование кода
|
||||
|
||||
В шаблонизаторе Fenom используются фигурные скобки для отделения HTML от кода Fenom.
|
||||
Если требуется вывести текст, содержащий фигурные скобки, то есть следующие варианты это сделать:
|
||||
|
||||
1. Использование блочного тега `{ignore}{/ignore}`. Текст внутри этого тега текст не компилируется шаблонизатором и выводится как есть.
|
||||
2. Если после открывающей фигурной скобки есть пробельный символ (пробел или `\t`) или перенос строки (`\r` или `\n`), то она не воспринимается как разделитель кода Fenom и код после неё выводится как есть.
|
||||
3. Установить опцию `:ignore` у блочного тега. Все Fenom теги внутри блока будут проигнорированны
|
||||
|
||||
Example:
|
||||
|
||||
```smarty
|
||||
{ignore}
|
||||
<style>
|
||||
h1 {font-size: 24px; color: #F00;}
|
||||
</style>
|
||||
{/ignore}
|
||||
<script>
|
||||
(function (text) {
|
||||
var e = document.createElement('P');
|
||||
e.innerHTML = text;
|
||||
document.body.appendChild(e);
|
||||
})('test');
|
||||
{if:ignore $cdn.yandex}
|
||||
var item = {cdn: "//yandex.st/"};
|
||||
{/if}
|
||||
</script>
|
||||
```
|
||||
|
||||
Outputs
|
||||
|
||||
```html
|
||||
<style>
|
||||
h1 {font-size: 24px; color: #F00;}
|
||||
</style>
|
||||
<script>
|
||||
(function (text) {
|
||||
var e = document.createElement('P');
|
||||
e.innerHTML = text;
|
||||
document.body.appendChild(e);
|
||||
})('test');
|
||||
var item = {cdn: "//yandex.st/"};
|
||||
</script>
|
||||
```
|
||||
|
||||
### Пробелы
|
||||
|
||||
Шаблонизатор допускает любое количество пробелов или переносов строк в своём коде
|
||||
|
||||
```smarty
|
||||
{include 'control.tpl'
|
||||
$options = $list
|
||||
$name = $cp.name
|
||||
$type = 'select'
|
||||
isolate = true
|
||||
disable_static = true
|
||||
}
|
||||
|
||||
{foreach [
|
||||
"one" => 1,
|
||||
"two" => 2,
|
||||
"three" => 3
|
||||
] as $key => $val}
|
||||
|
||||
{$key}: {$val}
|
||||
|
||||
{/foreach}
|
||||
```
|
||||
|
||||
### Параметры тегов
|
||||
|
||||
| имя | код | тип тега | описание |
|
||||
| ------- | ---- | --------- | ------------ |
|
||||
| strip | s | блоковый | активирует удаление лишних пробелов наподобие модификатора `strip` |
|
||||
| ignore | i | блоковый | парсер будет игнорировать любой Fenom синтаксис на контент блокового тега |
|
||||
| raw | a | любой | отключает экранирование |
|
||||
| escape | e | любой | принудительно активирует экранирование |
|
||||
|
||||
```smarty
|
||||
{script:ignore} ... {/script}
|
||||
{foreach:ignore:strip ...} ... {/foreach}
|
||||
```
|
|
@ -0,0 +1,14 @@
|
|||
Тег {autoescape}
|
||||
================
|
||||
|
||||
Задает индивидуальное значение параметра `auto_escape` на фрагмент шаблона:
|
||||
|
||||
```smarty
|
||||
{autoescape true}
|
||||
...
|
||||
Text: {$text} {* значение переменной $text будет заэкранированно *}
|
||||
...
|
||||
{/autoescape}
|
||||
```
|
||||
|
||||
Так же смотите тег [{raw}](./raw.md) и параметр тега [:raw](../configuration.md)
|
|
@ -0,0 +1,12 @@
|
|||
Тег {autotrim}
|
||||
==============
|
||||
|
||||
Задает индивидуальное значение параметра `auto_trim` на фрагмент шаблона:
|
||||
|
||||
```smarty
|
||||
{autotrim true}
|
||||
...
|
||||
Text: {$text}
|
||||
...
|
||||
{/autotrim}
|
||||
```
|
|
@ -0,0 +1,16 @@
|
|||
Тег {cycle}
|
||||
===========
|
||||
|
||||
Тег {cycle} используется для прохода через множество значений.
|
||||
С его помощью можно легко реализовать чередование двух или более заданных значений.
|
||||
|
||||
```smarty
|
||||
{for $i=1 to=6}
|
||||
<div class="{cycle ["odd", "even"]}">
|
||||
{/for}
|
||||
|
||||
|
||||
{for $i=1 to=6}
|
||||
<div class="{cycle ["odd", "even"] index=$i}">
|
||||
{/for}
|
||||
```
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue