Wrangler는 블로그를 작성하지 않는 사람들을 위한 정적 사이트 생성기입니다.
특징:
Springload에서는 종종 정적 사이트를 개선해야 하지만 이를 수행할 수 있는 도구를 찾는 데 어려움을 겪었습니다. 랭글러를 입력하세요. 귀하의 콘텐츠가 일련의 블로그 게시물 형식으로 구성될 것으로 예상하지 않습니다. 정적 자산을 복사하거나 SaSS를 처리하거나 커피를 만들지 않습니다.
그것은 한 가지 일을 하고, 그 한 가지 일을 아주 잘 합니다.
우리는 당신이 그것을 좋아하길 바랍니다.
pip를 통해 랭글러를 설치합니다.
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
- 웹 루트 폴더. 실제로 어디든 출력할 수 있습니다. 우리는 합리적인 기본값으로 www를 선택했습니다.lib
- 사용자 정의 확장, 클래스, 후크 등이 여기에 들어갑니다. 일부 Python 모듈을 작성하고 결과를 Wrangler에 다시 전달합니다.var
- 템플릿 캐시와 파일 개체 캐시를 보유합니다(랭글러는 기본 제공되는 Pickle 및 Shelve 콤보를 사용함). 이러한 모든 경로는 wrangler.yaml
에서 변경할 수 있습니다.
Wrangler는 사용자가 일종의 구조화된 데이터로 작업하고 있으며 해당 데이터 파일을 HTML(또는 원하는 경우 기존 ASP)로 변환하려고 한다고 가정합니다.
패키지에는 json, yaml 및 markdown(yaml 머리말 포함)의 세 가지 파서가 포함되어 있습니다. 이는 파일별로 작동하므로 이는 완벽하게 유효합니다.
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 >
마크다운은 환상적인 쓰기 형식이지만 보다 구조화된 데이터를 처리할 때 몇 가지 제한 사항이 있을 수 있습니다. YAML 및 JSON 파일의 경우 data
사전의 일부에 액세스하여 적합하다고 판단되는 대로 연결합니다.
< div class = " content " >
{{ data.content }}
{% for block in data . blocks %}
< p >{{ block }}</ p >
{% endfor %}
</ div >
Wrangler의 편집 가능한 옵션은 프로젝트 루트의 wrangler.yaml
파일에 저장됩니다.
열어보면 wrangler
, site
, extensions
세 개의 노드가 있습니다.
이것이 핵심 구성, 하드코어 구성입니다. 다음과 같이 보입니다.
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
모든 페이지의 출력 파일 확장자를 classic 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
하나의 위치 인수(제공할 디렉터리)와 선택적인 --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 ()
}
위의 예에서는 세 가지 기본 페이지 메소드인 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
속성을 설정하여 랭글러에게 로드할 클래스를 알려줍니다.
콘텐츠/custom.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"]
세 가지 파일 형식을 허용하는 것을 알 수 있습니다.
Wrangler에는 기본적으로 입력 파일을 사용하고 의미 있는 데이터로 나타내는 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
의 템플릿에서 액세스할 수 있습니다.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