[TurboGears] ブログを作成する。その3

注意

この記事は、id:SumiTomohiko:20070117:11690428370の続きです。

記事入力画面

日記の記事を入力する機能を作成します。tgdiary/controller.pyに、以下のメソッドを追加します。addメソッドは、入力画面を表示するメソッドで、doaddメソッドは、入力画面の入力を受けて、実際にデータベースに登録するメソッドです。とりあえず、入力値検証については考えないことにします。

    @expose(template="tgdiary.templates.add")
    @identity.require(identity.not_anonymous())
    def add(self):
        return dict()

    @expose()
    @identity.require(identity.not_anonymous())
    def doadd(self, title, body):
        # TODO: Validate.
        article = Article(title=title, body=body, user=identity.current.user)
        created = article.created
        redirect("/date?user=%d&date=%04d%02d%02d&span=%d" % (identity.current.user.id, created.year, created.month, created.day, 1))

入力画面となる、以下のtgdiary/template/add.kidを作成します。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#"
    py:extends="'master.kid'">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/>
<title>Welcome to TurboGears</title>
</head>
<body>
    <form action="doadd" method="post">
        <center>
            <table border="1">
                <tr>
                    <td>題名</td>
                    <td><input name="title" size="64" type="text" value=""/></td>
                </tr>
                <tr>
                    <td>本文</td>
                    <td><textarea cols="64" rows="16" name="body"></textarea></td>
                </tr>
                <tr>
                    <td colspan="2" align="center"><input type="submit" value="送信"/></td>
                </tr>
            </table>
        </center>
    </form>
</body>
</html>
<!--
    vim: tabstop=4 shiftwidth=4 expandtab
-->

これで、/addをブラウザで開いたら、記事が入力できるようになります。

日付別記事一覧画面

指定された日付から、指定された日数分の記事を表示する画面を作成します。tgdiary/controller.pyに以下のメソッドを追加します。記事は、日付ごとに枠を変えるなどして区分けしたいので、記事を日付ごとにまとめています。

    @expose(template="tgdiary.templates.date")
    def date(self, user, date, span):
        # TODO: Validate date and span.
        import datetime
        year = int(date[0:4])
        month = int(date[4:6])
        day = int(date[6:8])
        today = datetime.datetime(year, month, day, 0, 0, 0)
        date_from = today - datetime.timedelta(int(span) - 1)
        date_to = today + datetime.timedelta(1)
        userID = int(user)
        articles = list(Article.select(AND(Article.q.created >= date_from, Article.q.created < date_to, Article.q.userID == userID), orderBy=-Article.q.created))

        if len(articles) < 1:
            return dict(articles=[])

        articles_by_date = []
        current_date = datetime.date(datetime.MINYEAR, 1, 1)
        for article in articles:
            created_date = article.created.date()
            if current_date != created_date:
                articles_by_date.append([])
                current_date = created_date
            articles_by_date[-1:][0].append(article)

        return dict(articles=articles_by_date)

以下のtgdiary/templates/date.kidを作成します。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#"
    py:extends="'master.kid'">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/>
<title>Welcome to TurboGears</title>
</head>
<body>
<table border="1" py:for="articles_by_date in articles">
    <tr>
        <td>
            <table border="1" py:for="article in articles_by_date">
                <tr>
                    <h1 py:content="article.title"></h1>
                    <p py:content="article.body"></p>
                </tr>
            </table>
        </td>
    </tr>
</table>
</body>
</html>
<!--
    vim: tabstop=4 shiftwidth=4 expandtab
-->

これで、/date?user=1&date=20070101&span=1などとすると、記事の一覧が表示されます。