Wrangler は、ブログを構築していない人向けの静的サイト ジェネレーターです。
特徴:
Springload では、静的サイトを作成する必要があることがよくありますが、それを実行できるツールを見つけるのに苦労しました。ラングラーに乗り込みます。コンテンツが一連のブログ投稿としてフォーマットされることは想定されていません。静的アセットをコピーしたり、SaSS を処理したり、コーヒーを淹れたりすることはありません。
それは 1 つのことを実行し、その 1 つのことを非常にうまく実行します。
気に入っていただければ幸いです。
pip 経由で Wrangler をインストールします。
pip install wrangler
現在のディレクトリに新しいプロジェクトを生成します.
wrangler create .
これにより、多数のディレクトリが作成されます。動作を確認するには、小さな自動生成サイトを構築します。
wrangler build content www
選択したエンジン、またはhttp://127.0.0.1:8000/
にある便利な組み込みサーバーを介してサイトを提供します。
wrangler serve www
コンテンツとテンプレートの変更を監視し、自動的に再構築したいですか?そのためのアプリがあります。 watch タスクは、 build
と同じオプションをすべて受け取ります。
wrangler watch content www
Wrangler は非常に単純なファイルシステム規則に従っています。
my-site/
| --content
| ----index.yaml
| --lib
| --templates
| ----template.j2
| --var
| --wrangler.yaml
| --www
content
- コンテンツディレクトリ。サイト構造はこのディレクトリを反映します。 content/index.yaml
がある場合は、 www/index.html
を取得します。templates
- jinja2 .j2
テンプレートが存在する場所www
- Web ルート フォルダー。実際、どこにでも出力できます。私たちは、賢明なデフォルトとして www を選択しただけです。lib
- カスタム拡張機能、クラス、フックなどがここに入ります。いくつかの Python モジュールを作成し、結果を Wrangler に返します。var
- テンプレート キャッシュとファイル オブジェクト キャッシュを保持します (Wrangler はすぐに使える Pickle と Shelve のコンボを使用します)これらのパスはすべてwrangler.yaml
で変更できます。
Wrangler は、ユーザーが何らかの構造化データを操作しており、それらのデータ ファイルを HTML (必要に応じて従来の ASP) に変換することを想定しています。
パッケージには、json、yaml、markdown (yaml フロントマターを含む) の 3 つのパーサーが含まれています。これらはファイルごとに動作するため、これは完全に有効です。
my-site/
| --content
| ----index.yaml
| ----page-2.json
| ----page-3.md
meta :
title : My title
template : template.j2
description : " My cool page! "
data :
content : " Here's some page content! "
blocks :
- " Lots of content "
- " even more content "
- " wow, so much content! "
{
"meta" : {
"title" : " My title " ,
"template" : " template.j2 " ,
"description" : " My cool page! "
},
"data" : {
"content" : " Here's some page content! " ,
"blocks" : [
" Lots of content " ,
" even more content " ,
" wow, so much content! "
]
}
}
---
title : My title
template : template.j2
description : " Markdown uses yaml front-matter "
---
# A heading!
Some paragraph text
## Another heading!
Even more text
---
Nice HR you got there.
* A list
* with some
* list items
これは素晴らしいマークダウンチートシートです
ページに関連するあらゆるものにメタデータを使用します。ここには好きなものを入力できますが、いくつかの予約語があります。
meta :
title : " Musings on the pronounciation of doge "
alias : " Doge "
template : " template.j2 "
class : DogePage
hide_from_nav : true
description : " Is it dog-e, doog, douge, douche? How do I properly refer to this meme? "
keywords : ["much", "analytics", "such", "SEO"]
output_file_extension : asp
weight : 1
thumbnail : /assets/images/thumb/doge-100x100.jpg
related :
- content/other-page.yaml
- content/pages/this-page-here.yaml
ナビゲーション内のページ名 (おそらくタイトルタグも)
テンプレート パス (wrangler.yaml のtemplates_dir
に相対)
タイトルの短縮形。代わりにナビゲーションで使用できます。
ページ オブジェクトの Python クラスを置換しようとします。 wrangler.Core.Page
のサブクラスである必要があります
このページをナビゲーション ツリーから非表示にします。
缶に書いてあること
キーワードのリスト
wrangler.yaml のデフォルトのoutput_file_extension
をオーバーライドします。ページはこの拡張機能を使用してレンダリングされます。
ページを下位から上位に並べるのに便利です。デフォルトでは、Wrangler はファイルシステムのアルファベット順の並べ替えを使用します。
サムネイル画像へのパス
関連ページの一覧です。これにより、テンプレートで、他のページに関する基本情報 (タイトルや説明など) を取得できるようになります。
ラングラーは、アクセスできるテンプレート内でメタデータにいくつかの内容を自動的に追加します。
{{ meta.url }}
{{ meta.segments }}
{{ meta.filepath }}
{{ meta.mtime }}
{{ meta.children }}
{{ meta.parents }}
{{ meta.parents_siblings }}
ビルドされたファイルへのパスoutput_dir
を基準とした相対パス) (例: /
すべての URL セグメントのリスト: ["sub-directory", "index.html"]
入力ファイルの名前
変更された時刻。これを使用して、たとえばブログのタイムスタンプを作成できます。
現在のディレクトリの直接の子
現在のファイルと/
間のすべてのノード
親ディレクトリの兄弟。
ページ データは完全にオプションです。
この小さなページ、 custom-page.yaml
を見てみましょう。必要に応じて、データのないページを Wrangler にスローして、テンプレートcustom-page.j2
内のすべてをハードコードすることができます。
meta :
title : No content!
template : custom-page.j2
output_file_extension : txt
これにより、 www/custom-page.txt
が構築されます。
Wrangler には jinja2 マークダウン フィルターが付属しています。マークダウン ファイルを使用している場合、マークダウンはdata.content
で入手できます。コンテンツをマークダウン フィルターにパイプすれば完了です。
< div class = " content " >
{{ data.content|markdown }}
</ div >
Markdown は素晴らしい記述形式ですが、より構造化されたデータを扱う場合にはいくつかの制限が生じる可能性があります。 YAML ファイルと JSON ファイルの場合は、 data
ディクショナリの一部にアクセスし、必要に応じてそれらを接続します。
< div class = " content " >
{{ data.content }}
{% for block in data . blocks %}
< p >{{ block }}</ p >
{% endfor %}
</ div >
Wrangler の編集可能なオプションは、プロジェクト ルートのwrangler.yaml
ファイルに保存されます。
開いてみると、 wrangler
、 site
、 extensions
3 つのノードが見つかります。
これはコア構成、つまりハードコアなものです。それは次のようになります。
wrangler :
# Template directory relative to your project root
templates_dir : templates
# Default template to load if no template is specified for a page
default_template : template.j2
# Default output file extension. Note this can be overwritten in the content
# by specifying 'output_file_extension' in the 'meta' area
output_file_extension : html
# Supported data formats. Ensure a parser is registered for each type.
# More information about parsers can be found in the link at the top of the file.
data_formats : ['yaml', 'yml', 'json', 'js', 'md', 'markdown']
# Ignore hidden files, and files starting with underscores
ignore : ['.','_']
# Prints all the internal plumbing output to stdout
verbose : false
# Always force all pages to be rendered
force : false
# Run without the cache (useful for developing custom page classes, to prevent them
# from being cached each run).
nocache : false
# The location of the template cache zip file.
# Ensure the var path exists and is writeable by the user
build_cache_file : var/build.cache
compiled_templates_file : var/jinja
compiled_templates_log : var/jinja.log
# Custom methods/classes go in the lib directory, for instance
# lib/Page.py or lib/Extensions.py or lib/Filters.py
lib_path : lib
# file continues....
ここで設定した拡張機能を設定します。拡張機能を使用すると、必要な Python 関数を実行し、その結果をテンプレートに挿入できます。
# wrangler.yaml continued...
extensions :
# Sitemap generates a tree structure of your entire site, relative to the
# webroot specified here
#
# {{ extensions.sitemap }}
#
# We leave it up to you to iterate over the sitemap and print everything in
# a pretty manner, but this gist might get you started:
# https://gist.github.com/joshbarr/111
sitemap :
webroot : /
{{ extensions.cachebuster }}
いくつかのデフォルト拡張子が含まれています: sitemap
、 fileinfo
、およびcachebuster
サイト変数はサイト全体の変数であり、 site
オブジェクトの子としてテンプレート内で使用できます。
たとえば、画像のパスを取得するには、 {{ site.paths.images }}
を呼び出すことで、入力の手間を省くことができます。
# wrangler.yaml continued...
site :
paths :
css : assets/css
js : assets/js
assets : assets
{# Hey, it's those handy vars I set in my site_vars #}
{{ site.paths.css }}
このドキュメントはすべてwrangler.yaml
ファイルにも含まれているため、迷うことはありません。
単一の位置引数、つまり新しいプロジェクトを作成するパスを受け取ります。
cd my-sweet-site && wrangler create .
# or
wrangler create my-sweet-site
input_dir
入力ディレクトリ ( site/content
など) output_dir
出力ディレクトリ ( www
など)
wrangler build content www
コンテンツが最後に変更された時期に関係なく、レンダリングを強制します。
wrangler build content www --force
すべてのページオブジェクトを再キャッシュします
wrangler build content www --nocache
すべてのページの出力ファイル拡張子をクラシックasp
に変更します (なぜそんなことをする人がいるでしょうか?)
wrangler build content www -o ".asp"
input_dir
内で検索するデータ形式をjson
に変更
wrangler build content www -d 'json'
テンプレートディレクトリの場所を変更する
wrangler build content www -t other-templates-dir
設定ファイルの場所を変更する
wrangler build content www -c site/config/wrangler.yaml
wrangler build
と同じオプションがすべてあります
ファイルが変更されるたびにすべての配管を出力します。
wrangler watch content www --verbose
1 つの位置引数 (提供するディレクトリ) とオプションの--port
(デフォルト 8000) を受け入れます。
wrangler serve www --port 8001
「var」ディレクトリからテンプレート キャッシュとオブジェクト キャッシュを削除します。
wrangler clean
Wrangler は起動時に、プロジェクトのlib
ディレクトリにあるすべての Python モジュールを読み込みます。
これにより、コア関数を拡張してページ データを操作できるようになります。たとえば、データベースからいくつかの値をロードして、テンプレートで使用できるようにすることができます。
build
呼び出すと、Wrangler はcontent/
ディレクトリにツリー構造の表現を構築します。
これは、ノードを処理するための便利なコンテナであるNodeGraph
にマッシュされるNode
オブジェクトの二重リンク リストを使用しています。
# Pseudocode
NodeGraph :
# The nodes in their hierarchical structure, eg:
tree :
Node :
children :
- Node :
children :
- Node
- Node :
children :
- Node
- Node
- Node
# The 'all' dictionary is the same nodes represented in a flat structure.
# This can be much quicker to iterate over than the tree, and you can
# access both from within your hooks and extensions.
# The filepath is used as the unique key.
all :
content/index.md :
Node :
# node's data...
content/other-page.md :
Node :
# node's data...
ノードは、その子だけでなくその親にもアクセスできます。
# More pseudocode
Node :
path : " content/index.md "
children :
- Node :
- Node :
- Node :
parent :
Node :
整理整頓のため、Node オブジェクトはページ データの表現を直接保持しません。ノードは単なるコンテナです。
この説明のアイデアに従って、ノードには実際のページ クラスを保持するカーゴプロパティがあります。
from wrangler . Core import Node
class GoldBullion ( object ):
price = 1200
the_node = Node ( "index" , "content/index.md" , parent = None , cargo = None )
the_node . add_cargo ( GoldBullion ())
cargo = the_node . get_cargo ()
print cargo . price
ページはソース ファイルのデータのdict
表現を保持し、 Renderer
データにアクセスするための一貫した方法を提供します。カスタム ページを作成するには、 wrangler.Core.Page
サブクラス化するだけで、自動的に読み込まれます。
便利なヒント:カスタム クラスの名前がPage
の場合、すべてのページのデフォルトのPage
オブジェクトが上書きされます。
# lib/Page.py
import wrangler . Core as wrangler
class Page ( wrangler . Page ):
def get_content ( self ):
return self . data [ "data" ]
def get_metadata ( self ):
return self . data [ "meta" ]
def get_properties ( self ):
print "Hey, I'm a custom page instance!"
return {
"title" : self . get_title (),
"alias" : self . get_short_title (),
"description" : self . get_meta_description (),
"url" : self . get_tidy_url (),
"show_in_navigation" : self . show_in_navigation (),
"weight" : self . get_weight (),
"thumbnail" : self . get_thumbnail ()
}
上記の例では、3 つのメイン ページ メソッドget_content()
、 get_metadata()
、およびget_properties()
を変更しています。
ページがレンダリングされるときに呼び出され、これはテンプレートでdata
オブジェクトとして使用できます。
<!doctype html>
< div class = ' dump-of-data-object ' >
{{ data.content }}
</ div >
ページがレンダリングされるときに呼び出されます。これはmeta
オブジェクトです。
<!doctype html>
< title >{{ meta.title }}
説明するのが少し難しくなりますが、それでも素晴らしいです。 Node
がレンダリングされると、子、兄弟、親、手動で関連するページなど、現在のページに関連するページに関する特定の情報が要求されます。
すべてを他のすべてと共有するのではなく、各Page
クラスは他のページと共有してもよい基本情報を記述します。
def get_properties ( self ):
return {
"title" : self . get_title (),
"alias" : self . get_short_title (),
"url" : self . get_tidy_url (),
"show_in_navigation" : self . show_in_navigation (),
"weight" : self . get_weight (),
# Let's add the modified time, so our theoretical parent
# page could know when we last saved the file.
"mtime" : self . getmtime ()
}
非常に単純な例、ページ上のすべてのテキストを反転するカスタム ページ クラスを見てみましょう。とても実用的です。
まず、ページ メタにclass
プロパティを設定して、Wrangler にどのクラスをロードするかを指示します。
コンテンツ/カスタム.md:
---
class : RightToLeft
---
# My custom page
With its custom content.
次に、 lib/
ディレクトリ内のどこかに、 Page
サブクラス化する新しいクラスを作成します。 lib/
ディレクトリ内のどこに配置されるかは問題ではありません。唯一のルールは、 Page
オブジェクトをサブクラス化する必要があるということです。
lib/pages.py
import wrangler . Core as wrangler
class RightToLeft ( wrangler . Page )
def get_content ( self ):
for key , val in self . data [ "data" ]:
self . data [ "data" ][ key ] = val [:: - 1 ]
return self . data [ "data" ]
素晴らしい!私たちのページは右から左へのテキストで印刷されます。
wrangler.yaml
ファイルを見ると、 ["yaml", "json", "md"]
の 3 つのファイル タイプを受け入れていることがわかります。
Wrangler にはデフォルトで 3 つのパーサー ( Yaml
、 Markdown
、およびJson
が含まれており、これらは入力ファイルを使用して意味のあるデータとして表します。
オートローダーは、 wrangler.Core.Parser
サブクラス化するものを探します。
たとえば、テキスト形式をサポートするには、 lib/Parsers.py
のどこかでこれを行うことができます。
from wrangler . Core import Parser
from lxml import objectify
from collections import defaultdict
class XmlParser ( Parser ):
accepts = [ "xml" , "robotlanguage" ]
def interpret ( self , file_contents ):
return root = objectify . fromstring ( file_contents )
Wrangler は、フックとエクステンションの処理にウインカーの信号を使用します。
フックは、レンダリング プロセスの重要なポイントで発生するシグナルです。これらはモジュールに表示される順序で処理され、受信オブジェクトを直接変更できます。また、Wrangler のconfig
、 renderer
、 reporter
にもアクセスできます。
from wrangler . Core import before_render , after_render , load_item , save_item , render_item
@ before_render
def before ( ** kw ):
nodes = kw [ 'nodes' ]
config = kw [ 'config' ]
renderer = kw [ 'renderer' ]
reporter = kw [ 'reporter' ]
print "Hey, I'm a hook!"
return "foo!"
@ after_render
def after ( ** kw ):
nodes = kw [ 'nodes' ]
config = kw [ 'config' ]
renderer = kw [ 'renderer' ]
reporter = kw [ 'reporter' ]
print "Hey, I'm a hook!"
return ""
拡張機能は、テンプレートのextensions
辞書に便利なデータを返す Python スクリプトです。
この小さなスクリプトを見てみましょう。
# lib/my_extensions.py
from wrangler . Core import extension
@ extension
def my_extension ( sender , ** kwargs ):
# Add some config to your YAML file and access it here:
config = kwargs [ 'config' ][ 'extensions' ][ 'my_extension' ]
return config [ "string_to_print" ]
extensions.YOUR_EXTENSION_NAME
のテンプレートからアクセスできます。
< em class = " extension " >
{{ extensions.my_extension }}
</ em >
その結果、次の出力が得られます。
< i > "This is my basic extension!" </ i >
wrangler.yaml
には、拡張機能を管理するためのセクションがあります。
# My extension just prints a string... not very exciting!
my_extension :
string_to_print : " This is my basic extension! "
Wrangler を使用すると、カスタム フィルターを使用して Jinja2 を拡張できます。
フィルターは、lib ディレクトリーlib/
内の任意のファイルに入れる必要があります。これらは、 template_filter
という適切な名前のデコレーターを介して接続されます。
#lib/filters.py
from wrangler . Core import template_filter
from jinja2 import contextfilter
@ template_filter
def my_filter ( value ):
return value . lower ()
jinja のcontextfilter
またはenvcontextfilter
にアクセスする必要がある場合は、それらをインポートして関数に適用することもできます。
jinja2 のコンテキスト フィルターについて詳しく読む
#lib/filters.py
from wrangler . Core import template_filter
from jinja2 import contextfilter
@ template_filter
@ contextfilter
def my_filter ( context , value ):
print context
return value