Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Snakeskin (https://javascript.ru/forum/project/35057-snakeskin.html)

yazonnile 02.03.2016 19:28

- namespace demo

- template myButton(@params)
 < .button
   {@value}

#{template myJS(foo)}
var a = {
  foo: 'bar'
  bla: #{1 + 2},
  baz: '#{foo ? "baz" : "bla"}'
};
#{/}


Вооооот! Вот это я искал. Спасибо. Пока решил на свой страх и риск начать его использовать в новом продже. И пока все классно :)
Ну, с вашими подсказками само собой.:lol:

Если вдруг нужна будет помощь в переводе на английский документации - рад буду помочь в меру времени

kobezzza 02.03.2016 19:41

Цитата:

Ну, с вашими подсказками само собой.
Без проблем :)

Цитата:

Если вдруг нужна будет помощь в переводе на английский документации
Это было бы шикарно :)

kobezzza 04.03.2016 17:03

Выпустил SS 7 beta 25. По мимо исправления ошибок также добавлен новый параметр pack, при включении которого шаблоны будут генерироваться для standalone сборки через WebPack, чтобы не прописывать дополнительные алиасы.

kobezzza 06.03.2016 20:50

Выпустил SS beta 27.

kobezzza 08.03.2016 21:38

Выпустил beta28.

Изменено поведение include: теперь если путь не глобальный и не начинается с указания контекста (./ или ../), то путь резолвится с node_modules. Также теперь если путь окончается на слеш или обратный слеш, то к пути подставляется правило: ?(dirname|main|index).ss

Добавлен плейсхоледер %dirName%. Принцип такой же как и у %fileName%.

foo/bar.ss
- namespace [%dirName%]

- template [%fileName%]()
  Hello!

yazonnile 10.03.2016 18:48

Задача.
Получить объект темплеитов из шаблона.

Решение 1.
SS.compileFile(fileSrc)
Все как надо, но создается файл с расширением js, который нужно постояно удалять.

Решение 2.
SS.compile(fileContent)
Возвращается string
Евалить, чтоли?) Или записывать в файл, который экспортирует обьект?

Есть вариант с объектом и чтобы файлы не создавались лишние?

yazonnile 10.03.2016 18:59

SS.exec(fileContent) возвращает только 1 метод.

kobezzza 10.03.2016 19:13

Цитата:

SS.compileFile(fileSrc)
Все как надо, но создается файл с расширением js, который нужно постояно удалять.
Дык файл создаётся для удобной отладки и как кеш, чтобы если шаблон не изменился при следующем запуске сразу взять скомпиленый. Ну да ладно.

Как я понял, ты хочешь получить просто объект со всеми шаблонами и с парсингом текста, а не файла.

Цитата:

SS.exec(fileContent) возвращает только 1 метод.
exec это просто надстройка над compile, которая всегда возвращает ссылку на главный шаблон. Поэтому смотрим исходный код https://github.com/SnakeskinTpl/Snak...keskin.js#L272

И то, что ты хочешь сделается вот так:

var ss = require('snakeskin');

var tpls = {};
ss.sompile('исходный шаблон', {context: tpls});

console.log(tpls); // Тут наши шаблоны :)


Но лично я предпочитаю юзать вебпак, чтобы просто рекваерить шаблоны.

yazonnile 10.03.2016 19:18

Цитата:

Сообщение от kobezzza (Сообщение 410591)
Дык файл создаётся для удобной отладки и как кеш, чтобы если шаблон не изменился при следующем запуске сразу взять скомпиленый

Наверное. Но сейчас именно такой кеис.


Цитата:

Сообщение от kobezzza (Сообщение 410591)
Но лично я предпочитаю юзать вебпак, чтобы просто рекваерить шаблоны.

Это уже внеконтекста вебпака. Просто на ноде решил посмотреть, сколько нужно телодвижений, чтобы получить объект шаблонов.

Спасибо)

yazonnile 14.03.2016 17:54

Привет!
Столкнулся с проблемой.

Есть такой шаблон

- namespace lalala

#{ template parent(@params) }
parent
#{/}

#{ template child(@params) extends parent }
child
#{/}


Ошибка
SnakeskinError: the specified template "parent" for inheritance is not defined;


Пример из документации тоже не работает
Вот этот

Вызываю через
const templates = ss.compileFile(
	path.resolve(__dirname, './../templates/index.ss')
);


В чем проблема, подскажите?
Доки под новый синтаксис не сделали или я что-то не так делаю?:-?

kobezzza 14.03.2016 19:22

Тут дело в том, что в СС7 появились неймспейсы, и при наследовании нужно указывать весь неймспейс целиком:

extends lalala.parent


Но, если шаблон наследования лежит в том же неймспейсе, что и базовый шаблон, то
можно проще:

extends @parent


Т.к. неймспейс создаёт неявный with блок с биндингом на себя.

Цитата:

Доки под новый синтаксис не сделали или я что-то не так делаю?
Над докой тружусь, но сильных различей между СС6 и СС7 в наследовании нет, поэтому можно юзать старую доку.

yazonnile 14.03.2016 19:25

О. Папка с тестами как всегда выручила :)
#{ template child(@params) extends @parent }


Собачку надо добавить :)

Цитата:

Сообщение от kobezzza (Сообщение 410966)
Над докой тружусь, но сильных различей между СС6 и СС7 в наследовании нет, поэтому можно юзать старую доку.

Спасибо.

kobezzza 14.03.2016 19:26

Цитата:

Собачку надо добавить
Если инклудится файл и там неймспейс другой, то нужно будет прописать весь неймспейс)

button.ss
- namespace ui.button

- template main()
  ...


super-button.ss
- include './button'
- namespace ui['super-button']

- template main() extends ui.button.main
  ...

yazonnile 15.03.2016 18:25

Привет.
Можете подсказать такую вроде не сложную вещину :) ?
задача глобальная - разбить все на микрочастицы, и комбинировать как хочется.

1.
Есть шаблон основной страницы
- namespace demo
- template layout.general(@params)
	- doctype
		< html
			< head
				< title
					{ @title }
				# style css
					.foo {}
				# script
					alert(1);
			< body
				< .hello
					Hello me!


2.
Есть модуль А
- namespace A

{ template html(@params) }
    < button
         { @buttonText }
{/ template }

#{ template styles(@params) }
#{ @buttonSelector } {
	background: #f00;
	outline: 0;
}
#{/}

#{ template scripts(@params) }
alert( #{@message} )
#{/}

{ template page(@params) }
???
{/ template }


Таких модулей может быть много.
Моя задача наследовать (может не совсем верная формулировка) каждый модуль от demo.layout.general
и на место стилей и скриптов в head ставить мои темплеиты.
Равно как и содержимое body также нужно заменить на A.html шаблон

Я пока себе не представляю, как это делается? При том, что мне нужно в каждый шаблон пробросить нужные переменные.

Т.е должно работать вроде как вот так
const a = ss.compileFile( path.resolve(__dirname, './../a.ss') );

a.page({
    message: 'Some alert message',
    buttonSelector: 'button.my-button',
    buttonText: 'Click me!',
    title: 'Кнопка же, ну'
});


Но я запутался с последовательностью.
Или в сторону block надо копать?

yazonnile 15.03.2016 18:29

Писать вот так не получается
< head
	< title
		{ @title }
	# style css
		{ block styles() }
			Hello world!
		{/ block }


Суть в том, что стили из шаблона А.styles мне будут нужны в двух видах.
Как здесь - внутри тега style
Так и как raw - чтобы вставить их в отдельный файл.

kobezzza 15.03.2016 18:45

Эммм, если я правильно понял, то есть мастер шаблон, и все остальные шаблоны должны от него наследоваться и заменять (или дополнять) некоторые его участки. Для этого будем использовать блоки и наследование.

base.ss

- namespace base

- template main()
  - doctype
  < html
    < head
      - block head
    < body
      - block body


child.ss

- namespace child
- include './base'

- template main() extends base.main
  - block head
    # style
      .foo { color: red }


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

- namespace child
- include './base'

- template main() extends base.main
  - block head
    - super
    # style
      .foo { color: red }

kobezzza 15.03.2016 18:56

Цитата:

Суть в том, что стили из шаблона А.styles мне будут нужны в двух видах.
Как здесь - внутри тега style
Так и как raw - чтобы вставить их в отдельный файл.
Всё просто, создаём шаблон со стилями и вызываем его внутри дочернего шаблона (шаблоны это просто функции, поэтому мы можем вызывать их внутри других шаблонов).

base.ss

- namespace base

- template main()
  - doctype
  < html
    < head
      - block head
    < body
      - block body


child.ss

- namespace child
- include './base'

#{template style()}

.foo { color: red }

#{/template}

- template main() extends base.main
  - block head
    - style
      += child.style() /// Или += @style() если не занят биндинг

yazonnile 15.03.2016 19:12

ой. Сработало.
Невнимательно переписал пример. Решетку убрать надо было.
А зачем она? Чем
# style
отличается от
- style
?

kobezzza 15.03.2016 19:20

Цитата:

Вот! То, что ищу, но оно не работает
Потому что вот здесь

# style


ты продекларировал расширенный синтаксис директив, вот тут

+= styles.test()


забыл про это и СС думает, что это просто текст :)

Исправь на

#+= styles.test()


А вообще в примере выше нет необходимость делать style через расширенный синтаксис, если всё что внутри неё будет - это просто вызов другого шаблона, т.к. расширенный синтаксис нужен если мы пишем текст, а тут просто вызов другого шаблона.

Цитата:

Или, к примеру, было бы ещё удобнее вот такая запись.
Как я понял, ты спрашиваешь возможно ли при вызове шаблона внутри другого шаблона передать ему подшаблон? Конечно можно :)

- template foo(content)
  < .wrapper
    {content}

- template bar()
  += foo()
    < .baz
      Hello world


Думаю смысл ясен :)

Если нужно передать несколько аргументов, то используем директиву putIn

- template foo(a, b, content1, content2)
  {a + b}
  < .wrapper1
    {content1}
  < .wrapper2
    {content2}

- template bar()
  += foo(1, 2)
      < .baz
        Hello world
    *
      < .bla
        Hello!


Больше примеров тут

yazonnile 15.03.2016 19:22

Это и спрашивал. Спасибо)
Пока все круто. Ну за исключением того, что сюда надо бегать за каждым чихом :)

kobezzza 15.03.2016 19:25

Цитата:

А зачем она? Чем
# style
отличается от
- style
Решётка декларирует расширенный синтаксис, это означает что все вложенные директивы должны также использовать его.

- template foo()
  # script
    var a = {}; /// Не будет ошибки т.к. мы используем расширенный синтаксис


Цитата:

Это и спрашивал. Спасибо)
Пока все круто. Ну за исключением того, что сюда надо бегать за каждым чихом
Зато когда освоишь СС то сможешь такие штуки писать, что закачаешься :)

trikadin 16.03.2016 02:33

Цитата:

Сообщение от kobezzza
Зато когда освоишь СС то сможешь такие штуки писать, что закачаешься

Яростно плюсую)

yazonnile 16.03.2016 15:25

Еще небольшой вопрос, если позволите.

< some
создаем тег some

- some
? простая директива?

# some
расширенная директива?


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

Например span.some
Сейчас использую вот так (класс вручную, а в переменной только класс)
< span (class = ${ @markup.spanClass })
    { @markup.spanText }


А вот так не получилось
< ${ @spanSelector }
	{ @markup.spanText }

Тк на выходе получал
<span.some>span text</span.some>

:))

{tag ${ @spanSelector }}
    Hello world
{/tag}

Результат тот же

kobezzza 16.03.2016 15:52

Цитата:

< some
создаем тег some
< - это сокращённый синтаксис для - tag, т.е.

- tag some


Даст такой же ответ. Сокращённые варианты есть лишь у некоторых директив и преследуют исключительно цель удобства написания

Цитата:

- some
? простая директива?
- обозначает, что следующий параметр будет имя директивы, но если директивы с таким именем нет, то будет использоваться либа директива output или global или const или decorator :) Т.е. всё зависи от контекста:

- template foo()
- var bla = 1
- bla /// 1
- bar = 2 /// создаст константу bar


Цитата:

# some
расширенная директива?
Расширенный синтаксис, его можно использовать с любой директивой и он просто означает, что все вложенные директивы должны использовать синтаксис #{ ... } и т.д. и это нужно, чтобы не было конфликтов с JS/CSS вставками, т.к. там используются блоки {}.

Цитата:

Например span.some
Сейчас использую вот так (класс вручную, а в переменной только класс)
Можно проще:

< span.${ @markup.spanClass }


И зачем взял в круглые скобки?

Цитата:

А вот так не получилось
< ${ @spanSelector }
    { @markup.spanText }


Тк на выходе получал
<span.some>span text</span.some>
Интерполяция в декларации тега требует, чтобы ты явно ставил разделитель класса, названия тега и ИД, например,

< ${tagName}#${idName}.${className1}.${className2}


Интерполяция также работает и при ручном задание атрибутов

< span ${attr1} = ${attrVal1}


А также можно использовать интерполяцию с объектом:

- var attrs = { foo: 1, bar: 2 }
< .foo ${attrs}

yazonnile 16.03.2016 16:03

Спасибо за подробное объяснение.

Т.е раскрыть строку span.some в тег с классом не выйдет?

kobezzza 16.03.2016 16:04

Цитата:

Т.е раскрыть строку span.some в тег с классом не выйдет?
- template foo(selector)
  /// Сокращение для - var
  : chunks = selector.split('.')
  < ${ chunks[0] }.${ chunks[1] }


Или более универсальный вариант (если классов много)

- template foo(selector)
  : chunks = selector.split('.')
  < ${ chunks[0] } сlass = ${ chunks.slice(1).join(' ') }

yazonnile 16.03.2016 16:06

И в догонку :)
Почему?

< span ${attr1} = ${attrVal1}
Но
< span
     {attr1} = {attrVal1}

kobezzza 16.03.2016 16:09

Цитата:

Почему?
Потому что, когда мы используем синтаксис управляющих пробелов каждая инструкция должна быть на 1-й строке, т.е. в твоём примере - это 2 разных инструкции, НО для того, что ты хочешь есть специальные операторы многострочного ввода:

< .foo &
  bla = 1 |
  baz = 2
.


Если использовать классический синтаксис, то это не нужно.

{< .foo
  bla = 1 |
  baz = 2
}{/}

kobezzza 16.03.2016 16:13

А стоп, не понял вопрос сначала. Ты спрашиваешь почему ${} и {}?

Потому что ${} - это синтаксис интерполяции, т.е. мы внутрь инструкции вставляем живые значения, а {} - это просто декларация директивы

< ${'foo'}
  {a} - {b}


Тоже самое на классическом синтаксисе

{< ${'foo'}}
  {a} - {b}
{/}


А разный синтаксис по 2-м причинам:

1) Визуальное отличие, чтобы не запутаться
2) Чтобы не было конфликтов с использованием {} блоков внутри директивы, например

/// <div class="foo" bla="{a: 1, b: 2}"></div>
< .foo bla = {a: 1, b: 2}

yazonnile 16.03.2016 16:18

Понял. спасибо!

Хорошего дня

yazonnile 22.03.2016 13:31

Привет. А есть возможность как-то задать путь для дефолтного ресолва модулей?
- include './templates/*.ss'
- include './../../__base/layouts'


Вторую строчку хотелось бы как-то красиво написать. Тк вложенность файла, что использует layout может быть разная.

kobezzza 22.03.2016 13:43

Привет!

Если такой кейз, то тут лучше всего использовать те же практике, что и в ноде: т.е. подключаем модуль path и вводим суперглобальные переменные (о них в доке можно почитать).

- import path from 'path'

/// .ss можно не писать - подставится автоматом
- include './templates/*' 
- include path.resolve(@@base, 'layouts')


Суперглобальную переменную можно задать как из самого СС файла:

- @@base = '...'


Так и из JS: параметр vars метода компиляции или просто

const ss = require('ss');
ss.Vars.base = '...';

kobezzza 22.03.2016 13:52

Можно сделать изящнее, заюзав фильтры:

const 
  ss = require('ss'),
  path = require('path');

ss.Filters.from = function (src, base) {
  return path.resolve(src, base);
};


- include './templates/*' 
- include './layouts'|from @@base

yazonnile 22.03.2016 14:38

Так и знал, что что-то есть. Спасибо в который раз :)

kobezzza 13.04.2016 18:24

Закончил раздел "учебник".

http://snakeskintpl.github.io/docs/guide.html#intro

kobezzza 13.04.2016 20:40

Выпустил beta.33

kobezzza 27.04.2016 23:28

Почти закончил документацию, думаю на майских праздниках добью.

kobezzza 14.05.2016 21:33

Закончил раздел документация, завтра буду собирать релиз СС7

kobezzza 15.05.2016 13:50

Свершилось! После 1.5 лет разработки, 2к+ коммитов, 35 бета релизов, множества сдвигов даты релиза :) и т.д. таки докатился до стейбла Snakeskin 7!

Было внесено огромное количество изменений, которые затронули как дизайн языка, так и его внутренности. Скажу откровенно: я очень горжусь этой работой :)

По своей сути, СС7 является результатом реинжиниринга СС6: многие вещи были сильно упрощены, например, больше нет прототипов, т.к. они полностью слились с вызываемыми блоками или больше нет костылей, чтобы передать при вызове функции ей подшаблон - теперь это делается с помощью всё тоже директивы call и т.д. Разрабатывая СС7 я стремился сделать его с одной стороны максимально простым, а с другой защитить пользователя от досадных ошибок, например, по этому были введены обязательные пространства имён и запрет на переопределение шаблона.

Кодовая база была значительно модифицирована: многие вещи переписаны с нуля, многие улучшены, а сам код полностью (включая модули) переписан на ES6, но по прежнему проходит максимально строгую проверку Google Closure Compiler. Также была улучшена интеграция JS и SS, теперь шаблоны полностью поддерживают: umd, amd, global, commonjs и native декларации, а для подключения JS в шаблоны введена директива import, которая повторяет функционал одноименного оператора в JS. Большое внимание уделено улучшениям отладчика, т.е. теперь сообщениями об ошибках более точные и подробные.

Также следует остановится на документации: она была полностью переписана, значительно расширена и выведена в отдельный проект для Github Pages. Сама документация написана на самом SS и это ещё одно доказательство зрелости и стабильности продукта. Но конечно работа по документации ещё не закончена и постепенно я буду дополнять разделы, примеры и переводить на английский.

Изменений очень много, поэтому проще читать доку, чем перечислять их тут :)

Но надо отметить, что CLI SS был вынесен в отдельный проект (snakeskin-cli) и пока не зарелизился (сегодня вечером планирую).

В общем поделился с вами радостной новостью :)

kobezzza 15.05.2016 16:32

Зарелизил https://github.com/SnakeskinTpl/snakeskin-cli


Часовой пояс GMT +3, время: 17:11.