Wunderbar ทำให้ง่ายต่อการสร้างแอปพลิเคชัน HTML5, XHTML ที่มีรูปแบบดี, Unicode (utf-8) ที่มีการเยื้องอย่างสม่ำเสมอและอ่านง่าย
Wunderbar ได้รับแรงบันดาลใจจาก Builder ของ Jim Weirich และจัดเตรียมรหัสองค์ประกอบและไวยากรณ์รหัสคลาสและอิงตามการใช้งานจาก Markaby
การรองรับ JSON ของ Wunderbar ได้รับแรงบันดาลใจจาก jbuilder ของ David Heinemeier Hansson
บทช่วยสอนอยู่ระหว่างการพัฒนา
ฟังก์ชันเพิ่มเติมมีให้โดยส่วนขยาย
สถานที่ตั้งของ Wunderbar คือ โดยทั่วไปแล้วเอาต์พุตประเภทต่างๆ จะเกิดขึ้นโดยการต่อท้ายชุดของคู่คีย์/ค่าหรือค่าอย่างง่าย และการดำเนินการเหล่านั้นควรได้รับการปรับปรุงให้เหมาะสม การต่อท้ายคู่คีย์/ค่าทำได้ผ่าน:
_key value
... และการต่อท้ายค่าง่าย ๆ ทำได้ดังนี้:
_ value
สำหรับ HTML คีย์/ค่าจะถูกใช้สำหรับโหนดองค์ประกอบ และใช้ค่าอย่างง่ายสำหรับโหนดข้อความ สำหรับ JSON จะใช้คีย์/ค่าสำหรับแฮช และใช้ค่าแบบง่ายสำหรับอาร์เรย์ สำหรับข้อความ ค่าอย่างง่ายจะถูกส่งออกผ่านการวาง และจะไม่ใช้คู่คีย์/ค่า
การทำรังทำได้โดยใช้บล็อก
เมธอดขีดเส้นใต้เมื่อไม่ผ่านอาร์กิวเมนต์ จะส่งคืนอ็อบเจ็กต์ที่สามารถใช้เพื่อทำหน้าที่พิเศษหลายอย่างได้ ฟังก์ชันบางอย่างมีลักษณะเฉพาะสำหรับวิธีเอาท์พุต วิธีอื่นๆ เช่นวิธีการบันทึกเป็นเรื่องปกติ
วิธีการขีดเส้นใต้เมื่อส่งผ่านอาร์กิวเมนต์หลายตัวหรือการรวมกันของอาร์กิวเมนต์และบล็อกอาจทำหน้าที่ทั่วไปอื่น ๆ ขึ้นอยู่กับประเภทของอาร์กิวเมนต์ที่ส่งผ่าน
เครื่องหมายคำถาม เครื่องหมายอัศเจรีย์ และเครื่องหมายขีดล่างต่อท้ายชื่อวิธีการอาจแก้ไขผลลัพธ์ได้
องค์ประกอบง่ายๆ:
_br
องค์ประกอบที่ซ้อนกัน:
_div do
_hr
end
องค์ประกอบที่มีข้อความ:
_h1 "My weblog"
องค์ประกอบที่มีคุณสมบัติ:
_img src: '/img/logo.jpg', alt: 'site logo'
องค์ประกอบที่มีทั้งข้อความและแอตทริบิวต์:
_a 'search', href: 'http://google.com'
องค์ประกอบที่มีคุณสมบัติบูลีน:
_input 'Cheese', type: 'checkbox', name: 'cheese', checked: true
องค์ประกอบที่มีลักษณะบูลีน (รูปแบบอื่น):
_input 'Cheese', :checked, type: 'checkbox', name: 'cheese'
องค์ประกอบที่มีคุณสมบัติเสริม (ละเว้น):
_tr class: nil
ข้อความ (อักขระมาร์กอัปจะถูกหลีก):
_ "<3"
ข้อความ (อาจมีมาร์กอัป):
_{"<em>hello</em>!!!"}
การนำเข้า HTML/XML:
_[Nokogiri::XML "<em>hello</em>"]
เนื้อหาผสม (เว้นวรรคอัตโนมัติ):
_p do
_ 'It is a'
_em 'very'
_ 'nice day.'
end
เนื้อหาผสม (ควบคุมพื้นที่):
_p! do
_ 'Source is on '
_a 'github', href: 'https://github.com/'
_ '.'
end
แทรกบรรทัดว่างระหว่างแถวใน HTML ที่ผลิต:
_tbody do
_tr_ do
_td 1
end
_tr_ do
_td 2
end
_tr_ do
_td 3
end
end
จับข้อยกเว้น:
_body? do
raise NotImplementedError.new('page')
end
ทางลัดแอตทริบิวต์คลาส (เทียบเท่ากับ class="front"):
_div.front do
end
ทางลัดแอตทริบิวต์ ID (เทียบเท่ากับ id="search"):
_div.search! do
end
รายการ/แถวที่สมบูรณ์สามารถกำหนดได้โดยใช้อาร์เรย์:
_ul %w(apple orange pear)
_ol %w(apple orange pear)
_table do
_tr %w(apple orange pear)
end
การวนซ้ำโดยพลการสามารถทำได้บน Enumerables:
_dl.colors red: '#F00', green: '#0F0', blue: '#00F' do |color, hex|
_dt color.to_s
_dd hex
end
โปรแกรมหลักทั่วไปจะสร้างเอาต์พุต HTML, JSON หรือข้อความธรรมดาตั้งแต่หนึ่งรายการขึ้นไป ซึ่งสามารถทำได้โดยการจัดเตรียมสิ่งใดสิ่งหนึ่งต่อไปนี้:
_html do
code
end
_xhtml do
code
end
_json do
code
end
_text do
code
end
_websocket do
code
end
สามารถวางโค้ด Ruby โดยพลการในแต่ละอันได้ พารามิเตอร์แบบฟอร์มพร้อมใช้งานเป็นตัวแปรอินสแตนซ์ (เช่น @name
) ค่าสภาพแวดล้อมโฮสต์ (CGI, Rack, Sinatra) สามารถเข้าถึงได้โดยใช้วิธีการของอ็อบเจ็กต์ _
เช่น _.headers
(CGI), _.set_cookie
(Rack), _.redirect
(Sinatra)
หากต้องการต่อท้ายเอาต์พุตที่ผลิต ให้ใช้วิธี _
ที่อธิบายไว้ด้านล่าง แอปพลิเคชันตัวอย่างอยู่ในบทช่วยสอน
การเรียกใช้วิธีการที่ขึ้นต้นด้วยอักขระบรรทัดต่ำแบบ Unicode ("_") จะสร้างแท็ก HTML เช่นเดียวกับตัวสร้างที่ใช้ไลบรารีนี้ แท็กเหล่านี้สามารถมีเนื้อหาข้อความและแอตทริบิวต์ได้ แท็กยังสามารถซ้อนกันได้ ลอจิกสามารถผสมกันได้อย่างอิสระ
Wunderbar รู้ว่าแท็ก HTML ใดที่ต้องปิดอย่างชัดเจนด้วยแท็กปิดท้ายที่แยกจากกัน (ตัวอย่าง: textarea
) และแท็กใดที่ไม่ควรปิดด้วยแท็กปิดท้ายที่แยกจากกัน (ตัวอย่าง: br
) นอกจากนี้ยังดูแลการอ้างอิง HTML และการหลีกเลี่ยงข้อโต้แย้งและข้อความ
ส่วนต่อท้ายหลังชื่อแท็กจะแก้ไขการประมวลผล
!
: ปิดการประมวลผลพิเศษทั้งหมด รวมถึงการเยื้อง?
: เพิ่มโค้ดเพื่อช่วยเหลือข้อยกเว้นและสร้างการย้อนกลับ_
: เพิ่มบรรทัดว่างเพิ่มเติมระหว่างแท็กนี้และรายการพี่น้อง วิธีการ " _
" มีจุดประสงค์หลายประการ การเรียกมันด้วยอาร์กิวเมนต์เดียวจะแทรกมาร์กอัปโดยคำนึงถึงการเยื้อง การแทรกมาร์กอัปโดยไม่คำนึงถึงการเยื้องข้อมูลทำได้โดยใช้ " _ << text
" มีการกำหนดวิธีการอำนวยความสะดวกอื่น ๆ จำนวนหนึ่ง:
_
: แทรกข้อความที่มีการเยื้องตรงกับเอาต์พุตปัจจุบัน_!
: แทรกข้อความโดยไม่เยื้อง_.post?
-- สิ่งนี้ถูกเรียกใช้ผ่าน HTTP POST หรือไม่_.system
-- เรียกใช้คำสั่งเชลล์ จับ stdin, stdout และ stderr_.submit
-- รันคำสั่ง (หรือบล็อก) เป็นกระบวนการ deamon_.xhtml?
-- ส่งออกเป็น XHTML? เมธอด _.system
รับแฮชเผื่อเลือกเป็นพารามิเตอร์ตัวสุดท้าย ซึ่งสามารถใช้เพื่อจัดเตรียมการตั้งค่าสำหรับเมธอด Process.spawn พื้นฐาน ตัวอย่างเช่น: ._system('pwd',{ system_opts: { chdir: dir } , system_env: { 'FOO' => 'BAR' } })
โปรดทราบว่าชื่อตัวแปรสภาพแวดล้อมต้องระบุเป็นสตริง ไม่ใช่สัญลักษณ์ ตัวเลือกเพิ่มเติมที่สามารถใช้ได้กับ _.system
ได้แก่:
:tag
- แท็ก HTML ที่จะใช้สำหรับอินพุต/เอาท์พุต ค่าเริ่มต้นเป็น pre
:bundlelines
- ว่าจะประมวลผลบรรทัดทั้งหมดสำหรับประเภทเอาต์พุตที่กำหนด (stderr, stdout ฯลฯ ) โดยเป็นส่วนหนึ่งของแท็กเดียว หากไม่ได้ระบุ จะมีค่าเริ่มต้นเป็น true
สำหรับแท็ก pre
มิฉะนั้นจะเป็น false
หากเป็น false
แต่ละบรรทัดของเอาต์พุตจะถูกประมวลผลแยกกันการเข้าถึงเมธอด ที่กำหนด โดยผู้สร้างทั้งหมด (โดยทั่วไปจะลงท้ายด้วยเครื่องหมายอัศเจรีย์) และวิธีการโมดูล Wunderbar ทั้งหมดสามารถเข้าถึงได้ด้วยวิธีนี้ ตัวอย่าง:
_.tag! :foo
: แทรกองค์ประกอบที่ชื่อสามารถเป็นแบบไดนามิกได้_.comment! "text"
: เพิ่มความคิดเห็น_.error 'Log message'
: เขียนข้อความไปยังบันทึกของเซิร์ฟเวอร์ ขีดล่างในชื่อองค์ประกอบและแอตทริบิวต์จะถูกแปลงเป็นขีดกลาง หากต้องการปิดใช้งานลักษณะการทำงานนี้ ให้แสดงชื่อแอตทริบิวต์เป็นสตริง และใช้ _.tag!
วิธีการตั้งชื่อองค์ประกอบ
XHTML แตกต่างจาก HTML ในการ Escape รูปแบบอินไลน์และองค์ประกอบสคริปต์ XHTML จะถอยกลับไปเป็นเอาต์พุต HTML เว้นแต่ตัวแทนผู้ใช้จะระบุว่ารองรับ XHTML ผ่านทางส่วนหัว HTTP Accept
นอกเหนือจากการประมวลผลองค์ประกอบ ข้อความ และคุณลักษณะเริ่มต้นแล้ว Wunderdar ยังกำหนดการประมวลผลเพิ่มเติมสำหรับสิ่งต่อไปนี้:
_head
: แทรก meta charset utf-8_svg
: แทรกเนมสเปซ svg_math
: แทรกเนมสเปซทางคณิตศาสตร์_coffeescript
: แปลง coffeescript เป็น JS และแทรกแท็กสคริปต์โปรดทราบว่าการเพิ่มเครื่องหมายอัศเจรีย์ที่ส่วนท้ายของชื่อแท็กจะปิดการทำงานนี้
หากหนึ่งในแอตทริบิวต์ที่ส่งผ่านการประกาศ _html
คือ :_width
จะมีการพยายามจัดวางข้อความใหม่เพื่อไม่ให้เกินความกว้างของบรรทัดนี้ สิ่งนี้จะไม่เกิดขึ้นหากจะส่งผลต่อสิ่งที่แสดงจริง
หากไม่มีองค์ประกอบย่อยสำหรับองค์ประกอบ html
ที่เป็น head
หรือ body
แท็กเหล่านี้จะถูกสร้างขึ้นสำหรับคุณ และองค์ประกอบย่อยที่เกี่ยวข้องจะถูกย้ายไปยังส่วนที่เหมาะสม หากเนื้อหามีองค์ประกอบ h1
และส่วน head
ไม่มี title
องค์ประกอบ title จะถูกสร้างขึ้นตามข้อความที่ให้กับองค์ประกอบ h1
แรก
การดำเนินการทั่วไปคือการส่งคืนแฮชหรืออาร์เรย์ของค่า แฮชคือชุดของคู่ชื่อ/ค่า และอาร์เรย์คือชุดของค่า
Wunderbar . json do
_content format_content ( @message . content )
_ @message , :created_at , :updated_at
_author do
_name @message . creator . name . familiar
_email_address @message . creator . email_address_with_name
_url url_for ( @message . creator , format : :json )
end
if current_user . admin?
_visitors calculate_visitors ( @message )
end
_comments @message . comments , :content , :created_at
_attachments @message . attachments do | attachment |
_filename attachment . filename
_url url_for ( attachment )
end
end
การเรียกใช้วิธีการที่ขึ้นต้นด้วยอักขระบรรทัดต่ำแบบ Unicode ("_") จะเพิ่มคู่คีย์/ค่าให้กับแฮชนั้น แฮชยังสามารถซ้อนกันได้ ลอจิกสามารถผสมกันได้อย่างอิสระ
วิธีการ " _
" มีจุดประสงค์หลายประการ
การเรียกมันด้วยอาร์กิวเมนต์หลายตัวจะทำให้อาร์กิวเมนต์แรกถือเป็นวัตถุและส่วนที่เหลือเป็นคุณลักษณะที่จะแยกออกมา
_ File.stat('foo'), :mtime, :size, :mode
การเรียกมันด้วยวัตถุ Enumerable เดียวและบล็อกจะทำให้อาร์เรย์ถูกส่งคืนตามการแมปแต่ละข้อโต้แย้งจากการแจงนับกับบล็อก
_([1,2,3]) {|n| n*n}
อาร์เรย์ยังสามารถสร้างได้โดยใช้วิธี _
:
_ 1
_ 2
_
วิธีการส่งกลับพร็อกซีไปยังวัตถุที่กำลังสร้าง สิ่งนี้มักจะมีประโยชน์เมื่อถูกเรียกโดยไม่มีข้อโต้แย้ง ตัวอย่าง:
_.sort!
_['foo'] = 'bar'
การผนวกเข้ากับเอาต์พุตสตรีมทำได้โดยใช้เมธอด _
ซึ่งเทียบเท่ากับ puts
_
วิธีการส่งกลับวัตถุที่พร็อกซีกระแสข้อมูลขาออกซึ่งให้การเข้าถึงวิธีการที่มีประโยชน์อื่น ๆ เช่น:
_.print 'foo'
_.printf "Hello %s!n", 'world'
การสนับสนุน WebSocket จำเป็นต้องติดตั้ง em-websocket
เว็บซ็อกเก็ตเป็นช่องทางสองทิศทาง _.send
หรือ _.push
สามารถใช้เพื่อส่งสตริงที่กำหนดเองได้ โดยทั่วไปแล้ว สามารถใช้เมธอดอาร์เรย์ JSON ที่อธิบายไว้ข้างต้นได้ทั้งหมด ข้อแตกต่างที่สำคัญคือแต่ละรายการจะถูกส่งทีละรายการและในขณะที่ถูกสร้างขึ้น
_.recv
หรือ _.pop
สามารถใช้เพื่อรับสตริงที่กำหนดเองได้ โดยทั่วไป _.subscribe
ใช้เพื่อลงทะเบียนบล็อกที่ใช้โทรกลับ
_.system
จะเรียกใช้คำสั่งที่กำหนดเอง บรรทัดของเอาต์พุตจะถูกส่งข้าม websocket เมื่อได้รับเป็นแฮชที่เข้ารหัส JSON ด้วยสองค่า: type
คือหนึ่งใน stdin
, stdout
หรือ stderr
; และ line
ที่มีเส้นนั้นอยู่ด้วย ถ้าคำสั่งเป็นอาร์เรย์ องค์ประกอบของอาร์เรย์จะถูกยกเว้นเป็นอาร์กิวเมนต์คำสั่งเชลล์ อาร์เรย์ที่ซ้อนกันอาจใช้เพื่อซ่อนองค์ประกอบจากการสะท้อนของคำสั่งไปยัง stdin ค่าศูนย์จะถูกละเว้น
ตัวเลือกสำหรับ _websocket
มีให้เป็นแฮช:
:port
จะเลือกหมายเลขพอร์ต โดยค่าเริ่มต้นจะเป็นการเลือกหมายเลขพอร์ตให้คุณ:sync
ที่ตั้งค่าเป็น false
จะทำให้เซิร์ฟเวอร์ WebSocket ทำงานเป็นกระบวนการ daemon ค่าเริ่มต้นนี้เป็น true
เมื่อเรียกใช้จากบรรทัดคำสั่ง และเป็น false
เมื่อเรียกใช้เป็น CGIbuffer_limit
จะจำกัดจำนวนรายการที่เก็บไว้และส่งไปยังไคลเอนต์ใหม่ตามคำขอที่เปิดอยู่ ค่าเริ่มต้นคือ 1
ค่าศูนย์จะปิดใช้งานการบัฟเฟอร์ ค่า nil
จะส่งผลให้มีการบัฟเฟอร์ไม่จำกัด หมายเหตุ: การบัฟเฟอร์ไม่จำกัดจนกว่าไคลเอ็นต์แรกจะเชื่อมต่อ Wunderbar จะหลีกเลี่ยงเอาต์พุต HTML และ JSON ทั้งหมดอย่างถูกต้อง ซึ่งช่วยขจัดปัญหาของการแทรก HTML หรือ JavaScript ซึ่งรวมถึงการเรียก _
เพื่อแทรกข้อความโดยตรง เว้นแต่ว่าก่อนหน้านี้จำเป็นต้องใช้ nokogiri
(ดูการขึ้นต่อกันเพิ่มเติมด้านล่าง) การเรียกเพื่อแทรกมาร์กอัป ( _{...}
) จะเป็นการหลีกมาร์กอัป
$USER
- รหัสผู้ใช้โฮสต์$PASSWORD
- รหัสผ่านโฮสต์ (หากผ่าน CGI และ HTTP_AUTHORIZATION)$HOME
- โฮมไดเร็กทอรี$SERVER
- ชื่อเซิร์ฟเวอร์$HOME
- โฮมไดเร็กตอรี่ของผู้ใช้$HOST
- โฮสต์เซิร์ฟเวอร์นอกจากนี้ ตัวแปรสภาพแวดล้อมต่อไปนี้จะถูกตั้งค่าหากยังไม่ได้ตั้งค่า:
HOME
HTTP_HOST
LANG
REMOTE_USER
ในที่สุด การเข้ารหัสภายนอกและภายในเริ่มต้นจะถูกตั้งค่าเป็น UTF-8
_.debug
: ข้อความแก้ไขข้อบกพร่อง_.info
: ข้อความแจ้งข้อมูล_.warn
: ข้อความเตือน_.error
: ข้อความแสดงข้อผิดพลาด_.fatal
: ข้อความแสดงข้อผิดพลาดร้ายแรง_.log_level
=: ตั้งค่าระดับการบันทึก (ค่าเริ่มต้น: :warn
)_.default_log_level
=: ตั้งค่า แต่อย่าแทนที่ระดับบันทึก_.logger
: ส่งคืนอินสแตนซ์ Logger เมื่อรันจากบรรทัดคำสั่ง จะสามารถระบุคู่ CGI name=value ได้ นอกจากนี้ ยังรองรับตัวเลือกต่อไปนี้:
--get
: คาดว่าจะมีเอาต์พุต HTML (HTTP GET)--post
: คาดว่าจะมีเอาต์พุต HTML (HTTP POST)--json
: คาดว่าจะมีเอาต์พุต JSON (คำขอ XML HTTP)--html
: บังคับให้เอาต์พุต HTML--prompt
หรือ --offline
: พรอมต์สำหรับคู่คีย์/ค่าโดยใช้ stdin--debug
, --info
, --warn
, --error
, --fatal
: ตั้งค่าระดับบันทึก--install=
path: สร้างสคริปต์ตัวตัดคำ suexec-callable--rescue
หรือ --backtrace
ทำให้สคริปต์ wrapper จับข้อผิดพลาด จำเป็นต้องใช้อัญมณีต่อไปนี้ตามฟังก์ชันที่คุณใช้:
wunderbar/websocket
ต้องใช้ em-websocket
wunderbar/markdown
จำเป็นต้องมี kramdown
ruby2js
เพิ่มการรองรับสคริปต์ที่เขียนเป็นบล็อกwunderbar/opal
จำเป็นต้องมี sourcify
ส่วนขยายที่มีชื่อเดียวกันจำเป็นต้องใช้อัญมณีต่อไปนี้:
coderay
- การเน้นไวยากรณ์opal
- คอมไพเลอร์ทับทิมถึงจาวาสคริปต์rack
- อินเตอร์เฟสเว็บเซิร์ฟเวอร์sinatra
- DSL สำหรับการสร้างเว็บแอปพลิเคชันหากติดตั้งอัญมณีต่อไปนี้จะสร้างผลลัพธ์ที่สะอาดและสวยงามยิ่งขึ้น:
nokogiri
ทำความสะอาดส่วน HTML ที่แทรกผ่าน <<
และ _{}
nokogumbo
ยังล้างแฟรกเมนต์ HTML ที่แทรกผ่าน <<
และ _{}
หากมีอัญมณีนี้ จะเลือกใช้ nokogiri
โดยตรงมากกว่าescape
การอ้างอิงคำสั่ง system
ที่สวยงามยิ่งขึ้น