2016-11-21 24 views
0

私はシンプルなカレンダーWebページを実装しようとしています。Jinja2:複雑なテンプレートを書く正しい方法

私はJinja2の新機能ですが、テンプレートの理解は、この目的のためにテンプレートが設計されているので、PythonソースにHTMLコードを書くのは避けなければなりません。

私が直面している問題は、私はこのプロジェクトのために明確なテンプレートを書く方法がわかりません。私は私のプロジェクトの全体的なアーキテクチャの問題があると思います...

マイページテンプレート:

{% extends "base.html" %} 
{% block title %}The title{% endblock %} 
{% block content %} 
    <h1>Hey</h1> 
    <p> I'm happy </p> 
    <div id="calendar"> 
     <table> 
      <tr> 
       {% for month in range(1, 13) %} 
        <td valign="top" align="center">{# html code for a single month goes here... #}</td> 
       {% endfor %} 
      </tr> 
     </table> 
    </div> 
{% endblock %} 

毎月テンプレート

<table> 
    <th>{{ month_name }}</th> 
    {% for day_number in days %} 
     <tr><td>{{ day_number }}</td><td>{{ weekday }}</td></tr> 
    {% endfor %} 
</table> 

は最後に、私はカレンダーのPythonのクラスを持っています基本的に月の曜日を計算するヘルパー関数を提供します:

class Calendar: 
    def __init__(self, year): 
     self.year = year 

    def monthrange(self, month): 
     nextmonth = month % 12 + 1 
     nextyear = self.year + 1 if nextmonth == 1 else self.year 
     firstday = datetime.date(self.year, month, 1) 
     lastday = datetime.date(nextyear, nextmonth, 1) 
     return (1, (lastday - firstday).days) 

    def itermonthdates(self, month): 
     first, last = self.monthrange(month) 
     for i in range(first, last + 1): 
      yield datetime.date(self.year, month, i) 

    def tohtml(self): 
     def month_to_html(month): 
      # !!! This code generate HTML but it should not !!! 
      s = '<table>\n' 
      s += '<th>{}</th>'.format(MONTHS[month - 1]) 
      for day in self.itermonthdates(month): 
       weekday = WEEKDAYS[day.weekday()] 
       d = {'day': day.day, 'weekday': weekday} 
       s += '<tr><td>%(day)02d</td><td>%(weekday)s</td></tr>\n' % d 
      s += '</table>\n' 
      return s 

     template_loader = jinja2.FileSystemLoader(searchpath='templates') 
     template_env = jinja2.Environment(loader=template_loader) 
     template = template_env.get_template('template.html') 
     print(template.render(months=[month_to_html(i) for i in range(1, 13)])) 

So彼のコードは、私がJinja2を毎月レンダリングする方法を知らないので、部分的にしか動作しません。

ご協力いただければ幸いです。 ベン

+0

これはかなり不明です。 '毎月'は別のページにありますか?もしそうなら、 '{%include 'path/to/file.html'%}'を使ってください。そうでない場合は、さらに明確にしてください。 –

+0

私はまだ正確に必要なものを理解していない、より具体的にしようとする?あなたがページを表示させる方法を知らない場合。 'Flask'で' return render_template( 'path/to/page.html') 'を使うことができます。そうでなければ、私は何を求めているのか正確には分かりません。 –

+0

あなたの答えをありがとう。結局、月は同じページに列として表示されます。私の質問です:基本的に、HTMLを描画するためのループは、PythonスクリプトでHTMLを書くことを避けるために、テンプレート内にある必要があります。ただし、ここでは、カスタムカレンダークラスのメソッドを使用して繰り返します。だから、それを行う適切な方法は何ですか? – blaurent

答えて

0

私はついにだと思います。私はあなたが望むものを手に入れました。 Do notHTMLPythonに書きます。代わりにPythonにカレンダーにlogicを作成し、そのデータをテンプレートに送信して、入力するテンプレートをJinjaにすることができます。十分な話、非常に簡単な例をコードしてみましょう。

簡単な例

にここでは、Webページに表示される現在の日付を取得します。

logic.py

@app.route('/') 
def index(): 
    import time 
    current_time = time.strftime("%d/%m/%Y") 
    return render_template('template.html', data = current_time) 

そのコードに適用することによりtemplate.html

{% if data %} # This checks if the variable "data" is set. 
    <p> {{data}} </p> ## This will output the date here 

、あなたは、変数に(それが生成されるPythonを必要とすることを意味する)任意の論理データを割り当てて送信し、それらを送信することができますJinjaテンプレートを追加してargumentrender_templateにテンプレートを追加します。今回私があなたが望んでいたことを理解していました。

0

ご回答ありがとうございます。 私は解決策で終わった。より良い方法があるかどうかはわかりません。最後に、calendarオブジェクトをテンプレートに渡します。

ページテンプレート:

{% extends "base.html" %} 
{% block title %}The title{% endblock %} 
{% block content %} 
    <h1>Hey</h1> 
    <p> I'm happy </p> 
    <div id="calendar"> 
     <table> 
      <tr> 
       {% for month in range(1, 13) %} 
       <td valign="top" align="center"> 
        {% include 'month_template.html' %} 
       </td> 
       {% endfor %} 
      </tr> 
     </table> 
    </div> 
{% endblock %} 

月テンプレート:

<table> 
    <th>{{ calendar.month_name(month) }}</th> 
    {% for day_number, weekday in calendar.itermonthdays(month) %} 
     <tr><td>{{ day_number }}</td><td>{{ weekday }}</td></tr> 
    {% endfor %} 
</table> 

Pythonスクリプト:

class Calendar: 
    def __init__(self, year): 
     self.year = year 

    @staticmethod 
    def month_name(monthid): 
     return MONTHS[monthid - 1] 

    def monthrange(self, month): 
     nextmonth = month % 12 + 1 
     nextyear = self.year + 1 if nextmonth == 1 else self.year 
     firstday = datetime.date(self.year, month, 1) 
     lastday = datetime.date(nextyear, nextmonth, 1) 
     return (1, (lastday - firstday).days) 

    def itermonthdates(self, month): 
     first, last = self.monthrange(month) 
     for i in range(first, last + 1): 
      yield datetime.date(self.year, month, i) 

    def itermonthdays(self, month): 
     for date in self.itermonthdates(month): 
      day = '{:02d}'.format(date.day) 
      weekday = WEEKDAYS[date.weekday()] 
      yield day, weekday 

    def tohtml(self): 
     template_loader = jinja2.FileSystemLoader(searchpath='templates') 
     template_env = jinja2.Environment(loader=template_loader) 
     template = template_env.get_template('template.html') 
     print(template.render(calendar=self)) 

は、あなたがより良いアプローチを見れば、私に教えてください。

ありがとうございました。

ベン

+0

uは 'to html'関数を必要としません。 'HTML'スクリプトは' .html'ファイルになければなりません。なぜ 'jinja2.FileSystemLoader'と' jinja2.Environment'を使用していますか?別のファイルでクラスを作成し、そのクラスをビューに組み込み、クラスのオブジェクトを作成し、私の例のように 'render_template'でオブジェクトを渡すだけです。 'jinja'のオブジェクトを使ってその属性を表示します。それは私がそれをする方法です –

+0

まあ、私はウェブ開発では新しいです。低レベルのJinja2とFlaskフレームワークの違いをあなたが提案しているのではないでしょうか? – blaurent

+0

正直言って、私は 'jinja.FileSystemLoader'やそれに類する機能を使ったことはありません。私はフラスコ "http://m41kdev3lops.pythonanywhere.com/"で動作しているWebサイトを持っていますが、それはまったく機能していますが、そのようなものは一度も使用されていません。謝罪は、そこに助けることはできません。 –

関連する問題