يعد Wrangler منشئ مواقع ثابتة للأشخاص الذين لا يقومون بإنشاء مدونات.
سمات:
في Springload، غالبًا ما نحتاج إلى إنشاء مواقع ثابتة، ولكننا نكافح للعثور على أداة تسمح لنا بمواصلة العمل. أدخل رانجلر. لن يتوقع أن يتم تنسيق المحتوى الخاص بك كسلسلة من منشورات المدونة. لا يقوم بنسخ الأصول الثابتة أو معالجة SaSS أو صنع القهوة.
إنها تفعل شيئًا واحدًا، وتفعل هذا الشيء بشكل جيد.
نأمل أن تنال إعجابك.
تثبيت رانجلر عبر النقطة:
pip install wrangler
إنشاء مشروع جديد في الدليل الحالي .
wrangler create .
سيؤدي هذا إلى إنشاء مجموعة من الدلائل. للتأكد من أنه يعمل، أنشئ الموقع الصغير الذي تم إنشاؤه تلقائيًا:
wrangler build content www
قم بخدمة موقعك عبر محرك من اختيارك، أو الخادم المدمج سهل الاستخدام على http://127.0.0.1:8000/
:
wrangler serve www
هل تريد مشاهدة المحتوى والقوالب الخاصة بك لإجراء التغييرات وإعادة بنائها تلقائيًا؟ هناك تطبيق لذلك. تأخذ مهمة المراقبة جميع الخيارات نفسها مثل 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
- المجلد الجذر للويب. حقًا، يمكنك الإخراج إلى أي مكان، لقد اخترنا للتو شبكة الاتصالات العالمية كإعداد افتراضي معقول.lib
- الملحقات المخصصة، والفئات، والخطافات، وما إلى ذلك، أدخل هنا. اكتب بعض وحدات بايثون وقم بتمرير النتائج مرة أخرى إلى رانجلرvar
- يحتفظ بذاكرة التخزين المؤقت للقالب وذاكرة التخزين المؤقت لكائنات الملف (يستخدم wrangler مجموعة Pickle and 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
اسم الصفحة في شريط التنقل (وربما علامة العنوان الخاصة بك أيضًا)
مسار القالب، المتعلق بـ templates_dir
الخاص بـ wrangler.yaml
اختصار للعنوان، والذي يمكن استخدامه في التنقل بدلاً من ذلك
محاولات لاستبدال فئة Python لكائن الصفحة. يجب أن تكون فئة فرعية من wrangler.Core.Page
إخفاء هذه الصفحة من شجرة التنقل.
ما هو مكتوب على القصدير
قائمة الكلمات الرئيسية
تجاوز output_file_extension
الافتراضي من wrangler.yaml. سيتم عرض الصفحة بهذا الامتداد.
مفيد لترتيب الصفحات، من الأقل إلى الأعلى. افتراضيًا، سيستخدم رانجلر الترتيب الأبجدي لنظام الملفات.
المسار إلى الصورة المصغرة
قائمة الصفحات ذات الصلة. في القالب الخاص بك، سيتيح لك ذلك الحصول على بعض المعلومات الأساسية حول الصفحات الأخرى (مثل العنوان والوصف).
يضيف 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
يمكنك إنشاء صفحة رانجلر بدون بيانات، وترميز كل شيء في القالب، custom-page.j2
إذا كنت تريد ذلك.
meta :
title : No content!
template : custom-page.j2
output_file_extension : txt
سيؤدي هذا إلى إنشاء www/custom-page.txt
.
تأتي رانجلر مزودة بمرشح تخفيض السعر 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
هذا هو التكوين الأساسي، الأشياء الصلبة. يبدو قليلا مثل هذا:
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....
قم بتكوين أي ملحقات قمت بإعدادها هنا. تتيح لك الإضافات تشغيل أي وظيفة لغة بايثون تريدها، وإدخال النتائج في القوالب الخاصة بك.
# 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
يقبل وسيطة موضعية واحدة (الدليل المطلوب تقديمه) ومنفذ --port
اختياري (افتراضي 8000).
wrangler serve www --port 8001
قم بإزالة ذاكرة التخزين المؤقت للقالب وذاكرة التخزين المؤقت للكائن من الدليل "var".
wrangler clean
يقوم Wrangler بتحميل جميع وحدات python الموجودة في دليل lib
الخاص بمشروعك عند تشغيله.
يمنحك هذا القدرة على توسيع الوظائف الأساسية ومعالجة بيانات الصفحة - على سبيل المثال، يمكنك تحميل بعض القيم من قاعدة بيانات وإتاحتها في القوالب الخاصة بك.
عند استدعاء build
، يقوم wrangler ببناء تمثيل لبنية الشجرة في دليل content/
الخاص بك.
إنها تستخدم قائمة مرتبطة بشكل مضاعف من كائنات Node
، والتي يتم دمجها في NodeGraph
، وهي حاوية سهلة الاستخدام للتعامل مع العقد.
# 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 :
للحفاظ على الأمور مرتبة، لا يحتفظ كائن العقدة بتمثيل لبيانات الصفحة مباشرة عليه - فالعقد هي مجرد حاويات.
باتباع الأفكار الواردة في هذه المناقشة، تمتلك العقدة خاصية شحن تحمل فئة الصفحة الحقيقية :
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
إلى فئة فرعية:
ليب/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 )
يستخدم رانجلر إشارات الوامض لمعالجة الخطافات والتمديدات.
الخطافات هي إشارات يتم إطلاقها عند نقاط حرجة في عملية العرض. تتم معالجتها بالترتيب الذي تظهر به في الوحدات النمطية الخاصة بك، ويمكنها تعديل الكائنات الواردة مباشرةً. لديهم أيضًا إمكانية الوصول إلى config
renderer
reporter
الخاص بـ wrangler.
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
القوالب الخاصة بك.
لنأخذ هذا السيناريو الصغير:
# 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 ()
إذا كنت بحاجة إلى الوصول إلى contextfilter
أو envcontextfilter
الخاص بـ jinja، فيمكنك استيرادهما وتطبيقهما على وظيفتك أيضًا:
اقرأ المزيد عن مرشحات السياق في 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