вторник, 29 октября 2013 г.

Заполняем шаблоны brython скриптом

Тут на днях один товарищ попросил решить такую задачку:
Имеется сайт состоящий из статических страниц. Среди них есть страницы где нужно выводить ленту новостей. И есть страница просто с новостями.
Статические страницы не удобно часто менять вручную. Ну и самое главное как быть с новостями? на каждой странице писать одну и туже ленту?
Это не удобно, то ошибешься где-то , то вообще забудешь что-то поменять, а если дизайн сменится вообще труба.
Как быть? Хотелось бы иметь один файл, где будут лежать данные о новостях, например в текстовом виде и с какими либо разделителями по полям. А еще хотелось бы иметь готовые html шаблоны для вывода на страницах. Тогда можно делать разный дизайн ленты новостей для разных страниц.
Но чем заполнять шаблоны данными из текстового файла?
Берем javascript интерпретатор для python-а  - Brython и пишем свой скрипт.

И получаем вот такой проектик - Brython-template-engine.

Что мы тут получаем?

В корневой директории сайта размещаем шаблоны html. Например для боковой ленты новостей в файле template_news1.html написано следующее:

<li>{{col0}}<head><b>{{col1}}</b></head>
<p>{{col2}}</p>
</li>

Этого достаточно, так как этот кусок будет повторяться столько раз сколько новостей или сколько раз указано выводить этот блок. Здесь указаны теги для html5, но это не важно т.к. можно написать любые теги.

А вот еще один шаблон в файле template_news2.html:

<tr>
    <td height="25"><strong>{{col0}}</strong><br>
    <img src="images/redline.jpg" alt=""></img></td>
  </tr>
  <tr>
    <td height="100" valign="top"><p align="justify">{{col2}}</p>
    <p>&nbsp;</p></td>
</tr>

Ну в общем как вам угодно создавайте шаблоны и сколько угодно.

Заметили что в шаблонах есть некоторые странные теги? например {{col0}} ?
Это как раз то место, куда будут вставляться данные из текстового поля  - это специальные теги разметки шаблонизатора. Я не стал сильно мудрствовать и взял стандартный способ применяемый в Django шаблонах.
Но на самом деле Вы можете придумать свои теги.

Теперь давайте рассмотрим как устроен файл с данными:
Он тоже лежит в корневой директории и называется news.txt
Но Вы можете назвать его как угодно, главное чтобы он имел обычный текстовый формат.
Вот его содержимое:

{{col0}};{{col1}};{{col2}}
1.;Head of first new;Text of first new. And more...
2.;Head of second new;Text of second new. And more...
3.;Head of third new;Text of third new. And more...
4.;Head of fourth new;Text of fourth new. And more...

Как видите в начале файле, в первой строке идет описание тех самых специальных тегов разметки. То есть тут Вы можете придумать какие-то свои теги. хоть например  %vasya% или &petya&. Главное чтобы каждый тег соответствовал своей колонке данных которые идут ниже.
Количество полей (колонок) может быть каким угодно. Там можно например добавить дата или ссылку на картинку.
Первая строка никогда не будет выводиться в шаблонах  - используйте ее для того чтобы задать специальные теги или символы.
Возникает вопрос -  а что является разделителями строк и колонок?
В данный момент я сделал стандартные разделители, то есть для строк '\\n' - перенос строки. Для разделения колонок указал знак ';' . Учтите что в разных системах перенос строки кодируется по разному, поэтому разделитель строк может не подходить.
Для того чтобы использовать другие разделители их нужно указать в коде скрипта. Скрипт лежит в директории /src/brython/src называется просто script.py. Так вот в нем в начале есть функция render:

def render(file,temp,target, count):
    global  file_data, template, target_id , count_view, rowscharsplit, colscharsplit
    file_data = file
    rowscharsplit = '\\n'
    colscharsplit = ';'
    template = temp
    target_id = target
    count_view = count
    open_template()

Вот здесь и можно указать специальные разделители.
rowscharsplit - разделитель строк, colscharsplit- разделитель полей.

Итак, как это все использовать:

1. скачиваете проект к себе корень проекта отсюда или делаете:
hg clone https://yaricp@bitbucket.org/yaricp/brython-template-engine, если есть установленный Mercurial ;
2. в случае архива распаковываете его;
3. подготавливаете шаблоны по цвету и вкусу;
4. заполняете файл с данными ;
5. в страницах в которые нужно вставить результат нужно в заголовке прописать :

<script type="text/javascript" src="src/brython/brython.js"></script>
    <script type="text/python" src="src/brython/src/script.py"></script>

в секцию <body> нужно вставить :

 onload="brython()"

Вот так например:

<body link="#000000" alink="#CC0000" vlink="#000000" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0"  onload="brython()">

а в конце страницы, перед </body> вставить:

<script type="text/python">
        render(file = 'news.txt',
        temp = 'template_news1.html',
        target = "news-content",
        count = 3
        )
</script>

Здесь указывается file - какой файл с данными использовать,temp -  в какой шаблон вставлять, target -  куда выводить результат на этой странице, count - сколько строк выводить в данном месте.

Ну и ясен пень на этой странице должен присутствовать элемент  с id = "news-content". Например <div id= "news-content"> или <table id="news-content">
Не важно какой элемент. И даже не важно имеет ли он внутри себя уже какие-то элементы или нет. Все что в нем имеется останется на месте, но еще добавится то, что указно в шаблонах и вставятся данные.

Вот что получается:



Если есть два места куда нужно вставлять данные, то делайте так:

<script type="text/python">
        render(file = 'news.txt',
        temp = 'template_news2.html',
        target = "newstable",
        count = None)
</script>
<script type="text/python">
        render(file = 'news.txt',
        temp = 'template_news1.html',
        target = "news-content",
        count = 3
        )
</script>

Здесь используются два шаблона и вставляются в разные места на странице.
Эти примеры   лежат в архиве в файлах index.html и news.html

Получится вот так:



Можете вставлять большее количество шаблонов и из разных файлов данных.

Немного анализа:

чем хорош данный метод?
Он позволяет снизить нагрузку на канал. т.к. закачиваются чистые данные без тегов разметки html, а теги подставляются на стороне клиента. Конечно теги разметки закачиваются, но это всего лишь один маленький шаблон. Если данных огромное количество  - это становится актуально. Но постраничной загрузки пока нет и я не знаю как это сделать таким способом.

Чем плох данный метод?
 Очевидно тем, что не все браузеры правильно отрабатывают даже обычный javascript код, а тут еще и brython :). А некоторые (люди) вообще не любят использовать скрипты на страницах и они отключают поддержку javascript в браузере, но возможно, уже не стоит на таких ориентироваться.

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

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





Комментариев нет:

Отправить комментарий