Hastache 0.6.0. Новый мейнтейнер

Апрель 01, 2014, 15:30

Вы­шла но­вая вер­сия has­tache 0.6.0. Са­мое за­мет­ное из­ме­не­ние — пе­ре­ход от ис­поль­зо­ва­ния ByteString к ис­поль­зо­ва­нию Text.

А са­мое за­мет­ное из­ме­не­ние для меня са­мо­го в том, что те­перь у has­tache но­вый мейн­тей­нер, ко­то­рый вот эту но­вую вер­сию и вы­пу­стил. Это Dani­il Fru­min. Я ото­шел от раз­ра­бот­ки has­tache про­сто по при­чине от­сут­ствия у меня ак­тив­ных про­ек­тов с его ис­поль­зо­ва­ни­ем, а лю­дям надо, кто-то поль­зу­ет­ся, вот Dani­il и по­про­сил­ся на эту роль. Те­перь у меня та­кое стран­ное чув­ство по это­му по­во­ду. С од­ной сто­ро­ны при­ят­но, что там что-то та­кое на­пи­сал, а вот те­перь оно со­всем сво­ей жиз­нью за­жи­ло. С дру­гой сто­ро­ны, эх вре­ме­ни бы мне немно­го сво­бод­но­го, сесть и пе­ре­пи­сать все со­всем по дру­го­му, по пра­виль­но­му, API мож­но еще немно­го обоб­щить, пар­сер пе­ре­пи­сать...

Доступ к элементам списка по номеру в Hastache

Июль 12, 2012, 09:00

Это ко­неч­но очень при­ят­но ко­гда что-то по­лез­ное де­ла­ешь. Поль­зо­ва­те­лей Has­tache в мире мо­жет и не очень мно­го, но они точ­но есть. Вот недав­но Chris­ti­aan Baaij при­слал со­об­ще­ние о функ­ции ко­то­рая есть во мно­гих ре­а­ли­за­ци­ях шаб­ло­ни­за­то­ра Mus­tache, а в Has­tache нет. Это об­ра­ще­ние к эле­мен­там спис­ка по но­ме­ру, т.е. как-то так:

{{heroes.1.name}}
{{heroes.0.name}}

По­лез­ная шту­ка, мне ни разу пока не при­го­ди­лась (по­это­му и не сде­лал), од­на­ко лег­ко мож­но при­ду­мать ей при­ме­не­ние и кому-то та­кое точ­но по­на­до­бит­ся.

Поль­зо­вать­ся так:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/local/bin/runhaskell
{-# LANGUAGE DeriveDataTypeable #-}
import Text.Hastache
import Text.Hastache.Context
import qualified Data.ByteString.Lazy as LZ
import Data.Data
import Data.Generics

main = mapM_ (\(template,context) ->
hastacheStr defaultConfig (encodeStr template) context >>= LZ.putStrLn)
[(template1, mkStrContext context1),
(template1, context2),
(template3, context3)]

names = ["Безымянный","Небо","Сломанный Меч","Летящий Снег","Цинь Шихуанди"]

template1 = concat [
"{{heroes.1.name}}\n",
"{{heroes.0.name}}\n"]

-- Руками написанный контекст в виде функции
context1 "heroes" = MuList $ map (mkStrContext . mkListContext) names where
mkListContext name = \"name" -> MuVariable name
context1 _ = MuNothing

-- Контекст с помощью Generics
data Hero = Hero { name :: String } deriving (Data, Typeable)
data Heroes = Heroes { heroes :: [Hero] } deriving (Data, Typeable)

context2 = mkGenericContext $ Heroes $ map Hero names

-- Контекст с помощью Generics (другой вариант)
template3 = concat [
"{{heroName.3}}\n",
"{{heroName.2}}\n"]

data HeroesStr = HeroesStr { heroName :: [String] } deriving (Data, Typeable)

context3 = mkGenericContext $ HeroesStr names

Ре­зуль­тат:

Небо
Безымянный

Небо
Безымянный

Летящий Снег
Сломанный Меч

Примеры использования Hastache

Ноябрь 14, 2011, 11:30

Вы­ло­жил при­ме­ров для has­tache: README.md (этот файл, кста­ти, хаста­шем же и со­би­ра­ет­ся — mkReadme.hs). Эти же при­ме­ры рос­сы­пью фай­лов: ex­am­ples.

Hastache растёт и развивается

Ноябрь 08, 2011, 11:20

Но­во­сти хаста­ше­стро­е­ния:

Во-пер­вых, Akaspin при­слал по­лез­ный патч, поз­во­ля­ю­щий с по­мо­щью mk­Gener­ic­Con­text со­зда­вать кон­тек­сты для ти­пов с по­ля­ми Mona­dIO m => (Byte)String -> m (Byte)String, за что ему вы­да­ёт­ся оче­ред­ной плюс в кар­му. Сам я о та­кой воз­мож­но­сти ду­мал, но не оси­лил, ура опен­сор­су. При­мер ис­поль­зо­ва­ния тут.

Во-вто­рых, я обоб­щил кон­струк­тор Mu­Lamb­da до Mu­Var a => Mu­Lamb­da (ByteString -> a), рань­ше мож­но было толь­ко ByteString воз­вра­щать, а те­перь лю­бой тип, для ко­то­ро­го есть ин­станс клас­са Mu­Var. Удоб­но, как-то я рань­ше не со­об­ра­зил так сде­лать.

В-тре­тьих, Сам Bryan O'Sul­li­van (один из ав­то­ров кни­ги Real World Haskell), при­слал неболь­шой патч для has­tache и по­со­ве­то­вал ис­поль­зо­вать blaze-builder для за­пи­си ре­зуль­та­та ра­бо­ты шаб­ло­ни­за­то­ра. Blaze-builder пред­на­зна­чен для ге­не­ра­ции Lazy ByteString с кон­тро­лем ми­ни­маль­но­го раз­ме­ра фраг­мен­тов этой стро­ки. За счет это­го до­сти­га­ет­ся су­ще­ствен­ное уве­ли­че­ние ско­ро­сти даль­ней­шей ра­бо­ты с этой стро­кой. Вме­сто кучи мел­ких бло­ков (а имен­но так и по­лу­ча­ет­ся при ра­бо­те has­tache), име­ем несколь­ко круп­ных, ко­то­рые, к при­ме­ру, по сети уедут быст­рее (за счет ми­ни­ми­за­ции ко­ли­че­ства си­стем­ных вы­зо­вов). Так что те­перь и обыч­ный ре­зуль­тат has­tache со­сто­ит из удоб­ных круп­ных бло­ков внут­ри Lazy ByteString, и, та­к­же, мож­но по­лу­чить непо­сред­ствен­но объ­ект Builder биб­лио­те­ки blaze-builder и даль­ше уже ра­бо­тать пря­мо с ним.

Hastache — вложенные контексты

Октябрь 12, 2011, 12:19

Akaspin за­ре­пор­тил один непри­ят­ный баг в has­tache, за что ему вы­ра­жа­ет­ся вся­че­ская бла­го­дар­ность с за­не­се­ни­ем в кар­му. Про­бле­ма за­клю­ча­лась в том, что до­ста­точ­но ча­сто нуж­но иметь воз­мож­ность об­ра­тить­ся из вло­жен­но­го бло­ка шаб­ло­на к пе­ре­мен­ной опре­де­лен­ной где-то выше в иерар­хии кон­тек­стов. В ори­ги­наль­ном Mus­tache та­кая функ­ция есть, а я это дело бла­го­по­луч­но про­во­ро­нил. Ис­прав­ля­юсь. Мож­но по­чи­тать по­дроб­но­сти, и по­смот­реть ещё один при­мер из те­стов.

Новая версия hastache

Октябрь 09, 2011, 11:34

Вы­ло­жил но­вую вер­сию шаб­ло­ни­за­то­ра has­tache. До­ба­вил воз­мож­ность ге­не­ри­ро­вать кон­текст из ти­пов со­дер­жа­щих функ­ции типа String -> String и ByteString -> ByteString. Смот­ри­те при­мер ис­поль­зо­ва­ния кому ин­те­рес­но.

Hastache — реализация Mustache для Haskell

Март 28, 2011, 07:00

До­вел до ума и вы­ло­жил в open source свою ре­а­ли­за­ция шаб­ло­ни­за­то­ра Mus­tache, на ко­то­рой, в част­но­сти, кру­тит­ся сайт с ко­то­ро­го вы это сей­час чи­та­е­те.

Взять мож­но либо на GitHub, либо из Hack­ageDB:

(далее...)

Шаблоны Mustache

Март 25, 2011, 08:05

Mus­tache — биб­лио­те­ка ми­ни­ма­ли­стич­ных шаб­ло­нов из­на­чаль­но ре­а­ли­зо­ван­ная для Ruby Кри­сом Ван­стра­сом (меж­ду про­чим CEO и один из ос­но­ва­те­лей GitHub). Ми­ни­ма­лизм Mus­tache вы­ра­жа­ет­ся в том, что там нет управ­ля­ю­щих кон­струк­ций вро­де if и else. Цик­лов там тоже нет, есть толь­ко теги. Неко­то­рые теги за­ме­ня­ют­ся про­сты­ми зна­че­ни­я­ми, неко­то­рые за­ме­ня­ют­ся се­ри­я­ми зна­че­ний, по­каз со­дер­жи­мо­го дру­гих за­ви­сит от опре­де­лен­ных усло­вий. Несмот­ря на весь ас­ке­тизм сво­е­го син­так­си­са, Mus­tache яв­ля­ет­ся мощ­ным и пол­но­цен­ным движ­ком шаб­ло­нов.

Вдох­но­ви­те­ля­ми Mus­tache по­слу­жи­ли ctem­plate и et.

Сей­час су­ще­ству­ют ре­а­ли­за­ции Mus­tache для огром­но­го ко­ли­че­ства язы­ков. Необ­хо­ди­мо учи­ты­вать что на раз­ных язы­ках ню­ан­сы ра­бо­ты бу­дут немно­го от­ли­чат­ся. Я сде­лаю об­зор без при­вяз­ки к кон­крет­но­му язы­ку, од­на­ко дан­ные для при­ме­ров буду пи­сать на JSON, т. к. ду­маю он всем по­ня­тен, и кро­ме все­го про­че­го ис­поль­зу­ет­ся в до­ку­мен­та­ции к Mus­tache.

(далее...)

Сергей Лымарь © 2005-2014, Все права защищены.