Compare commits

...

338 Commits

Author SHA1 Message Date
Ivan Shalganov fbf4f46f1f
Merge pull request #341 from fenom-template/v3.0.0
Migrate to php8
2023-02-27 09:38:43 +01:00
ivan shalganov e1601dce6c migrate to php8 2023-02-23 22:09:39 +01:00
ivan shalganov 65c33ac2e3 Merge remote-tracking branch 'origin/master' into v3.0.0
# Conflicts:
#	.github/workflows/php.yml
2023-02-23 22:06:19 +01:00
ivan shalganov 74fbcd1534 migrate to php8 2023-02-23 22:03:07 +01:00
ivan shalganov 9269c96fc3 migrate to php8 2023-02-23 22:01:33 +01:00
Ivan Shalganov c7b8835ff7
Create .github/workflows/php.yml 2023-02-23 21:57:33 +01:00
ivan shalganov f8863ee0ad migrate to php8 2023-02-23 21:53:03 +01:00
ivan shalganov e8647cfb02 migrate to php8 2023-02-23 21:50:12 +01:00
ivan shalganov b04c38a533 migrate to php8 2023-02-23 21:03:19 +01:00
ivan shalganov 3af87c3419 migrate to php8 2023-02-21 22:09:00 +01:00
ivan shalganov a4fbc2a6aa migrate to php8 2023-02-19 22:14:08 +01:00
ivan shalganov ba1bc18aba migrate to php8 2023-02-06 23:49:54 +01:00
ivan shalganov 4cdfd306d9 migrate to php8 2023-02-05 22:18:18 +01:00
ivan shalganov 84dac62a85 migrate to php8 2023-02-05 21:59:04 +01:00
Ivan Shalganov 065ccaec23
Merge pull request #335 from WinterSilence/patch-2
Fix `Fenom::isAllowedFunction()`
2022-06-13 15:52:24 +03:00
Ivan Shalganov 6650668b72
Merge pull request #337 from WinterSilence/patch-3
Fix method name in `docs/ru/ext/extend.md`
2022-06-13 15:51:26 +03:00
Anton b24d9d9e1e
Update extend.md 2022-06-12 12:10:23 +03:00
Anton 5e14c6bf90
Update Fenom.php 2022-06-12 11:46:43 +03:00
Anton 79283c6f7f
Fix `Fenom::isAllowedFunction()`
- Checks if function in `ini_get('disable_functions')`
- Replace `is_callable()` to `function_exists()` to ignore invokable classes
2022-06-12 10:44:00 +03:00
Ivan Shalganov 8fb0a70311
Merge pull request #329 from EMDM45/patch-1
Update Accessor.php
2021-11-12 00:08:13 +03:00
Ivan Shalganov f3722a5f37
Merge pull request #330 from get-web/patch-1
Update set.md
2021-10-25 21:23:31 +03:00
Vitalii P 87324033e7
Update set.md 2021-10-24 15:38:18 +03:00
EMDM45 317c775f50
Update Accessor.php 2021-10-22 12:42:41 +05:00
Ivan Shalganov decad1d1fa
Update license to BSD-3-Clause 2021-10-12 15:43:18 +03:00
Ivan Shalganov f0cb251843
Update Fenom.php 2020-07-06 20:02:31 +03:00
Ivan Shalganov cb1f25d8af TravisCI: fix testing 2020-07-06 11:35:15 +03:00
Ivan Shalganov 5f9d01ae6f TravisCI: add PHP 7.3 and 7.4 2020-07-06 11:33:51 +03:00
Ivan Shalganov daf9d3cb20 Fix travis CI 2020-07-06 11:32:35 +03:00
Ivan Shalganov 52fea74cc4 `notice` appears when expression unexpectedly ends 2020-07-06 11:31:44 +03:00
Ivan Shalganov 493fcce6e0 `notice` appears when expression unexpectedly ends 2020-07-06 11:31:08 +03:00
Ivan Shalganov 07ff960324 Travis does not support PHP 5.4 and PHP 5.5 2020-07-06 11:20:07 +03:00
Maxim Kostjukevich 47fb3b5e0a
Merge pull request #311 from Electrica/patch-2
Update internal.md
2020-04-27 10:22:44 +04:00
Maxim Kostjukevich 4dd1e1870c
Update Tokenizer.php 2020-04-27 10:18:25 +04:00
Maxim Kostjukevich 55b84888e8
Update operators.md 2020-04-27 10:10:55 +04:00
Миша b4ff112237
Update internal.md
тЬся
соответсТвует
поправил
2019-12-21 16:43:22 +06:00
Ivan Shalganov fc188a5822
Merge pull request #302 from OrderTarget/master
Modifier callable docBlock fix
2018-08-16 10:21:45 +03:00
OrderTarget e4e9b2e73c
Modifier callable docBlock fix 2018-07-20 15:31:17 +03:00
Maxim Kostjukevich 5b46e54133
Merge pull request #293 from Loki3000/master
fix error in docs
2018-06-15 08:13:03 +03:00
Maxim Kostjukevich ebbec8c6be
Merge pull request #297 from pafnuty/master
Fix typos in ru/dev/readme.md
2018-06-15 08:10:37 +03:00
Pavel_Belousov d477607831 Fix typos in ru/dev/readme.md 2018-04-28 10:47:22 +04:00
Ivan Shalganov dbc9388b2f
Merge pull request #296 from sreenadh/patch-1
Community Guidelines
2018-04-23 09:25:28 +03:00
Sreenadh H 85bdf5ca94
Create CONTRIBUTING.md (#2) 2018-04-23 08:32:18 +05:30
Sreenadh H c1531ea81a
Create ISSUE_TEMPLATE.md 2018-04-23 08:28:53 +05:30
Ivan Shalganov 9a1e56d164
Merge pull request #292 from tsukasa-mixer/master
parseChain array result support
2018-03-28 12:36:06 +03:00
Maksim K d141b14017 up travis 2018-03-26 18:35:11 +03:00
Maksim K 3c083cc0dd up travis and readme 2018-03-26 18:33:45 +03:00
Loki3000 3e1fa19c70
fix doc errors 2018-03-15 18:20:44 +03:00
Loki3000 00112bb4d5
fix doc errors 2018-03-15 18:19:55 +03:00
Loki3000 80a537de8c
non existent parameter 2018-03-15 17:02:10 +03:00
Loki3000 de8dbb4d53
non existent parameter 2018-03-15 17:01:29 +03:00
Loki3000 40f50d20fd
fix error 2018-03-15 11:49:33 +03:00
Maksim 5dd197ffac
parseChain array result support
{$var->func()->func()->props->func().array_key}
2018-03-14 22:41:37 +03:00
Maxim Kostjukevich 7b0dab9247
Merge pull request #291 from JorgenPo/patch-1
Исправлен перевод документации
2018-02-09 17:23:52 +02:00
Георгий Попов d8d9833ec8
Add missing translation 2018-02-03 16:16:26 +03:00
Max Kostjukevich ab6c5ea47c Merge pull request #280 from sartatpdev999/patch-7
Fix typo error
2017-07-31 07:34:08 +03:00
Max Kostjukevich e251305ef5 Merge pull request #281 from sartatpdev999/patch-8
Fix spelling error
2017-07-31 07:33:58 +03:00
Max Kostjukevich 999a23995f Merge pull request #284 from sartatpdev999/patch-10
Fix typo & spelling errors
2017-07-31 07:33:42 +03:00
Max Kostjukevich cc2a56339d Merge pull request #285 from sartatpdev999/patch-11
Fix multiple errors
2017-07-31 07:33:17 +03:00
sartatpdev999 ec17a083d4 Extra fix
Extra fix
2017-07-31 11:21:56 +07:00
sartatpdev999 c481365d9c Fix multiple errors
Fix multiple errors
2017-07-31 11:15:31 +07:00
sartatpdev999 eedf775238 Fix typo & spelling errors 2017-07-28 10:14:49 +07:00
Ivan Shalganov 7b38f936c9 Merge pull request #283 from sartatpdev999/patch-9
Fix typo error
2017-07-27 13:56:09 +03:00
sartatpdev999 d7a8a2372a Fix typo error
можнно > можно
2017-07-27 16:27:50 +07:00
sartatpdev999 9457ac60df Fix spelling error
рекоммендуется > рекомендуется
2017-07-26 14:50:55 +07:00
sartatpdev999 75c56ebe81 Fix typo error
фунций > функций
2017-07-26 14:40:02 +07:00
Max Kostjukevich cce0e578f1 Merge pull request #279 from sartatpdev999/patch-5
Fix typo error
2017-07-26 09:37:25 +03:00
Max Kostjukevich 293893a9c8 Merge pull request #278 from sartatpdev999/patch-6
Fix spelling error & more correct translation
2017-07-26 09:36:52 +03:00
sartatpdev999 7d9b474de1 Fix spelling error & more correct translation
возвращяет > возвращает
коллбек, который будет вызван для изменения данных > функция обратного вызова, которая будет вызвана для изменения данных
2017-07-26 12:19:55 +07:00
sartatpdev999 73bb8791a5 Fix typo error
добавте > добавьте
2017-07-26 12:16:21 +07:00
Max Kostjukevich 0e5d0a27cd Merge pull request #277 from sartatpdev999/patch-4
Fix typo
2017-07-21 13:35:36 +03:00
sartatpdev999 cbab4d3184 Fix typo
интрвелами > интервалами
2017-07-21 17:21:33 +07:00
Ivan Shalganov 2d968ab8d0 Merge pull request #274 from bezumkin/patch-1
Fixed method tagPaste
2017-06-29 13:49:38 +03:00
Vasily Naumkin 6a7291fac6 Fixed method tagPaste
We need to remove quotes from names of blocks to get them from array.
2017-06-26 12:47:19 +03:00
bzick 8730343442 Fix #272 2017-05-23 11:21:35 +03:00
Ivan Shalganov 7d0db43050 Merge pull request #270 from fenom-template/develop
Fix bugs; phpunit things
2017-04-22 22:48:52 +03:00
bzick 44ac3b16e5 Phpunit things 2017-04-22 16:39:33 +03:00
bzick 4d9a82314b Phpunit things 2017-04-22 16:35:42 +03:00
bzick 2fac2bbc9f Phpunit things 2017-04-22 16:34:19 +03:00
bzick a591724d07 Phpunit things 2017-04-22 16:29:44 +03:00
bzick 4666fdced5 Phpunit things 2017-04-22 16:25:04 +03:00
bzick 66d9201a61 Phpunit things 2017-04-22 16:20:55 +03:00
bzick abf3bd5414 Fix #260 2017-04-22 15:59:20 +03:00
bzick 902284a76b Remove CI for old PHP (because PHPUnit...) 2017-04-22 15:25:00 +03:00
bzick 9670f0433a Merge branch 'master' into develop 2017-04-22 15:23:52 +03:00
bzick 28b4074d66 phpunit 5.* 2017-04-22 15:00:48 +03:00
Ivan Shalganov 449b76e554 Merge pull request #267 from 1f7/update_adapters_md
Update adapters.md
2017-03-12 22:49:05 +03:00
1f7 91c4dc611a Update adapters.md 2017-03-05 05:44:16 +03:00
bzick e97ef95ef5 CI: add --quiet mode for composer 2016-11-18 22:30:44 +03:00
bzick 23646edb6e PHP 7.1 supports 2016-11-18 22:26:03 +03:00
bzick d139a1ebf3 Fix #256 2016-11-18 22:07:14 +03:00
bzick 35455b761f Fixed: Unrecognized option "src_dir" under "coveralls" 2016-10-10 11:58:50 +03:00
bzick b92e0bbad3 Fix #241 + tests 2016-10-09 23:41:07 +03:00
Max Kostjukevich 05cda5426d Update extend.md
опечатки
2016-09-16 09:16:30 +03:00
bzick cd4f688088 Fix #249 2016-08-27 22:30:34 +03:00
bzick 514b0b6769 Fix #247 2016-08-22 17:09:18 +03:00
bzick 3171d80d8b Fix #247 2016-08-22 17:09:18 +03:00
Max Kostjukevich 58f8c0facb Merge pull request #246 from Sleuthhound/patch-4
Замечание
2016-08-13 19:23:32 +03:00
Anton Popov d64706b675 Замечание
http://php.net/manual/ru/function.fnmatch.php
2016-08-13 20:53:11 +05:00
Max Kostjukevich a4c8ae17ba Merge pull request #245 from ig0r74/patch-1
Update adapters.md
2016-08-12 19:53:04 +03:00
Igor ade29f5d67 Update adapters.md 2016-08-12 19:14:12 +03:00
Max Kostjukevich aa587a6293 Merge pull request #239 from Xesau/patch-1
Translated one sentence from Russian to English...
2016-07-06 18:06:47 +03:00
Xesau 0d599cb211 Translated one sentence from Russian to English...
and added documentation for {parent}
2016-07-05 20:10:23 +02:00
Max Kostjukevich f160664f0e Merge pull request #238 from vasia123/patch-2
fix typo
2016-06-29 21:22:36 +03:00
Vasily Krakovetsky 23cf3e72ad fix typo 2016-06-29 21:20:30 +03:00
bzick 7fffa19fa9 Fix valid filename and length 2016-06-10 15:53:16 +03:00
Ivan Shalganov eef14ecf06 Update CHANGELOG.md 2016-06-09 22:58:05 +03:00
Ivan Shalganov a3a84ea606 Merge pull request #237 from fenom-template/develop
2.11
2016-06-09 22:46:27 +03:00
bzick 76e1b5a48c Change depends satooshi/php-coveralls 2016-06-09 18:05:22 +03:00
bzick f486c7d5d4 Different packages for PHP55 and PHP70 2016-06-09 18:01:25 +03:00
bzick c87d831189 Update composer.lock 2016-06-09 17:57:42 +03:00
bzick 1e724e4c70 Tests++ 2016-06-09 16:00:18 +03:00
bzick a910b71a81 Fix comp. with 5.3 2016-06-09 14:30:20 +03:00
bzick e357a38946 Fix comp. with 5.3 2016-06-09 14:28:08 +03:00
bzick 626334017b Small fix of #229 2016-06-09 14:24:35 +03:00
bzick 24621099bf Add accessor callback; Add ?? operator 2016-06-09 13:45:26 +03:00
bzick 19ba9d3031 #231 2016-06-09 13:45:26 +03:00
bzick e557123e3c Done #231; Improve compile mechanism 2016-06-09 13:45:26 +03:00
Max Kostjukevich 180c171b1e fix #229
Fix error extends template call function
2016-06-08 13:28:02 +03:00
Max Kostjukevich 8e57ef2853 Merge pull request #235 from Daisuke-sama/patch-4
Update extends.md
2016-06-08 13:22:16 +03:00
Max Kostjukevich ed1c9f4837 Merge pull request #234 from Daisuke-sama/patch-3
Update extends.md
2016-06-08 13:21:57 +03:00
Daisuke-sama f8a2df3041 Update extends.md 2016-05-29 16:41:11 +02:00
Daisuke-sama 36b5c213a2 Update extends.md
Раздел "{$.block}" - опечатка.
2016-05-26 15:48:25 +02:00
Max Kostjukevich c6d6bc6e12 Merge pull request #233 from Daisuke-sama/patch-2
Update syntax.md
2016-05-26 16:34:51 +03:00
Max Kostjukevich c1ca6d2246 Merge pull request #232 from Daisuke-sama/patch-1
Update configuration.md
2016-05-26 16:34:37 +03:00
Daisuke-sama a005732286 Update syntax.md
1. Исправлена ссылка в разделе "Использование переменных"
2. Описка в разделе "Модификаторы"
3. Опечатка в разделе "Параметры тегов"
2016-05-26 15:27:23 +02:00
Daisuke-sama 4d76ce7abf Update configuration.md 2016-05-26 14:45:15 +02:00
bzick dec06c888e Done #228 2016-05-08 18:26:01 +03:00
bzick d23e2b4c4f Cleanup 2016-05-08 00:58:53 +03:00
bzick 32ce405de2 Docs++ 2016-05-08 00:57:02 +03:00
Ivan Shalganov 48f42c82a9 Merge pull request #227 from fenom-template/develop
2.9.0
2016-05-08 00:44:38 +03:00
Ivan Shalganov 0d1e7e56a6 Merge pull request #226 from fenom-template/master
Sync develop
2016-05-08 00:38:42 +03:00
bzick f315d937a8 Docs++ 2016-05-08 00:38:17 +03:00
Ivan Shalganov 279459be55 Merge pull request #224 from Sleuthhound/patch-3
Доступ к последовательности методов
2016-05-08 00:34:50 +03:00
bzick e289b9b3b1 Docs++ 2016-05-08 00:33:23 +03:00
bzick ba4ba548ff Foreach props, range iterator and more 2016-05-06 23:04:08 +03:00
Ivan Shalganov 9d1f0c4cae Merge pull request #222 from Sleuthhound/patch-1
Глобальная переменная в качестве параметра
2016-05-04 11:52:36 +03:00
Anton Popov 165d4816d6 Update Fenom.php 2016-04-19 14:35:25 +05:00
Anton Popov bfb64f150a Глобальная переменная в качестве параметра
Использование глобальных переменных в качестве параметров функций и методов:
object->method($.post.id)
2016-04-19 14:06:49 +05:00
bzick 1559adf030 Docs++ 2016-04-14 12:58:16 +03:00
bzick 45c9f27ae6 Docs++ 2016-04-13 11:34:38 +03:00
bzick eb75ae0bbb Docs++ 2016-04-12 12:28:57 +03:00
bzick 497f2e5b4b Docs++ 2016-04-12 09:37:40 +03:00
bzick 1c73d35681 Cleanup extending algorithm 2016-04-11 20:23:28 +03:00
bzick d6aa777fd0 Docs #209 [ru] 2016-04-11 20:19:31 +03:00
bzick 027075d7b5 Add #209: block's accessor $.blocks 2016-04-11 19:44:59 +03:00
Max Kostjukevich 2d3c89ec1e Merge pull request #219 from vasia123/patch-1
fix typo
2016-03-28 11:34:40 +03:00
Vasily Krakovetsky 1a3a3739ce fix typo 2016-03-28 11:13:26 +03:00
Max Kostjukevich 2ed57c959c Merge pull request #218 from DaaGER/patch-2
Update start.md
2016-03-15 14:27:38 +02:00
DaaGER 0dfcdfbcf7 Update start.md 2016-03-15 15:11:13 +03:00
Ivan Shalganov d52aaa57a2 Merge pull request #212 from fenom-template/develop
Fix #195; Catch Throwable exceptions;
2016-02-23 13:21:43 +03:00
bzick 3766505e5c Fix #195; Catch Throwable exceptions; 2016-02-23 13:16:48 +03:00
Ivan Shalganov 7668426f65 Merge pull request #211 from fenom-template/develop
Fix #162
2016-02-23 12:56:24 +03:00
bzick 46708c6195 Fix #162 2016-02-23 12:41:46 +03:00
Ivan Shalganov 32755c3787 Merge pull request #210 from fenom-template/master
Sync develop
2016-02-23 12:41:32 +03:00
Ivan Shalganov 9f1bad3740 Merge pull request #203 from zhabinka/patch-1
Update lower.md
2015-12-28 13:35:05 +03:00
zhabinka 939a608db0 Update lower.md 2015-12-27 18:50:18 +03:00
Max Kostjukevich b9ee7bf609 Merge pull request #202 from zhabinka/master
Update lower.md
2015-12-27 17:47:34 +02:00
zhabinka de35e9addb Update lower.md 2015-12-27 17:52:57 +03:00
Ivan Shalganov da9cafe4f3 Merge pull request #198 from sin4end/patch-1
Update ereplace.md
2015-11-04 16:28:09 +03:00
sin4end 6ca82e267b Update ereplace.md
Исправлена опечатка в строке 8: должно быть ereplace, а не replace
2015-11-04 17:28:29 +06:00
Ivan Shalganov 4491176cf4 Update readme.md 2015-11-04 11:15:06 +03:00
Ivan Shalganov 359cf5fbcb Update start.md 2015-11-04 11:14:46 +03:00
Ivan Shalganov 28935c0ddc Support PHP 7.0 (again) 2015-10-10 23:20:00 +03:00
Ivan Shalganov 10c8109bb5 Merge pull request #186 from maxicms/patch-1
fix typo
2015-08-14 21:25:19 +03:00
Max Kostjukevich b82b6e7a58 fix typo 2015-08-14 13:05:45 +03:00
Ivan Shalganov e2a3087dfa Merge pull request #185 from fenom-template/develop
2.8
2015-08-13 15:04:17 +03:00
bzick 5c86d2d6ae Docs 2015-08-13 14:55:00 +03:00
bzick 544aa4f248 Fix sub-issue #159 (https://github.com/fenom-template/fenom/issues/159#issuecomment-119112070) 2015-08-13 11:03:51 +03:00
bzick 1363945716 Fix #171 2015-08-13 10:33:39 +03:00
Ivan Shalganov d596c81b4c Merge pull request #184 from fenom-template/master
sync develop
2015-08-13 00:13:28 +03:00
bzick 10221b87ea Fix php53 2015-08-13 00:12:06 +03:00
bzick 4fe339ba21 Add predefined accessors Fenom::ACCESSOR_PROPERY and Fenom::ACCESSOR_METHOD 2015-08-13 00:07:01 +03:00
bzick 213184c8a8 Fix: travis-ci: sudo: false 2015-08-07 17:21:24 +03:00
bzick 5da2df1eb4 Fix: #174 2015-08-07 17:20:50 +03:00
Ivan Shalganov ae93c8f94a Merge pull request #175 from maxicms/master
Add prefix compile ID for template file name (by @maxicms )
2015-08-06 15:19:12 +03:00
maxicms 0a8793fe7b remove default prefix 2015-08-06 14:02:43 +03:00
maxicms 05e35261e4 Add prefix compile ID for template file name 2015-08-06 08:51:26 +03:00
Ivan Shalganov 6331ad44a4 Merge pull request #173 from fobo66/patch-1
Fix a lot of typos
2015-07-21 10:19:54 +03:00
Andrey Mukamolow f5d05e81a6 Fix a lot of typos 2015-07-18 12:04:49 +03:00
Ivan Shalganov 35cfda7516 Merge pull request #172 from Qwarble/patch-1
Опечатка
2015-07-01 17:43:51 +03:00
Alexey f9fa4fe474 Опечатка 2015-07-01 17:25:27 +03:00
Ivan Shalganov 56dfcfc71f Merge pull request #170 from fenom-template/develop
2.7.0
2015-06-03 11:57:35 +03:00
bzick bf44511a53 Merge branch 'origin/master' 2015-06-03 11:41:43 +03:00
bzick bd5557925d Merge remote-tracking branch 'remotes/origin/master' into develop
# Conflicts:
#	src/Fenom.php
2015-06-03 11:36:19 +03:00
bzick 10bc614a84 Merge remote-tracking branch 'remotes/origin/master' into develop
# Conflicts:
#	src/Fenom.php
2015-06-03 11:36:05 +03:00
bzick 48e4931506 Add Fenom::ACCESSOR_CALL parser 2015-06-03 11:31:53 +03:00
bzick c6dbdfff95 Add global charset for Fenom 2015-06-03 00:19:40 +03:00
bzick c2751e069c Fix #158 2015-06-03 00:13:09 +03:00
bzick e0fc70b751 Improve accessor: add writable condition 2015-06-02 10:59:28 +03:00
bzick ef4458ca10 Add custom parsers for accessors 2015-06-01 23:42:47 +03:00
bzick 3b56906ec8 Remove php 7 from CI (buggy) 2015-06-01 23:37:49 +03:00
bzick 30921d3500 Refectory term parser (if ->switch) 2015-06-01 23:36:30 +03:00
bzick ec890cc819 Add is_var argument for accessor 2015-06-01 23:20:02 +03:00
bzick bf0a0ffedc Add support PHP 7 for CI 2015-05-23 23:21:46 +03:00
Ivan Shalganov 0511a43539 Merge pull request #168 from fenom-template/develop
Done #165
2015-05-23 23:17:34 +03:00
bzick 806467453d Done #165 2015-05-23 23:09:16 +03:00
Ivan Shalganov 86c6630243 Merge pull request #167 from pafnuty/patch-7
Update ignore.md
2015-05-05 20:06:30 +03:00
Pavel Belousov fd777eb606 Update ignore.md
Добавил описание модификатора `:ignore, его логично упомянуть в этом файле.
2015-05-05 19:33:46 +03:00
Ivan Shalganov 7f05e13725 Merge pull request #164 from fenom-template/develop
Fix: parse error if macro defined without arguments
2015-04-26 22:32:22 +03:00
bzick 9269b6b4ad Fix: parse error if macro defined without arguments 2015-04-26 22:24:20 +03:00
Ivan Shalganov 034b4b7f14 Merge pull request #161 from Sleuthhound/master
Fix typo, version
2015-03-10 10:47:49 +03:00
Anton Popov 4d11eeed0d Fix typo, version 2015-03-08 11:17:14 +05:00
Ivan Shalganov 3a1da1c154 Merge pull request #157 from fenom-template/develop
2.6
2015-02-22 23:43:33 +03:00
bzick c34d45698a Update changelog 2015-02-22 23:31:12 +03:00
bzick 9a725deaff Done range in foreach 2015-02-22 23:07:26 +03:00
bzick 83fbfb1fca Merge branch 'origin/master'
Conflicts:
	src/Fenom/Template.php
	tests/cases/Fenom/SandboxTest.php
2015-02-22 11:32:11 +03:00
Ivan Shalganov fdc6caeb20 Merge pull request #154 from pafnuty/patch-6
fix typo
2015-02-22 11:08:17 +03:00
Pavel Belousov a9f8a34aa2 fix typo 2015-02-20 23:07:42 +03:00
Ivan Shalganov d9df706ae1 Merge pull request #153 from pafnuty/patch-5
fix typo
2015-02-20 10:22:31 +03:00
Pavel Belousov b07a9beea1 fix typo 2015-02-19 19:39:51 +03:00
bzick 22501f3704 Add composer.lock to git 2015-02-19 17:12:33 +03:00
bzick 3db7d0b220 Fix #152 2015-02-19 17:11:44 +03:00
bzick 8f3c94a7a1 Fix #147 2015-02-19 17:04:15 +03:00
Ivan Shalganov 4dbbc81785 Merge pull request #150 from pafnuty/patch-4
fix typo
2015-02-17 16:47:48 +03:00
Pavel Belousov 89f9da8c9d fix typo 2015-02-14 04:16:51 +03:00
bzick ed860a49cb Add range support. Tag {for} now deprecated 2015-02-12 12:13:35 +03:00
Ivan Shalganov 45a3abed88 Merge pull request #148 from fenom-template/develop
Fix bug: unexpected array conversion when object given to {foreach} with...
2015-02-10 14:37:55 +03:00
bzick a9b9c89f88 Fix bug: unexpected array conversion when object given to {foreach} with force verify option 2015-02-10 14:30:31 +03:00
Ivan Shalganov 5dc7bbfd56 Merge pull request #145 from fenom-template/develop
2.5.1
2015-02-02 12:11:30 +03:00
bzick d5417630ac Add test for #144 (condition) 2015-02-02 12:05:02 +03:00
bzick f985fff314 Fix #144: invalid ternary operator priority 2015-02-02 12:03:15 +03:00
bzick a09b2f7620 Fix #135 (repeat commit) 2015-02-02 12:02:30 +03:00
bzick 89f2e23750 Fix #144: forgot prepend unary operator 2015-02-02 11:49:42 +03:00
Ivan Shalganov 1a72b9d43e Update README.md 2015-02-01 01:28:22 +03:00
Ivan Shalganov feb3a51884 Merge pull request #142 from fenom-template/develop
2.5
2015-02-01 01:16:58 +03:00
bzick 5d87060f42 Dummy protect 2015-02-01 01:13:39 +03:00
bzick fb544b10e8 Add more test for 'in' 2015-02-01 00:58:40 +03:00
bzick 76b5d3e6fa Add array of variable to tag-function's arguments 2015-02-01 00:51:49 +03:00
bzick 4beacd57b9 Fix #116 (broken regexp) 2015-02-01 00:49:59 +03:00
bzick 0592e248e2 Add test for 'in' operator 2015-02-01 00:35:41 +03:00
bzick 0339a12b3d Fix #116 2015-01-31 19:16:43 +03:00
Ivan Shalganov 1ec97221f5 Update .coveralls.yml 2015-01-30 17:18:53 +03:00
Ivan Shalganov e157c08dcf Update .coveralls.yml 2015-01-30 17:18:08 +03:00
Ivan Shalganov 269dd36a30 Update README.md 2015-01-30 16:58:34 +03:00
Ivan Shalganov dd6986b60f Merge pull request #139 from fenom-template/develop
Fix #138
2015-01-30 16:56:37 +03:00
bzick e310236745 Fix #138 2015-01-30 16:52:58 +03:00
Ivan Shalganov 7e32c38db4 Update README.md 2015-01-30 12:51:38 +03:00
Ivan Shalganov 01ae6081c6 Merge pull request #136 from bzick/develop
Fix: parse error then modifier's argument converts to false
2015-01-22 14:54:34 +03:00
bzick 2f769c294c Fix: parse error then modifier's argument converts to false 2015-01-22 13:55:22 +03:00
Ivan Shalganov 47cee02dd3 Merge pull request #133 from bzick/develop
Fix #132
2015-01-08 16:06:52 +03:00
bzick 7ac11fb3cc Remove debug 2015-01-08 15:57:53 +03:00
bzick d096a80395 Fix #132 + test.
Also small performance fix
2015-01-08 15:52:33 +03:00
bzick 16d5f337c0 Formatting 2015-01-08 12:44:38 +03:00
Ivan Shalganov e4a7a07107 Merge pull request #131 from bzick/develop
small fixes
2015-01-07 17:42:58 +03:00
bzick 5e42892979 fix typo 2015-01-07 17:19:17 +03:00
bzick 8d6bfb00d1 Small improve 2015-01-07 17:00:54 +03:00
bzick 22fb471c89 Cleanup. Improves. 2015-01-07 15:24:57 +03:00
Ivan Shalganov 7d1b7cb691 Merge pull request #130 from bzick/develop
Bug fixes 2.4.1
2015-01-07 00:57:06 +03:00
bzick d4bfb366b8 Fix #128 2015-01-06 23:42:54 +03:00
bzick ae592d22c7 Fix bug: invalid cache name then templates extends via array 2015-01-06 21:35:42 +03:00
Ivan Shalganov 317bce9e19 Fix typo 2015-01-02 23:12:32 +03:00
Ivan Shalganov 964f20a914 Merge pull request #127 from bzick/develop
Release 2.4.0
2015-01-02 23:11:47 +03:00
bzick 2fbb6b44e4 Add note into changelog 2015-01-02 23:05:23 +03:00
bzick bc73e5b733 Merge branch 'master' into develop
Conflicts:
	docs/ru/syntax.md
	sandbox/fenom.php
2015-01-02 22:48:56 +03:00
bzick e88d416df1 Docs: add english docs 2015-01-02 22:44:23 +03:00
bzick 4ca7ccb5e0 Fix #126: disable clearcachestats() by default in Fenom\Provider. Add method Fenom\Provider->setClearCachedStats() for enable clearcachestats() 2015-01-02 17:43:41 +03:00
bzick 22dc90943f Add example 2014-11-06 22:32:20 +03:00
bzick b0422ad43c Add example 2014-11-06 22:31:59 +03:00
bzick f532658cc4 Fix #122. Compatibility problem with mb_string 2014-11-06 00:55:32 +03:00
bzick 7e8598ae3b ++Docs 2014-11-05 16:07:50 +03:00
bzick 1c439fedb7 Docs 2014-10-31 10:55:58 +03:00
bzick e0a3cc3a0d Docs 2014-10-31 00:24:56 +03:00
bzick c238053e99 Fix #120, #104, #119 2014-10-30 23:56:16 +03:00
Ivan Shalganov ab52186dfa Update README.md 2014-10-15 10:01:22 +04:00
bzick 0091b17c8a Done accessor 2014-10-15 01:01:55 +04:00
Ivan Shalganov d89a315d4b Update README.md 2014-10-13 14:33:50 +04:00
bzick 4b65e80312 Fix for php 5.3 2014-10-05 22:01:11 +04:00
bzick e55402c2f4 Dev accessor. Add ~~ operator. ++Docs. ++Tests 2014-10-05 20:37:30 +04:00
Ivan Shalganov 8259503efe Update README.md 2014-09-19 17:58:28 +04:00
Ivan Shalganov e01a474b90 Merge pull request #114 from MunGell/master
English docs
2014-09-15 21:26:17 +04:00
Shmavon Gazanchyan 292bdd90b5 Editorial changes for dev readme 2014-09-15 18:06:05 +01:00
Shmavon Gazanchyan 16b1bef169 Remove duplicate content
Git instructions are already exist in readme.md file
2014-09-15 18:05:39 +01:00
Ivan Shalganov 88a5efb7ea Merge pull request #111 from pafnuty/patch-3
Исправил опечатки
2014-09-08 15:12:20 +04:00
Pavel Belousov 435fd15a67 Исправил опечатки 2014-09-08 01:17:48 +04:00
Ivan Shalganov cd8b466951 Merge pull request #109 from pafnuty/patch-1
убрал лишний текст на английском
2014-09-07 11:58:28 +04:00
Ivan Shalganov 94c468032b Merge pull request #110 from pafnuty/patch-2
поправил недопереведённую фразу
2014-09-07 11:58:06 +04:00
Pavel Belousov f27ddd904e поправил недопереведённую фразу 2014-09-05 17:04:53 +04:00
Pavel Belousov 0514d579c8 убрал лишний текст на английском 2014-09-05 17:00:34 +04:00
Ivan Shalganov 506fbd8909 Update extend.md 2014-08-29 10:43:23 +04:00
Ivan Shalganov 94a588e494 Update start.md
Add example (in progress)
2014-08-23 14:09:18 +04:00
Ivan Shalganov 57d1ca37ee Update readme.md
Add warning
2014-08-23 12:48:18 +04:00
Ivan Shalganov 4d89a7f3d0 Update extend.md
Fix typos #107
2014-08-23 12:29:25 +04:00
Ivan Shalganov b3992033c9 Update operators.md
fix typos #107
2014-08-23 12:23:04 +04:00
Ivan Shalganov 0be8b15d68 Update syntax.md
fix typos #107
2014-08-23 12:16:26 +04:00
Ivan Shalganov b842421408 Update start.md
fix typos #107
2014-08-23 12:08:32 +04:00
Ivan Shalganov b6f363eaff Merge pull request #106 from bzick/develop
Fix #105 + tests
2014-08-23 11:46:19 +04:00
bzick af7546a8ec Fix #105 + tests 2014-08-23 11:41:21 +04:00
Ivan Shalganov 8772df82db Merge pull request #103 from pafnuty/patch-3
Небольшое исправление опечаток
2014-08-08 18:27:58 +04:00
Pavel Belousov 7142641ac3 Небольшое исправление опечаток 2014-08-08 16:50:51 +04:00
Ivan Shalganov 90e235047a Merge pull request #102 from pafnuty/patch-2
добавил ссылку на хабр.
2014-08-08 16:50:26 +04:00
Pavel Belousov 823b7fc15a добавил ссылку на хабр. 2014-08-08 16:44:12 +04:00
Ivan Shalganov 250c9c1e1c Update CHANGELOG.md 2014-08-08 16:22:46 +04:00
Ivan Shalganov 8ce6779119 Merge pull request #101 from bzick/develop
Ver 2.3.0
2014-08-08 16:18:53 +04:00
bzick bb8d351e93 Merge branch 'origin/master'
Conflicts:
	docs/ru/tags/raw.md
2014-08-08 16:04:37 +04:00
bzick 295ad63cf1 Done ru docs [beta] 2014-08-08 15:58:50 +04:00
bzick 11af8fd2c1 Makeup ru docs 2014-08-07 13:36:04 +04:00
bzick d43887a3d8 Back to coveralls.io 2014-08-06 23:36:04 +04:00
Ivan Shalganov 4af53621e6 Update README.md 2014-08-06 22:43:41 +04:00
bzick 72b4e36585 Translate tags's documentation 2014-08-06 22:42:42 +04:00
bzick 0118ef192b Translate modifier's documentation 2014-08-06 21:36:11 +04:00
bzick 7d59b0e642 Done #97 + tests 2014-08-06 01:17:21 +04:00
bzick 469833376d Add tests for {add} 2014-08-06 00:08:51 +04:00
Ivan Shalganov f15fbb323d Merge pull request #99 from pafnuty/patch-1
опечатка в слове {/autoescape}
2014-08-05 22:32:26 +04:00
bzick 3dc64aa2ce Update dosc and add tags {set} and {add} 2014-08-05 17:50:00 +04:00
bzick 6329765572 Update dosc and add tags {set} and {add} 2014-08-05 17:49:42 +04:00
Pavel Belousov c5217075ca опечатка в слове {/autoescape} 2014-08-05 00:40:58 +04:00
bzick 0b96a02dd9 Add operator doc [ru] 2014-08-03 17:00:30 +04:00
bzick 0ff3ffc27f Reformat documentation 2014-08-02 00:24:14 +04:00
bzick 5972884c80 Add russian docs 2014-08-01 12:12:19 +04:00
Ivan Shalganov 00eaafc39f Merge pull request #96 from bzick/develop
Improve code climate
2014-07-30 00:35:01 +04:00
bzick 86479f6459 Improve GPA 2014-07-30 00:23:26 +04:00
bzick e357dbe5f3 Change code coverage system to CodeClimate 2014-07-29 23:33:28 +04:00
Ivan Shalganov eb5ba94ff9 Update upper.md 2014-07-29 14:47:45 +04:00
Ivan Shalganov 05e501a096 Merge pull request #94 from bzick/develop
Develop
2014-07-29 13:32:13 +04:00
bzick 342078b45e Merge branch 'origin/master' 2014-07-29 13:24:52 +04:00
bzick 14bcae4fa1 Merge branch 'origin/master' 2014-07-29 13:23:24 +04:00
bzick c52606a5ab Docs++ 2014-07-29 13:22:46 +04:00
Ivan Shalganov 9314d9ca46 Merge pull request #93 from bakatrouble/master
Fixing link to options documentation (by @bakatrouble)
2014-07-28 23:30:39 +04:00
bakatrouble 7ef193749b Update start.md 2014-07-28 13:49:28 +04:00
bakatrouble f7d30418b6 Fixed link to settings documentation 2014-07-28 13:48:55 +04:00
Ivan Shalganov ca95ce0ec7 Add Code Climate 2014-07-13 11:52:26 +04:00
Ivan Shalganov 87105bf683 Merge pull request #92 from bzick/develop
2.2
2014-07-11 14:01:59 +04:00
bzick b1b88e932a Fix travis config 2014-07-11 12:15:21 +04:00
bzick 97838eb0b9 Add tests 2014-07-11 12:11:51 +04:00
bzick e6a9b511bd Add test for new modifiers and fix bugs 2014-07-11 11:46:19 +04:00
bzick 8e48d1aaee Add modifiers match, ematch, replace, ereplace, split, esplit, join with documentation [2] 2014-07-10 23:28:27 +04:00
bzick 702dbfd88d Add modifiers match, ematch, replace, ereplace, split, esplit, join with documentation 2014-07-10 23:27:59 +04:00
bzick d9b21ea68c addFunctionSmart allow array as callable 2014-07-08 10:27:02 +04:00
Ivan Shalganov 7422aef4de Update CHANGELOG.md 2014-07-03 12:23:20 +04:00
Ivan Shalganov f74ee26d95 Merge pull request #91 from bzick/develop
2.1.2
2014-07-03 12:18:51 +04:00
bzick 0340915b76 Fix test for PHP 5.3 2014-07-03 12:11:21 +04:00
bzick a4883d75e5 Fix #90 2014-07-03 12:07:20 +04:00
bzick eb49861ab8 Done #88 2014-07-03 11:28:59 +04:00
Ivan Shalganov 8024cd614a Update CHANGELOG.md 2014-06-30 14:14:06 +04:00
Ivan Shalganov 19aa493474 Merge pull request #86 from nekufa/patch-1
Fixed array convertion and foreach tag separator
2014-06-30 13:59:31 +04:00
bzick 3a6347d96b Hotfix: semicolon missed 2014-06-30 13:56:58 +04:00
Dmitry Krokhin 89d1cae918 Fixed array convertion and foreach tag separator 2014-06-30 13:36:11 +04:00
Ivan Shalganov ce9245cb50 Update CHANGELOG.md
Add 2.1 changes
2014-06-29 15:22:36 +04:00
171 changed files with 9100 additions and 2727 deletions

View File

@ -1,5 +1,4 @@
service_name: travis-ci
src_dir: src
coverage_clover: build/logs/clover.xml

34
.github/CONTRIBUTING.md vendored Normal file
View File

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

18
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -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}
```

31
.github/workflows/php.yml vendored Normal file
View File

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

10
.gitignore vendored
View File

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

View File

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

View File

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

View File

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

View File

@ -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" ]
}
}

1752
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
Git conversation
================
Ветка `master` содержит стабильную последнюю версию проекта. В ветку `master` может сливаться новая версия проекта из `develop` или исправления.
Ветка `develop`, для разработки, содержит не стабильную версию проекта. Принимает все новшевства, изменения и исправления.

View File

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

3
docs/adapters.md → docs/en/adapters.md Normal file → Executable file
View File

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

View File

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

15
docs/en/dev/readme.md Normal file
View File

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

View File

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

18
docs/en/mods/ematch.md Normal file
View File

@ -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}
```

23
docs/en/mods/ereplace.md Normal file
View File

@ -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 *}
```

19
docs/en/mods/esplit.md Normal file
View File

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

16
docs/en/mods/join.md Normal file
View File

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

View File

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

24
docs/en/mods/match.md Normal file
View File

@ -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}
```

14
docs/en/mods/replace.md Normal file
View File

@ -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"}
```

18
docs/en/mods/split.md Normal file
View File

@ -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"]
```

View File

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

View File

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

94
docs/en/readme.md Normal file
View File

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

View File

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

569
docs/en/syntax.md Normal file
View File

@ -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}
```

View File

@ -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}
```

9
docs/en/tags/do.md Normal file
View File

@ -0,0 +1,9 @@
Tag {do}
========
Evaluates any expression and doesn't print anything
```smarty
{do $count++}
{do $object->method()}
```

70
docs/en/tags/extends.md Normal file
View File

@ -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}
```

View File

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

104
docs/en/tags/foreach.md Normal file
View File

@ -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}`.

44
docs/en/tags/if.md Normal file
View File

@ -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}
```

51
docs/en/tags/macro.md Normal file
View File

@ -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}
```

84
docs/en/tags/set.md Normal file
View File

@ -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}.

View File

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

10
docs/ru/adapters.md Executable file
View File

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

6
docs/ru/articles.md Normal file
View File

@ -0,0 +1,6 @@
Статьи
======
## 2013
[Fenom — yet another PHP template engine](http://habrahabr.ru/post/169525/) [RU]

63
docs/ru/benchmark.md Normal file
View File

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

3
docs/ru/callbacks.md Normal file
View File

@ -0,0 +1,3 @@
Callbacks
=========

58
docs/ru/configuration.md Normal file
View File

@ -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*')
```
**Замечание**
По умолчанию все параметры деактивированы.

90
docs/ru/dev/internal.md Normal file
View File

@ -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()`, который распарсит модификатор.

22
docs/ru/dev/readme.md Normal file
View File

@ -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).

120
docs/ru/dev/schema.md Normal file
View File

@ -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 |
|___________________|
```

281
docs/ru/ext/extend.md Normal file
View File

@ -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");`

View File

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

90
docs/ru/ext/tags.md Normal file
View File

@ -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);
```

4
docs/ru/inheritance.md Normal file
View File

@ -0,0 +1,4 @@
Наследование шаблонов
=====================
Документации пока нет, [почитайте на хабре](http://habrahabr.ru/post/169525/) пока

View File

@ -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 - часовой пояс или имя или сокращение
* %% - буквальный символ `%'

18
docs/ru/mods/ematch.md Normal file
View File

@ -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}
```

25
docs/ru/mods/ereplace.md Normal file
View File

@ -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 *}
```
**Замечание:** воизбежание скрытых ошибок при выполнении сущностей регулярные выражения стоит помещать в одинарные кавычки.

19
docs/ru/mods/escape.md Normal file
View File

@ -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`.

19
docs/ru/mods/esplit.md Normal file
View File

@ -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"]
```

12
docs/ru/mods/in.md Normal file
View File

@ -0,0 +1,12 @@
Модификатор in
===========
Модификатор является реализацией оператора содержания [in](../operators.md#Оператор-содержания).
```smarty
{if $number|in:[1, 3, 42]}
...
{/if}
```

16
docs/ru/mods/join.md Normal file
View File

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

10
docs/ru/mods/length.md Normal file
View File

@ -0,0 +1,10 @@
Модификатор length
===============
Модификатор возвращает количество элементов массива, итератора или символов в строке (работает с UTF8).
```smarty
{if $images|length > 5}
to many images
{/if}
```

13
docs/ru/mods/lower.md Normal file
View File

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

29
docs/ru/mods/match.md Normal file
View File

@ -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 символов.

14
docs/ru/mods/replace.md Normal file
View File

@ -0,0 +1,14 @@
Модификатор replace
================
Заменяет все вхождения строки поиска на строку замены
```
{$string|replace:$search:$replace}
```
Этот модификатор возвращает строку, в котором все вхождения `$search` в `$subject` заменены на `$replace`.
```smarty
{$fruits|replace:"pear":"orange"}
```

18
docs/ru/mods/split.md Normal file
View File

@ -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"]
```

27
docs/ru/mods/strip.md Normal file
View File

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

23
docs/ru/mods/truncate.md Normal file
View File

@ -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 без дополнительных расширений.

9
docs/ru/mods/unescape.md Normal file
View File

@ -0,0 +1,9 @@
Модификатор unescape
=================
Модификато `unescape` является обратным действием модификатора `escape`. Так же имеет режимы `html`, `js` and `URI`.
```smarty
{$text|unescape:$type = 'html'}
```

13
docs/ru/mods/upper.md Normal file
View File

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

309
docs/ru/operators.md Normal file
View File

@ -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]}
```

103
docs/ru/readme.md Normal file
View File

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

110
docs/ru/start.md Normal file
View File

@ -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);
```
-->

451
docs/ru/syntax.md Normal file
View File

@ -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}
```

View File

@ -0,0 +1,14 @@
Тег {autoescape}
================
Задает индивидуальное значение параметра `auto_escape` на фрагмент шаблона:
```smarty
{autoescape true}
...
Text: {$text} {* значение переменной $text будет заэкранированно *}
...
{/autoescape}
```
Так же смотите тег [{raw}](./raw.md) и параметр тега [:raw](../configuration.md)

12
docs/ru/tags/autotrim.md Normal file
View File

@ -0,0 +1,12 @@
Тег {autotrim}
==============
Задает индивидуальное значение параметра `auto_trim` на фрагмент шаблона:
```smarty
{autotrim true}
...
Text: {$text}
...
{/autotrim}
```

16
docs/ru/tags/cycle.md Normal file
View File

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