Не нашёл в wiki, у snakeskin есть callback из скрипта, а ля Snakeskin(tpl, callback) или что-то типа Snakeskin.compile.then? Чтобы вызывался после активации DOM в шаблоне. callback в шаблоне не понял что делает.
Сейчас использую Snakeskin.hash[tplName] для рендеринга шаблона в DOM, так подключать нормально? в wiki тоже не нашёл описания про это. Использую es6, про это тоже в вики немногословно. Скомпиленные шаблоны подключены в header> menu.ss.js ... и т.д. Если я что-то не нашёл, то просьба ткнуть носом или пояснить. |
Не совсем понял, что ты хочешь сделать. Ты имеешь ввиду, можно ли, чтобы результат шаблона отдавался по колбеку, а не сразу?
Цитата:
foo.ss {template foo()} Hello World! {/} index.js console.log(foo()); // Hello World! Если не хочется писать в глобалспейс, то просто добавляем шаблону неймспейс, например tpls.foo Цитата:
{void foo(...args)} |
Цитата:
Типа как тут: insertTplIntoDOM('menu').then(function(){ //плавно скрываем первый элемент и уже точно известно, что элемент примонтирован и к нему есть доступ. }); //где 'menu' это Snakeskin.hash['menu'] В принципе у меня обертка есть, я просто подумал, может есть из коробки. Или меня уже глючит и все вставляемые элементы уже доступны мгновенно после innerHTML=tpl? Цитата:
а в скрипте Snakeskin.hash[tplName] - тут получаем доступ к шаблону Цитата:
{template tpls.foo()} Hello World! {/} Как вообще не писать в глобал? Snakeskin.hash[tplName] - это разве не локал? |
Цитата:
Цитата:
https://github.com/SnakeskinTpl/Snak...world.ss.js#L6 Вот тут можно глянуть код после компиляции и увидеть логику. Цитата:
Цитата:
{template foo()} {/} Тоже самое, что и function foo() { } А {template bar.foo()} {/} Тоже самое, что и if (typeof bar === 'undefined') { var bar = {}; } bar.foo = function foo() { }; Неймспейс может называться как угодно и иметь любую вложенность, можно использовать точечную и скобочную нотацию: логика идентичная с JS. {var fffuuu = 121} {template car.bar['someStr' + fffuuu]foo()} {/} Можно ставить шаблоны, как методы JS класса {template MyWidget.prototype.tpl()} {/} Цитата:
Ещё можно просто обернуть полученный JS код функций и задать нужный this. Для таких задач удобно использовать конвеер сборки gulp/grunt с плагином wrap. PS: отмечу, что в SS7 весь этот механизм значительно улучшен, например появилась поддержка runtime модулей и можно явно задать тип экспорта шаблонов. {@= export 'es6'} {import { getUserData } from './myLib.js'} {template foo() @async} {forEach await getUserData() => @el} {@name} - {@age} {/} {/} |
Цитата:
|
Одна из важнейших фич SS7 будет открытость API парсера, т.е. сам пользователь сможет расширять язык своими директивами и поэтому я потратил кучу времени на рефакторинг существующего API и в итоге получился на мой взгляд очень простой, но в тоже время мощный интерфейс, вот например директивы switch-case-default на новом API:
import { Snakeskin } from '../core'; Snakeskin.addDirective( 'switch', { block: true, notEmpty: true, inside: Snakeskin.group('case') }, function (command) { this.append($=> `switch (${this.out(command, {sys: true})}) {`); }, function () { this.append('}'); } ); Snakeskin.addDirective( 'case', { block: true, notEmpty: true, group: 'case', replacers: { '>': 'case ', '/>': 'end case' } }, function (command) { this.append($=> `case ${this.out(command, {sys: true})}: {`); }, function () { this.append('} break;'); } ); Snakeskin.addDirective( 'default', { block: true, group: 'case' }, function () { this.append('default: {'); }, function () { this.append('}'); } ); Как вам? |
Цитата:
Я пока из ss6 использую 40% и ума не приложу зачем мне больше, поэтому вряд ли буду полезен. Для меня главное дока и предсказуемое поведение, в остальном пиши хоть "справа налево". |
Как вставить код скрипта, вместе с тегами script в шаблон, чтобы парсер не ругался?
cdata, data, ругается, мол ошибка. Почему? |
Оо, нашёл. Честно говоря решётку не заметил, думал это коммент, автоматом воспринимаю в конфигах...
#{cdata} А тогда такой вопрос, а зачем тут решётка? Был хитрый план по на будущее? :) |
Цитата:
Логика простая: когда ты начинаешь юзать #{...} для декларации директивы, то все вложенные директивы также будут требовать такую декларацию, например: {template foo()} #{script} var a = { bar: #{1 + 2} }; #{/} {/} Цитата:
{template foo()} <input type="button" onclick="{data console.log({foo: 1})}"> {/} Цитата:
Цитата:
/// Однострочный коммент /* Многострочный коммент */ /** JSDoc (не вырезается парсером из конечного кода) */ Для создания XML комментариев есть удобная директива comment, которая также поддерживает условия для старых ИЕ. {template foo()} {comment IE 7} {link}http://bar.com/ie.css{/link} {/} {/} Но также можно просто писать по старинке :) PS: По поводу однострочных комментов: есть сильное желание заменить в SS7 на //# (или ещё как), т.к. сейчас можно напороться на ошибку при подключение некоторых урлов: <a href="file:///C://foo.png">121</a> Т.е. нужно явно экранировать: <a href="file://\/C://foo.png">121</a> Забавно, что я сделал коммент как /// чтобы не напарываться на такие ошибки с //, но не учёл, что урлы с тремя слешами тоже бывают :( |
У меня такой вопрос, я подключаю в node шаблон так:
var tpl = require('../tpl/menu.ss.js').init(require('snakeskin')); tpl.menu([{item: '', item: ''}]); Но если один и тот же шаблон подключается в двух разных файлах, то кидается ошибка. Это потому что подключение глобальное или почему? Как правильней организовать подключение шаблонов в проекте на сервере если шаблон используется в разных файлах? |
Не понял где ошибка, напиши подробнее.
|
Цитата:
menu.js но если так подключить в двух menu.js menu2.js То появляется ошибка. |
Проверил дома, действительно есть баг, сейчас сделаю патч.
UPD: патч 6.6.5 выложен в NPM, спасибо за репорт. |
Забыл сказать, что для исправления баги нужно перекомпилить шаблоны пропатченой версий SS.
|
kobezzza, я не совсем пойму как сделать, мне нужно сгенерить js файл через gulp
что в таком формате: require.config({ waitSeconds: 60, paths: <%= map.paths %>, shim: <%= map.shim %> }); я искал что то подобное в доке но не нашел, можно так? |
cyber, не совсем понял, что ты хочешь. Раз ты задаешь вопросы в треде SS, то ты хочешь понять, как сгенерить JS файл через SS и gulp?
config.ss # template config(@map) require.config({ waitSeconds: 60, paths: #{@paths|json}, shim: #{@shim|json} }); gulpfile.js var gulp = require('gulp'), ss = require('gulp-snakeskin') gulp.task('config', function () { gulp.src('./config.ss') .pipe(ss({exec: true, data: {paths: [ ... ], shim: [ ... ]}})) .pipe(gulp.dest('./config.js')); }); Как то так. |
Цитата:
Не получилось за юзать вебпак, так как ты писал, сильно много менять, приходится подстраивается под то что есть) |
Цитата:
Если нужна гибкая сборка файлов без привязки к языку или фреймворку, то рекомендую мой другой проект: https://github.com/MonicBuilder/Monic |
kobezzza, уже использую давно
https://github.com/cyberua/multiPopu...rc/popup.js#L8 |
а как экранировать вывод html кроме <br>? например: есть текст и в нем \n переносы строк, если написать так:
{content|br}, то вместо <br> мы получим <br> отэкранируются все символы, а нужно все, кроме <br> |
если написать так:
{content|br|!html}то получится натуральная XSS Что нужно написать в фильтр, чтобы не получить дыру в сайте и переводить строку? |
MakeMeFeel,
- block tpl->outputWithBr(text) : paragraphs = text.split('\n') - forEach paragraphs -> p {p} < br |
Ну и, соответственно, создаёшь темплейт tpl, где и юзаешь активно этот блок)
|
А правильно, конечно, вот так:
- block tpl->p(text) : paragraphs = text.split('\n') - forEach paragraphs -> p < p {p} |
trikadin,
это весь текст нужно отпарсить, что это за жесть? Сначала применяем фильтр на html, а затем грабли на перевод строки? Проще тогда дрюкать в браузере пользователя, чтобы сервер не упарывать. Механизма встроенного, порядка фильтров например, нету? типа как в php nl2br? , а и спасибо за пример. |
MakeMeFeel, эээм, в чём проблема? Где нужно отпарсить какой текст? Не понял тебя)
|
Цитата:
вместо записи: {content|nl2br} ты предложил писать весь твой код в блоке. Как минимум нужно запихать твой код в фильтр. Но мне интересно, есть ли встроенных nl2br? чтобы его не писать. Для меня странно, что его нет или я что-то упустил? Я уж не говорю о том, что ты навязываешь мне использование тега p |
Страннее всего, что нет html2br, экранировать всё, а переносы гнать в <br>
|
MakeMeFeel, если тебе принципиально сделать это фильтрами, то легко:
{text |html |replace '\n', '<br>' |!html} Но это плохой вариант. |
Цитата:
|
MakeMeFeel, при выводе текста разбить его на параграфы (<p>) гораздо разумнее -- потом можно задать параграфам стили, вроде отступа первой строки и какой-нибудь заглавной буквы, расстояние между параграфами и т. д. Плюс директива tag в snakeskin работает в DOM-режиме (когда шаблон компилируется непосредственно в DOM в браузере) лучше, т. к. сразу создаёт тег через createElement() , а вариант с replace, хоть и сработает в таком режиме, но будет хуже по производительности из-за юзания innerHTML и дополнительного разбора браузером.
|
Фич реквесты лучше оставлять на гитхабе, но ок, я добавлю такой фильтр в ближайшем минорном релизе SS6 на выходных.
Будет так: data|nl2br |
К тому же, может понадобиться сделать такую операцию не с одним текстом на странице, а с двумя разными -- и тут тоже гораздо логичнее сделать что-то типа callBlock p(text1), callBlock p(text2).
|
Цитата:
Цитата:
|
trikadin,
У меня блоки короткие и плодить в них p, ничего не даст. Один, два переноса. |
Гораздо важнее поменьше кода, т.к. шаблоны и так уже довольно сложные и дополнительная логика в блоках уже начинает напрягать. А также хочется такую фичу из коробки, т.к. она и работать будет побыстрее.
kobezzza, только если можно не забыть, что остальной части данных html фильтр должен работать :) |
Цитата:
|
Забыл тут написать, что вышел очередной релиз SS ветки 6. В основном багфиксы. Добавлен фильтр nl2br.
|
Я тут новый язык шаблонов для юишки пилю, как вам пасоны? как джейд тока круче, больше придется добавлять префиксы к кастомным атрибутам так как при компиляции движок поймет что раз есть директива с таким именем то значит надо при превращении в html добавить префикс)) ну грубо говоря.
и вот в фотошопе подсветочку примерную нарисовал чтобы вы понимали структуру, все атрибуты желтые а точ то до конца строки это просто значение атрибута, строковое, а то как его парсить будет уже решать сам атрибут, ну все как в ангуляре ![]() А вот как бы это было написано на jade например ![]() Правда еще префиксы надо добавлять чтобы не было конфликта с обычными атрибутами (вдруг потом в html10 атрибут repeat добавят), вот так щас приходится писать в jade: ![]() СРАВНИТЕ ВОТ С ЭТИМ: ![]() Плюс, раз уж я буду писать плагин для подсветки синтаксиса то потом вполне научу идешку подсвечивать атрибуты которые кастомные каким-то особым цветом. кстати messages in Message или message in @messages это обычные строки синтаксис которых не определен, там могло быть написано хоть "апывавпаав 434 334 34 34", и директива repeat или range например должна была бы быраспарсить эту строгу и выдернуть нужное) как щас она делает со строкой message in @messages создатель директивы сам решает че туда передавать и в каком формате, но я заготовил пару парсеров для выражений через запятую типа name, 1+2, 33 он распарсит эту строку в массив, ну парсинг частого выражения name as val in arr которое во всяких итераторах используется тоже добавил, можно будет свои пресеты выражений создавать и вообще я думаю это дело как-то стандартизировать чтобы потом можно было подсветку выражений организовывать. все таки это же не просто строки а какой то код и он чето делает. потому шо я могу организовать подсветку в подстановках {{1+2}} потому что там банальный кофескрипт. А вот строку которую мы в атрибут передаем, которая тоже мини логику несет, я как то не стандартизировал. А еще я хочу добавить че-то типа дубликатов атрибутов, ну знаете часто хочется это сделать в коде ![]() И будет например если дублируется обычный атрибут то при рендере все значения просто сложатся и разделятся пробелом ну в случае с class например пригодится. А если же это кастомный какой-то атрибут то я хочу чтобы туда какая-то функция вызывалась чтоле, то есть чтобы он конструировался один раз, но какая то функция типа init вызывалась несколько раз с разными значениями)) удобно? Удобно. Например кастомный атрибут add-class будет парсить строку регуляркой типа вначале слово название класса, потом двоеточие, а потом до конца строки выражение которое будет отслеживаться в скоупе на изменения и.т.п. и вот эта логика опишется в функции init и эта функция вызовится несколько раз с разными значениями атрибута) Ребят по моему это вообще прорыв и это самый лучший шаблонизатор который я видел. Кто знает как на атрибутах красиво сделать свитч? я вот уже 3 года не знаю как придумать))). Или раз уж у нас свой синтаксис теперь то может какую нить хитрую конструкцию придумаем? А еще думаю может чето типа таких логическх псевдоблоков запилить? а то логику в атрибутах элементов не всегда удобно писать. когда что то вроде "примени для этого элемента эту штуку" да, самое то, типа как настройки элемента. но когда это логика связанная именно С РАЗМЕТКОЙ карл. Тут нужно что-то ВНЕ блоков. ![]() Че думаете? А при рендеринге я буду рендерить это в какие-то хитрые html комментарии которые че-то делают. Ну или вот лучше так, вначале реализую стандартные компоненты которые логику реализуют, а потом шаблон просто буду вн их компилить, шаблон вообще это сахар по сути над декларативным html и все что мы пишем в шаблоне должно быть можно написать без шаблона используя чистый html (ну в данном случае я для простоты на джейде написал пример) ![]() То есть текущий API уже позволяет реализовать такую логику, просто ужасно смотрится по этому я и не делал такое, но по сколкьу пилим шаблонизатор... ;) п.с. на самом деле шаблонизатор будет препроцессором, и будет на выходе выдавать обычный html который мы бы могли руками написать) это сделано чтобы не повышать порог вхождения во фреймворк и любая даша не знающая про прероцессоры могла начать пилить сайтики А вообще, по скольку я создам компоненты на все свойства которые есть в style тогда можно будет писать вот так ![]() и это вообще сказка) прям как в css прикиньте)) тока динамически подвязка к яваскрипту. при компиляии заменится на уже работающие сейчас <ul class='ui-chat ui-button ui-text' style-position='absolute' style-width='100px' style-height='{{@height}}px'> |
Часовой пояс GMT +3, время: 21:21. |