fenom-template / fenom

Template Engine for PHP. Maintainers wanted!
Other
446 stars 108 forks source link

Передача JSON в шаблон #147

Closed litvinenkow closed 9 years ago

litvinenkow commented 9 years ago

Всё-таки есть проблема, сейчас попробую описать. В прошлый раз я говорил что у меня два раза прогоняется код.

То есть имеется общий шаблон в который внедряется кусок сварганеный функцией fetch. Например нам надо в этот кусок вставить JSON какой-то. Ну просто передать массив в JavaScript. Мы делаем так

<script>
var v = '{json_encode($var)}';
</script>

В итоге при прогоне второй раз этот JSON кусок пытается обработаться и ничего не получается. Я исхитрялся прошлый раз делал через base64encode, а потом декодировал уже JavaScript'om.

<script>
include('/js/base64.js');
var car_volume_base64 = '{base64_encode(json_encode($l->volume_arr))}';
var car_volume=$.parseJSON(Base64.decode(car_volume_base64));
</scipt>            

Но это понятное дело не путь джедая.

Сразу оговорюсь, {ignore}{json_encode($var)}{/ignore} как и {ignore}{$encoded_var}{/ignore} понятное дело не подойдут, в результат полетят имена переменных. Так вот как же всё-таки правильно передать туда этот JSON кусок, чтобы он не рендерился второй раз впоследствии?

Я пока вижу только одну возможность, написать свою функцию, которая будет возвращать выражение, обрамленное {ignore}{/ignore}, но может еще какая-то имеется?

maxisoft-git commented 9 years ago

а можно реальный кусок кода шаблона увидеть?

litvinenkow commented 9 years ago

я добавил

bzick commented 9 years ago

попробуйте так

<script>
var v = '{$var|json_encode:$.const.JSON_PRETTY_PRINT}';
</script>
bzick commented 9 years ago

json будет не однострочный, конечно, но зато будут переносы после { и Fenom будет их игнорировать

bzick commented 9 years ago

Правда, константа JSON_PRETTY_PRINT появилась с php 5.4

litvinenkow commented 9 years ago

грустно, у меня на одном сервере есть 5.4, а на другом нет( придется видимо, где-понадобится что-то такое использовать

$fm->addModifier('json_encode_ignore', function ($var) {
    return '{ignore}'.json_encode($var).'{/ignore}';
});
maxisoft-git commented 9 years ago

Добрался до ноута с fenom и проектам моими. проверил работу кода который был представлен выше а частности есть шаблон index.tpl такого формата

<div class="page"> 
{$html_page}
</div>

и есть шаблон config.tpl который получаем в перемерную html_page через fetch

в шаблоне config.tpl прописал

<script>
var v = '{json_encode($cfg)}';
</script>

все работает корректно без ломания кода, может быть конечно вызов шаблона у Вас по другому сделан, но я так и не смог повторить проблему с пломкой кода.

bzick commented 9 years ago

как я понял проблему (грубая зарисовка): fragement.tpl:

<script>
var v = '{json_encode($cfg)}';
</script>

PHP

$fragment = $fenom->fetch("fragement.tpl");
...
// $fragment == '<script>var v =  {"a":1, "b":2};</script>'
$tpl = '<body>'.$fragment.'</body>';
$fenom->compileCode($tpl)->display($vars); // падает ибо {"a":1, "b":2} воспринимается как тег
alexandr-v commented 9 years ago
<script>
var v = '{$var|replace:"{":"{ "}';
</script>

а так не прокатит?)

bzick commented 9 years ago

Да, должно прокатить

<script>
var v = '{$var|json_encode|replace:"{":"{ "}';
</script>

но есть риск замены в { строках json-на

maxisoft-git commented 9 years ago

Да так будет ошибка ее можно побороть если ввести в класс template.php проверку на наличие тега nofilter и сделать вывод не обработанной переменной.

пример

$tpl = '<body>{'.$fragment.' nofilter}</body>';

тогда по факту не будет разбора переменной и она попадает в конечный шаблон такой какой и пришла.

Думаю такая реализация будет полезна для всех у кого json и не только.

Хотя из приведенной зарисовки

$fragment = $fenom->fetch("fragement.tpl");
...
// $fragment == '<script>var v =  {"a":1, "b":2};</script>'
$tpl = '<body>'.$fragment.'</body>';
$fenom->compileCode($tpl)->display($vars); // падает ибо {"a":1, "b":2} воспринимается как тег

ничего не мешает переменную окружить {ignore} и все будет работать - проверил все запустилось :), для меня всеж пока не понятно как вызывается злочастный шаблон который нельзя окружить {ignore} или то как вызывал я его в своем примере. Тут скорее всего нужно просить топик стартера привести всеже его вызов шаблонов.

litvinenkow commented 9 years ago

но есть риск замены в { строках json-на

конечно, такой реплейс наверное не покатит

bzick commented 9 years ago

Я раньше думал пойти другим путем, расширить {ignore} до возможности указывать что игнорить:

{set $a = 5}

{ignore}
var a = {$a}; 
var b = {a: 5};
{/ignore}
{* будет 
var a = {$a}; 
var b = {a: 5};
*}

{ignore tags} {* игнорим теги, но обрабатываем переменные*}
var a = {$a}; 
var b = {a: 5};
{/ignore}
{* будет 
var a = 5; 
var b = {a: 5};
*}
bzick commented 9 years ago

@maxicms это разве не то же что и $tpl = '<body>{ignore}'.$fragment.' {/ignore}</body>';

litvinenkow commented 9 years ago

как я понял проблему (грубая зарисовка)

абсолютно точно так и есть

но есть риск замены в { строках json-на

если json заэнкоденый через \u то скорее всего не будет, но вероятно

вот ваш последний вариант наверное самый правильный, я думаю есть много CMS где шаблоны прогоняются по несколько раз и рендерятся из кусков

maxisoft-git commented 9 years ago

@maxicms это разве не то же что и $tpl = '{ignore}'.$fragment.' {/ignore}';

:) да именно это и будет, не подумал сразу.

bzick commented 9 years ago

Я, конечно, не знаю что там за кусочность в шаблонах и надеялся что include/insert, макросы и наследования должны были помочь не парится по этому поводу

litvinenkow commented 9 years ago

Catchable fatal error: Object of class Closure could not be converted to string in \www\system\lib\Fenom\Fenom\Template.php on line 826

вот даже от такой функции на последней версии, перестало работать почему-то ( $fm->addModifier('json_encode_ignore', function ($var) { $result='{ignore}'.json_encode($var).'{/ignore}'; return $result; });

bzick commented 9 years ago

Исправил в 2.5.3