Я уже на высшие силу грешу, вот блин всё вроде верно указано: нода определяется, bin прописан, sha-bang есть... что ему ещё надо то? Ух, тяжело мне виндузятнику.
|
kobezzza, перепроверь окончания строк.
Код:
root@4ce0735a160c:/# echo $SSЦитата:
Код:
вывожу в консоль NODE_ENV: Код:
vagrant@vagrant-ubuntu-trusty-64:/vagrant.sync$ echo $NODE_ENVКод:
vagrant@vagrant-ubuntu-trusty-64:/vagrant.sync$ nodejs -e "console.log(process.env.NODE_ENV === 'development')"я долгое время ломал голову, пока не догнал: Код:
vagrant@vagrant-ubuntu-trusty-64:/vagrant.sync$ echo "<<<$NODE_ENV>>>"после этого добавил в .editorconfig: Код:
[.env-dev] |
Цитата:
Кажется я понял, действительно, в Sha-Bang у меня строка закансивается на \r\n и поэтому не видится нода! Твою же мать за ногу!!! Пойду поем и буду фиксить) |
Цитата:
держи скринкаст в нём я поменял окончания строк в файле бинарника через VIM и всё заработало ![]() |
Огромное спасибо! Я бы никогда не подумал, что ошибка кроется в такой ерунде! :)
Я решил что сделаю так: заводить конфиг для редактора мне кажется лишним, а добавлю Gulp-таск, который будет конвертить всё в \n, потом публиковать в NPM, а потом конвертить обратно в родное для ОС значение, т.е. вместо npm pub я буду делать gulp pub |
Выкатил релиз, должно всё работать, спасибо огромное Gozar и melky за локализацию и помощь в устранении этой баги :)
gulp.task('pub', function () {
gulp.src('./bin/*.js')
.pipe(eol('\n'))
.pipe(gulp.dest('./bin'))
.on('end', function () {
run('npm pub').exec(undefined, function () {
gulp.src('./bin/*.js')
.pipe(eol())
.pipe(gulp.dest('./bin'));
});
});
});
Вот такой вот таск вышел. |
Цитата:
snakeskin -s head.ss -o head.ss.js
или
snakeskin -s ./head.ss -o ./head.ss.js
fs.js:642
return binding.mkdir(pathModule._makeLong(path),
^
Error: ENOENT, no such file or directory ''
at Object.fs.mkdirSync (fs.js:642:18)
at /usr/lib/node_modules/snakeskin/bin/snakeskin.js:191:7
at Array.forEach (native)
at testDir (/usr/lib/node_modules/snakeskin/bin/snakeskin.js:187:64)
at action (/usr/lib/node_modules/snakeskin/bin/snakeskin.js:268:3)
at Object.<anonymous> (/usr/lib/node_modules/snakeskin/bin/snakeskin.js:510:4)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
запуск в папке в которой находится файл head.ss |
Исправлено, был очередной привет из Линуха.
Кстати, почему ты используешь -s для задания файла-шаблона, ведь гораздо удобнее просто использовать: snakeskin путь к файлу или текст файла Можно использовать также с потоками ввода/вывода. |
Цитата:
|
Цитата:
|
Цитата:
А в нормальной консоли это не нужно, хотя дело твоё. https://github.com/kobezzza/Snakeski...0%BE%D0%B5-API Тут описаны все возможные кейсы использования CLI. |
Цитата:
|
snakeskin.compileFile как смотрел от корня проекта, так и смотрит, а не как require в node относительно текущего места.
|
require('../tpl/header.ss').init(require('snakeskin'));
выдает вот такую забавную ошибку:
/server/app/tpl/header.ss:1
ction (exports, require, module, __filename, __dirname) { {template head(title
^^^^
SyntaxError: Unexpected identifier
at Module._compile (module.js:439:25)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (/server/app/modules/login.js:4:14)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
При подключении скомпиленного шаблона. Что-то я совсем не догоняю. Подключаю require('../tpl/header.ss'), но ведь это просто обёрнутая функция, там нет module.exports. Как тогда прекомпилить, если оно его не подхватит через require? |
Цитата:
https://github.com/kobezzza/Snakeski...keskin.js#L110 Вот тут видно, что при резолвинге URL используется позиция родителя. ***
require('../tpl/header.ss.js').init(require('snakeskin'));
При таком подключении нужно подключать скомпиленый файл, а не файл-шаблонов. https://github.com/kobezzza/Snakeski...oworld.node.js Вот тут пример. Вот пример скомпиленого файла. https://github.com/kobezzza/Snakeski...lloworld.ss.js. Цитата:
|
Цитата:
У меня вопрос. Можно ли такое сделать и сразу еще вопрос правильно ли так делать? Есть файл html.ss
{template html(head, body)}
<!doctype html>
<html lang="ru">
{head}
{body}
</html>
{/template}
head и body отдельные файлы head.ss, body.ss Читал про proto, но догнать не могу, как написать шаблоны и подключить правильно в nodejs? Можно пример? В файле index.js :
var snakeskin = require('snakeskin');
var html = require('../tpl/html.ss.js').init(snakeskin);
var head = require('../tpl/head.ss.js').init(snakeskin);
var body = require('../tpl/body.ss.js').init(snakeskin);
html.html(head, body);
Далее мозг ломается... |
Чёто тебя в странную степь понесло, ну да ладно.
1) Во первых (на всякий случай) в файле можно объявлять сколько угодно шаблонов, а не только один (этим SS принципиально отличается от того же Jade)
{template foo()}
...
{/}
{template bar()}
...
{/}
/// Можем использовать неймспейсы
{template some.foo.bar()}
...
{/}
2) Во вторых (тоже на всякий случай) в файл шаблона можно подключать другие файлы
{include 'myFile.ss'}
{include 'tpls/*.ss'}
/// Можно даже так
{eval}
{forEach ['foo.ss', 'bar.ss'] => url}
{include url}
{/}
{/}
{template foo()}
...
{/}
А в JS вызывать один главный файл. 3) Как ты хочешь тоже можно, но я опишу самый лучший кейз - это использование наследования. Чтобы понять наследование в SS, то нужно просто привыкнуть к той мысле, что шаблон - это класс (в вики этому посвящён целый раздел). Я всегда для начала завожу абстрактный шаблон, от которого потом будут наследоваться другие и определяют там базис и базисные методы. base.ss
{template base(@params)}
{doctype}
<html>
<head>
{block head}
/// Подключим базовые стили и скрипты
{block script}
{script js src = base.js}{/}
{/}
{block style}
{link css}base.css{/}
{/}
{/block}
</head>
<body>
{block body}
{/block}
</body>
</html>
{/template}
Далее создают, например, profile.ss
{include 'base.ss'}
/// Наследуемся от базового шаблона и доопределяем / переопределяем структуру (это блоки, прототипы. константы и т.д.)
{template profile(params) extends base}
{block script}
{super}
{script js src = profile.js}{/}
{/}
{block style}
{super}
{link css}profile.css{/}
{/}
{block body}
<div class="foo">
...
</div>
{/}
{/template}
И т.д. уровень наследования не ограничен и не нужно боятся его использовать, т.к. на скорость конечно шаблона это вообще никак не повлияет. Теперь про термины в наследовании: 1) Блоки (те, что я использовал в примере) - это как свойства класса, которые можно переопределить или доопределить в дочернем классе. 2) Константы и входные параметры - это свойства, которые можно также изменять при наследовании; 3) Прототипы - это протектед методы класса; 4) Вызываемые блоки - это публичные методы класса. PS: В примере я использовал параметр с @ - это сахар для with биндинга, https://github.com/kobezzza/Snakeskin/wiki/with |
Да, да, то, что нужно. Конечно же мне подойдет наследование. Встроенный механизм хорошо.
|
Цитата:
Чтобы заюзать его на полную катушку, то обязательно прочитай про константы: https://github.com/kobezzza/Snakeskin/wiki/const Затем про блоки и прототипы (16-я глава). А потом про наследование (18-я глава). Например, я также на разных уровнях наследования определяю методы:
/// Можно объявлять как вне шаблона
{proto foo->getLogo(style)}
...
{/}
{block foo->getTitle()}
...
{/}
{template foo()}
/// Так и внутри
{proto getFavicon(style)}
...
{/}
{/}
Их также можно выносить в отдельный файл. Как ты уже наверное догадался, эти методы также наследуются и их можно переопределять и доопределять. Для вызова этих методов используется apply (для прототипов) и callBlock (для блоков).
{block bar->getTitle()}
{super} /// super - это вызов тела родителя
...
{/}
{template bar() extends foo}
{apply getStyle('dark')}
{/}
Внутри блоков/прототипов можно определять другие блоки/прототипы и так до бесконечности :) |
html.ss
{template html(@params)}
{doctype}
<html lang="ru">
<head>
{block head}
{block meta(title, kwd, des)}
<meta charset="UTF-8">
<title>{title}</title>
<meta name="keywords" content="{kwd}">
<meta name="description" content="{des}">
{/}
{block style}
{super}
{/}
{block script}
{super}
{/}
{/block}
</head>
<body>
{block body}
{/block}
</body>
</html>
{/template}
От него наследуется main.ss:
{include 'html.ss'}
{template main(params) extends html}
{block meta(title, kwd, des)}
{super}
{/}
{block style}
{super}
{link css}/css/style.css{/}
{/}
{block script}
{super}
{script js src = /js/lib/react.js}{/}
{script js src = /js/lib/shim.js}{/}
{/}
{block body}
{/}
{/template}
В ноде подключаем
var tpl = require('../tpl/main.ss.js').init(require('snakeskin'));
//а как вызывать?
tpl.html(); //работает
//как передать title, kwd, des?
как передать title, kwd, des?
var html = tpl.html().main().head.meta('Заголовок', 'ключевые, слова', 'Много Текста Описания');
Не фурыкает. Доку тоже рыл, не могу найти. |
В общем буду постить в этот коммент. Удалось таки запустить наследование...
html.ss
{template html(@param)}
{doctype}
<html lang="ru">
<head>
{block head}
{block meta}
<meta charset="UTF-8">
<title>{param.title}</title>
<meta name="keywords" content="{param.meta_kwd}">
<meta name="description" content="{param.meta_des}">
{/}
{block style}
{/}
{block script}
{/}
{/block}
</head>
<body>
{block body}
{/block}
</body>
</html>
{/template}
main.ss
{include 'html.ss'}
{template main(param) extends html}
{block style}
{super}
{link css}/css/style.css{/}
{/}
{block script}
{super}
{script js src = /js/lib/react.js}{/}
{script js src = /js/lib/shim.js}{/}
{/}
{block body}
{super}
<div class="wrap">{param.title}</div>
{/}
{/template}
вызов:
var tpl = require('../tpl/main.ss.js').init(require('snakeskin'));
var html = tpl.main({title:'Заголовок', meta_kwd:'ключевые, слова', meta_des: 'Много Текста Описания'});
Как можно заметить в main мы не вызываем напрямую {block head}: {block head}{super}{/} Он сам вызовется. В main мы просто дополняем блоки нужными нам данными. Причем место значения не имеет, можно хоть сначала написать {block body}, а в конце {block style}. Выводиться будет в порядке обозначенном в html.ss. |
kobezzza,
Советую добавить это пример как основной, чтобы люди себе мозг не трахали. Ты изобрел язык, а описание к нему очень скудное и не очевидное. Добавь вызовы, с передачей параметров, к примерам шаблонов. Вся очень просто, только когда знаешь. Сейчас справка читается как псевдокод. |
Ещё такой вопрос.
Данные в базе я храню с переносами строки \n, а при выводе нужно заменить на <br>. В snakeskin есть встроенный механизм замены? Флаг или ещё что-то? Если нет, то чтобы не экранировало <br> использовать https://github.com/kobezzza/Snakeskin/wiki/data ? |
Цитата:
Цитата:
*** А почему ты пишешь param.title Ты же забиндил параметр param c помощью with https://github.com/kobezzza/Snakeskin/wiki/with Т.е. ты можешь писать просто @title Цитата:
{template some(param1)}
{param1.replace(/\n/, '<br>')|!html}
{/}
Если я прав, то почитай главу (там кстати видео ещё есть) https://github.com/kobezzza/Snakeski...80%D0%BE%D0%B2 https://github.com/kobezzza/Snakeski...BD%D0%B8%D0%B9 Ещё про output и call почитай. Тем ни менее в базовом пакете фильтров такого фильтра нет, но его очень легко добавить самому, с другой стороны такой фильтр может есть смысл добавить из коробки, я подумаю над этим, спасибо. PS: извини за долгий ответ, вчера был на тусе, а сегодня бошка трещит :( |
Ещё обратил внимание, что в твоём примере
{block body}
{super}
<div class="wrap">{param.title}</div>
{/}
Тут этот super не особо нужен, т.к. в родительском блоке ничего нет. Super в SS тоже самое что в ES6 и других языках с классами, т.е. просто вызов родителя и если его не использовать, то дочерний блок просто заменить родительскую реализацию, также следует отметить что super не обязательно должен быть в начале, т.е. можно вставить его в конец или середину и т.д. и это будет ожидаемо влиять на конечный код шаблона. |
как бы заюзать SnakeSkin вместе с React?
как это сделать сначала шаблон компилим в HTML, а потом HTML в VDOM реакта? |
Цитата:
__RESULT__ += '<!DOCTYPE html>'; __RESULT__ += '<html lang="ru"> <head> '; __RESULT__ += '<meta charset="UTF-8"> <title>'; __RESULT__ += __FILTERS__.html(__FILTERS__.undef(param.title), false, false); __RESULT__ += '</title> <meta name="keywords" content="'; __RESULT__ += __FILTERS__.html(__FILTERS__.undef(param.meta_kwd), true, false); __RESULT__ += '"> <meta name="description" content="'; __RESULT__ += __FILTERS__.html(__FILTERS__.undef(param.meta_des), true, false); __RESULT__ += '"> '; |
Цитата:
Цитата:
|
Цитата:
Цитата:
Цитата:
|
Цитата:
|
Цитата:
|
kobezzza,
А может шаблон собираться из разных файлов. html.ss
{template html(@param)}
{/}
header.ss
{template header(@param)}
{/}
main.ss
{include 'html.ss'}
{include 'header.ss'}
{template main(param) extends html}
{block header}
{super}
{/}
{/template}
Или только proto и apply? |
Конечно, такой приём по аналогии с классическими языками (от слова класс) называется "композицией". Самый удобный способ сделать это - это использовать директиву call.
{template foo(a, b)}
{a + b}
{/}
{template bar()}
{call foo(1, 2)} /// 3
{/}
Цитата:
Это уже вопросы архитектуры, лично я стараюсь отдавать предпочтение наследованию, т.к. в таком случае архитектура более управляемая и ясная, а композицию могу использовать, где она явно напрашивается. |
Цитата:
|
Цитата:
|
kobezzza,
Пару вопросов. 1. proto может быть только один? 2. block или blocks? В чем отличия или это опечатка? Цитата:
Цитата:
{@des|br|!html}
Фильтры клева. Немного чудно, что !html отменяет html, который задается неявно, но клева :) |
Цитата:
{proto foo->some(a, b)}
{a + b}
{/}
{template foo()}
{proto bar(a)}
{a * 2}
{/}
{apply some(1, 2)} /// 3
{apply bar(2)} /// 4
{/}
Цитата:
Цитата:
Следует помнить, что фильтры можно применять почти в любых директивах, т.е. этот механизм пронизывает всю шаблонку.
{var a = ' fooo '|trim}
{if ' fooo '|trim}
и т.д. Если нужно наложить фильтр на определённую часть выражения, а не на всю, то нужно выделить её скобками.
{var a = (' ffffuuu '|trim) + ' bar '}
Но фильтр !html можно применять только глобально. PS: на меня тут гора дел навалилась, поэтому не смог сделать релиз как обещал :( Буду стараться к концу этой недели сделать. |
Цитата:
|
Цитата:
Вот сделал примерчик, где идёт использование прототипов при наследовании, причём один из прототипов переопределяется. http://jsfiddle.net/NAPWB/15/ PS: хороший пример возможных вариантов использования можно глянуть в тестах, для прототипов, например, https://github.com/kobezzza/Snakeski.../test/proto.ss https://github.com/kobezzza/Snakeski...test/proto2.ss (шаблоны расположены между ###, а остальное данные для тестового скрипта) |
Цитата:
{template html(@param)}
<html>
<body>
{block body}
{proto des(@des)}
<div class="des">{@des}</div>
{/proto}
{/block}
</body>
</html>
{/template}
test.ss
{include 'test_html.ss'}
{template main(param) extends html}
{block body}
<div class="wrap">
{apply des()}
</div>
{/}
{/template}
des + <div class="des"></div> нет ни в test_html.ss.js ни в test.ss.js. То есть он не компилится. |
| Часовой пояс GMT +3, время: 12:54. |