Шаблонизатор bem-xjst

Yandex

Шаблонизатор bem-xjst

Вячеслав Олиянчук

Яндекс.Субботник, 27 февраля 2016

bit.ly/tplcmp

bem/bem-xjst

История 1: про данные

            
    layout
        include ../blocks/header
        include ../blocks/content
        include ../blocks/footer
            
        
            
    {
        user: { currency: 'RUR', session: { … } },
        searchResults: [
            {
                area: '108',
                price: '9 990 000',
                created: 1456099246245,
                …
            },
            …
        ]
    }
            
        
            
    {
        user: { currency: 'RUR', session: { … } },
        searchResults: [
            {
                area: '108',
                price: '9 990 000',
                created: 1456099246245,
                …
            },
            …
        ]
    }
            
        
            
    {
        user: { currency: 'RUR', session: { … } },
        searchResults: [
            {
                area: '108',
                price: '9 990 000',
                created: 1456099246245,
                …
            },
            …
        ]
    }
            
        
            
/**
 * @param {Object} offer
 *   @param {String} offer.url
 *   @param {String} offer.title
 */
mixin offer(offer)
    li.offer
        a(href=offer.url)
            = offer.title
            
        
            
.content
    each offer in data.searchResults
        include ../block/offer(offer)
            
        
            
.content
    each offer in data.searchResults
        include ../block/offer(offer)
            
        
            
/**
 * @param {Object} offer
 *   @param {String} offer.url
 *   @param {String} offer.title
 */
mixin offer(offer)
    li.offer
        a(href=offer.url)
            = offer.title
            
        
            
.data .searchResults .offer {
    display: block;
}
            
        
            
.data > .searchResults > .offer {
    display: block;
}
            
        
            
.data > .searchResults > .offer {
    display: block;
}
            
        
            
    layout
        include ../blocks/header
        include ../blocks/content
        include ../blocks/nearby
        include ../blocks/footer

    nearby
        each item in data.nearby
            offer(item)
            
        
            
    layout
        include ../blocks/header
        include ../blocks/content
        include ../blocks/nearby
        include ../blocks/footer

    nearby
        each item in data.nearby
            offer(item)
            
        
            
    .nearby .offer
    {
        color: red;
        font-weight: 1.5em;
    }
            
        
            
    .nearby .offer
    {
        color: red;
        font-weight: 1.5em;
    }
            
        
            
    .offer
    {
        color: red;
        font-weight: 1.5em;
    }
            
        
            
    {
        user: { currency: 'RUR', session: { … } },
        searchResults: [
            {
                area: '108',
                price: '9 990 000',
                created: 1456099246245,
                …
            },
            …
        ]
    }
            
        
            
    {
        user: { currency: 'RUR', session: { … } },
        searchResults: [
            {
                block: 'offer',
                area: '108',
                price: '9 990 000',
                created: 1456099246245,
                …
            },
            …
        ]
    }
            
        
            
    // Входные данные
    {
        block: 'offer',
        area: '108',
        price: '9 990 000',
        created: 1456099246245,
        …
    }

    // Шаблон
    block('offer')(
        tag()('li')
    );
            
        

История 2: про рутину

            
    {
        user: { currency: 'RUR', session: { … } },
        searchResults: [
            {
                area: '108',
                price: '9 990 000',
                created: 1456099246245,
                …
            },
            …
        ]
    }
            
        
            
    layout
        include ../blocks/header
        include ../blocks/nav
        include ../blocks/content
        include ../blocks/footer
            
        
  1. page
    1. header
      1. logo
    2. nav
      1. item
      2. item
            {
    block: 'page',
    content: [
        { block: 'header' },
        { block: 'navigation' },
        { block: 'content' },
        { block: 'footer' }
    ]
}
            
        
            {
    block: 'page',
    content: [
        { block: 'header' },
        { block: 'navigation' },
        { block: 'content' },
        { block: 'footer' }
    ]
}
            
        
            {
    block: 'page',
    content: [
        { block: 'header' },
        { block: 'navigation' },
        { block: 'content' },
        { block: 'footer' }
    ]
}
            
        

Online demo

История 3: про вариативность

            mixin link(href, name, isNew)
              - var cls = "button";
              if isNew 
                - cls = cls + " new"
             
              a(href=href, class=cls)
                = name
                 if isNew
                   = " Новинка!"
             
            <a href="/fish" class="button new">Рыба Новинка!</a>
            <a href="/vegetable" class="button">Фрукты</a>
        
            mixin link(href, name, isNew)
              - var cls = "button";
              if isNew 
                - cls = cls + " new"
             
              a(href=href, class=cls)
                = name
                 if isNew
                   = " Новинка!"
             
            <a href="/fish" class="button new">Рыба Новинка!</a>
            <a href="/vegetable" class="button">Фрукты</a>
        
            <a id="anchor">Якорь</a>
            <a href="http://yandex.ru">Яндекс</a>
        
            ? {
                color: black;
                text-decoration: none;
            }
             
            ? {
                color: red;
            }
        
            <a id="anchor">Якорь</a>
            <a href="http://yandex.ru">Яндекс</a>
        
            a {
                color: black;
                text-decoration: none;
            }
             
            a[href] {
                color: red;
            }
        
            block('link')
(
    tag()('a'),
    attrs()(function() {
        return { href: this.ctx.url };
    }),

    match(function() { return this.ctx.isNew; })
    (
        mix()({ block: 'new' }),
        content()(function() {
            return applyNext() + ' Новинка!';
        })
    );
);
            
        

История 4: про точки расширения

            <tag class="bem-name  mixed  cls  js" attrs>
                content
            </tag>
        

Шаблоны:

            block('link').tag()('a');
        

Шаблоны:

            block('link').tag()('a');
            block('link').mix()({ block: 'counter' });
        

Шаблоны:

            block('link').tag()('a');
            block('link').mix()({ block: 'counter' });
            block('link').attrs()(function() {
    return { href: thix.ctx.url, target: '_blank' };
});
        

Шаблоны:

            block('link').tag()('a');
            block('link').mix()({ block: 'counter' });
            block('link').attrs()(function() {
    return { href: thix.ctx.url, target: '_blank' };
});
        

Шаблоны:

            block('link')(
                tag()('a'),
                mix()({ block: 'counter' }),
                attrs()(function() {
                    return { href: thix.ctx.url, target: '_blank' };
                })
            );
        

Шаблоны:

            block('link')(
                tag()('a')
            );
        
            block('link')(
                mix()({ block: 'counter' }),
                attrs()(function() {
                    return { href: thix.ctx.url, target: '_blank' };
                })
            );
        

Повторим всё вместе

bem-xjst

Домашняя работа

Благодарю за внимание

@miripiruni

#yasubbotnik

Благодарю за внимание

Fork me on GitHub