Четвертая часть статьи, и вероятно — не последняя. Напомню, что предыдущие три статьи (а так же все последующие) теперь можно будет увидеть по этому адресу — статей много и проставлять в них навигационные ссылки друг на друга мне надоело;-)
Напомню, что мы закончили на обзоре контроллера для нашего примера и обещании, что в следующей части все начнется, и, наконец-то, все станет интересно и захватывающе. Станет обязательно. Итак —
Как вы знаете, такие слова как MVC уже давно стали даже не модными, а прям-таки подразумевающимеся (другой вопрос что понимает их всяк по своему). Наш пример не стал исключением — и теперь нам нужно объединить достижения контроллера и модели воедино и показать их пользователю. В этом нам немало поможет тот факт, что GAE внутри использует Django, механизм шаблонов которого является одним из самых лучших среди тех, которые я знаю. Одним из самых интересных, на мой взгляд, свойств шаблонов Django является то, что они поддерживают наследование.
Действительно, зачастую дизайн двух функционально разных страниц веб-сайта отличается лишь незначительно и использует общие элементы — header, footer, меню и т.д. Обидно будет дублировать этот код — и в то же время, всяческие include-директивы это все-таки вчерашний день. В Django вы можете наследовать один шаблон от другого.
Рассмотрим наш базовый шаблон, который можно найти в дереве исходников как templates/basic.html. Поскольку HTML на Хабр красиво вставляться не желает (и никакой Хабраредактор с этим справится не может), а некрасиво его читать — голову сломать можно, посмотрите его уж в SVN по ссылке выше. Суть не в этом. Суть в том, что в каких-то местах мы объявляем «заглушки»:
Содержимое этих заглушек объявляет шаблон, который наследует наш basic.html, например, как это показано в please_login.html:
Мы не будем рассматривать наследование шаблонов в Django — примеров масса и найти их не составит никакого труда. Заметим только, что please_login.html определяет два блока — title и content; первый, соответственно, используется в заголовке, а второй — в теле страницы.
Наверняка вы обратили внимание на конструкции вида:
Собственно, вот и вся магия. Мы создаем login URL так же как и раньше, и просто передаем его в качестве параметра шаблона механизму Джанги. Последний берет на себя все задачи разрешения наследования, соединения многих шаблонов воедино, подстановки блоков и значений, и на выходе мы получаем приятно выглядящую страницу:
Абсолютно аналогичным образом мы создаем представление для страницы залогиненного пользователя:
Ничего непредсказуемого нет. Единственное отличие от первого примера — здесь мы создаем logout url вместо login, и передаем имя пользователя чтобы «персонализировать» приветствие. Я думаю, если вы читали пост внимательно, для вас не составит труда представить себе, что именно должно быть в шаблоне и представлении для страницы статистики; проверить же себя можно, соответственно по адресам stats.html и view.py.
Ну что ж — пора подвести некоторые итоги. Серия статей GAE from the beginning насчитывает уже четыре части, а мы только коснулись всего многообразия возможностей Google AppEngine. Дальше я, пожалуй, буду ждать комментарией пользователей и читателей, с вопросами, предложениями, идеями —, а через пару дней, отдохнув, напишу еще пару статей. О чем — это зависит только от вас!
Наконец, если у вас возникнут вопросы — пишите сюда, здесь явно есть специалисты получше чем я, и мы все вместе постараемся вам ответить.
Напомню, что мы закончили на обзоре контроллера для нашего примера и обещании, что в следующей части все начнется, и, наконец-то, все станет интересно и захватывающе. Станет обязательно. Итак —
Представление
Как вы знаете, такие слова как MVC уже давно стали даже не модными, а прям-таки подразумевающимеся (другой вопрос что понимает их всяк по своему). Наш пример не стал исключением — и теперь нам нужно объединить достижения контроллера и модели воедино и показать их пользователю. В этом нам немало поможет тот факт, что GAE внутри использует Django, механизм шаблонов которого является одним из самых лучших среди тех, которые я знаю. Одним из самых интересных, на мой взгляд, свойств шаблонов Django является то, что они поддерживают наследование.
Действительно, зачастую дизайн двух функционально разных страниц веб-сайта отличается лишь незначительно и использует общие элементы — header, footer, меню и т.д. Обидно будет дублировать этот код — и в то же время, всяческие include-директивы это все-таки вчерашний день. В Django вы можете наследовать один шаблон от другого.
Рассмотрим наш базовый шаблон, который можно найти в дереве исходников как templates/basic.html. Поскольку HTML на Хабр красиво вставляться не желает (и никакой Хабраредактор с этим справится не может), а некрасиво его читать — голову сломать можно, посмотрите его уж в SVN по ссылке выше. Суть не в этом. Суть в том, что в каких-то местах мы объявляем «заглушки»:
- <div id='content'>
- {% block content %} {% endblock %}
- </div>
Содержимое этих заглушек объявляет шаблон, который наследует наш basic.html, например, как это показано в please_login.html:
- {# $Id: please_login.html 3 2010-01-25 12:14:40Z sigizmund $ #}
-
- {% extends "basic.html" %}
-
- {% block title %}
- HelloWorld! — a simple GAE application
- {% endblock %}
-
- {% block content %}
- Welcome to HelloWorld! — a simple application to illustrate some features of GAE. To continue, <a href="{{ login_url }}">please login</a> using your Google credentials.
- {% endblock %}
Мы не будем рассматривать наследование шаблонов в Django — примеров масса и найти их не составит никакого труда. Заметим только, что please_login.html определяет два блока — title и content; первый, соответственно, используется в заголовке, а второй — в теле страницы.
Наверняка вы обратили внимание на конструкции вида:
- <a href="{{ login_url }}">...
В принципе, ясно, что здесь имеет место быть подстановка аргументов в шаблон. Давайте посмотрим, как именно это происходит: красивого кода опять не получилось, потому как подсветка в Хабраредакторе почему-то убивает отступы, что, в случае Питона, согласитесь, имеет некоторое значение
- class StartPage:
- def __init__(self, request):
- self.request = request
- def render(self, out):
- template_values = {'login_url' : users.create_login_url("/login")}
- path = os.path.join('templates/please_login.html')
- out.write(template.render(path, template_values))
Собственно, вот и вся магия. Мы создаем login URL так же как и раньше, и просто передаем его в качестве параметра шаблона механизму Джанги. Последний берет на себя все задачи разрешения наследования, соединения многих шаблонов воедино, подстановки блоков и значений, и на выходе мы получаем приятно выглядящую страницу:
Абсолютно аналогичным образом мы создаем представление для страницы залогиненного пользователя:
- {# $Id: welcome.html 3 2010-01-25 12:14:40Z sigizmund $ #}
-
- {% extends "basic.html" %}
-
- {% block title %}
- Welcome page for {{ username }}
- {% endblock %}
-
- {% block content %}
- Dear {{ username }}!<br/><br/>
- Welcome to HelloWorld! — a simple application to illustrate some features of GAE. Now when you're logged in, you can <a href='/stats'>view your stats</a>. Alternatively, you can <a href="{{ logout_url }}">log out</a> and start all over again.<br/><br/>
- {% endblock %}
и, соответственно,
- class WelcomePage:
- def __init__(self, request):
- self.request = request
- self.user = users.get_current_user()
-
- def render(self, out):
- template_values = {
- 'username' : self.user.nickname(),
- 'logout_url' : users.create_logout_url('/')
- }
-
- path = os.path.join('templates/welcome.html')
- out.write(template.render(path, template_values))
На выходе мы получаем: Ничего непредсказуемого нет. Единственное отличие от первого примера — здесь мы создаем logout url вместо login, и передаем имя пользователя чтобы «персонализировать» приветствие. Я думаю, если вы читали пост внимательно, для вас не составит труда представить себе, что именно должно быть в шаблоне и представлении для страницы статистики; проверить же себя можно, соответственно по адресам stats.html и view.py.
Ну что ж — пора подвести некоторые итоги. Серия статей GAE from the beginning насчитывает уже четыре части, а мы только коснулись всего многообразия возможностей Google AppEngine. Дальше я, пожалуй, буду ждать комментарией пользователей и читателей, с вопросами, предложениями, идеями —, а через пару дней, отдохнув, напишу еще пару статей. О чем — это зависит только от вас!
Внеклассное чтение
- Как я уже и говорил, начать стоит с официального AppEngine QuickStart почти наверняка по прочтению вы сможете написать что-то толковое. Если же по прочтению вы поймете, что чего-то явно не хватает, то вам надо посмотреть на …
- … официальную документацию по AppEngine. Она действительно очень хорошо написана, и прочитать ее стоит.
- Наконец, про шаблоны Django вы можете прочитать на сайте django — уверен, что вам понравится и вы не остановитесь пока не прочтете всю документацию от корки до корки;-)
Наконец, если у вас возникнут вопросы — пишите сюда, здесь явно есть специалисты получше чем я, и мы все вместе постараемся вам ответить.