الفرق بين المراجعتين ل"Rails/action view overview"
جميل-بيلوني (نقاش | مساهمات) (إنشاء الصفحة. هذه الصفحة من مساهمات "محمود أبو الحسن") |
(لا فرق)
|
مراجعة 09:47، 26 يناير 2019
نظرة عامة على وحدة العرض في ريلز
بعد قراءة هذا الدليل، ستعرف:
- ما هو إجراء العرض (Action View) وكيفية استخدامه مع ريلز.
- أفضل طريقة لاستخدام القوالب والجزئيات (partials) والتخطيطات.
- ما الذي يقدمه المساعدون عن طريق إجراء العرض.
- كيفية استخدام العروض المحلية.
ما هو إجراء العرض؟
في ريلز، تُعَالَج طلبات الويب من خلال وحدة التحكم وإجراء العرض. عادةً ما يقع على عاتق وحدة التحكم التواصل مع قاعدة البيانات وتنفيذ الإجراءات CRUD عند الضرورة؛ بعد ذلك، يكون إجراء العرض مسؤولًا عن تفسير (compiling) الاستجابة.
تُكتَب قوالب إجراء العرض باستخدام روبي المضمّنة بالوسوم التي تمزج مع HTML. لتجنب ازدحام القوالب بشيفرة نمطية، يوفر عدد من أصناف المساعد سلوكًا شائعًا للنماذج والتواريخ والسلاسل النصية. من السهل أيضًا إضافة مساعدين جدد إلى تطبيقك أثناء تطويره.
ملاحظة: ترتبط بعض ميزات الإجراء العرض بالسجل الفعال، ولكن هذا لا يعني أن إجراء العرض يعتمد على السجل الفعال. إجراء العرض هو حزمة مستقلة يمكن استخدامها مع أي نوع من مكتبات روبي.
استخدام إجراء العرض مع ريلز
هناك مجلد مرتبط في المجلد app/views لكل وحدة تحكم الذي يحتفظ بملفات القالب التي تشكل العروض المرتبطة بوحدة التحكم هذه. تُستخدَم هذه الملفات لعرض الشكل التي تنتج من كل إجراء وحدة تحكم.
دعونا نلقي نظرة على ما يفعله ريلز افتراضيَّا عند إنشاء مصدر جديد باستخدام المولد Scaffold:
$ bin/rails generate scaffold article
[...]
invoke scaffold_controller
create app/controllers/articles_controller.rb
invoke erb
create app/views/articles
create app/views/articles/index.html.erb
create app/views/articles/edit.html.erb
create app/views/articles/show.html.erb
create app/views/articles/new.html.erb
create app/views/articles/_form.html.erb
[...]
يوجد اصطلاح تسمية للعروض في ريلز. عادةً ما تشارك العروض اسمَها مع إجراء وحدة التحكم المرتبط، كما ترى أعلاه. على سبيل المثال، سيستخدم فهرس حدث وحدة التحكم article_controller.rb ملف العرض index.html.erb في المجلد app/views/articles. الملف HTML الكامل المعاد إلى العميل يتكون من مزيج من الملف ERB هذا، وقالب تخطيط يغلفه، وكل الجزئيات (partials) التي يشير إليها العرض. ضمن هذا الدليل، ستجد توثيقًا أكثر تفصيلًا حول كل من هذه المكونات الثلاثة.
القوالب والجزئيات والتخطيطات
كما ذكرنا، فإن ناتج HTML النهائي هو عبارة عن تركيبة تتألف من ثلاثة عناصر هي: القوالب والجزئيات والتخطيطات. فيما يلي نظرة عامة موجزة لكل منها.
القوالب
يمكن كتابة قوالب إجراء العرض بعدة طرق. إذا كان ملف القالب بامتداد erb.
، فإنه يستخدم خليطًا من ERB (روبي المضمَّنة [Embedded Ruby]) و HTML. إذا كان ملف القالب بامتداد builder.
، فستُستخدَم المكتبة Builder::XmlMarkup
.
يدعم ريلز أنظمة القوالب المتعددة ويستخدم امتدادًا للملف للتمييز بينها. على سبيل المثال، يملك الملف HTML المستخدِم لنظام القالب ERB الامتداد html.erb.
كامتداد للملف.
القالب ERB
داخل قالب ERB، يمكن تضمين شيفرة روبي باستخدام الوسم <% %>
والوسم <%= %>
. تُستخدَم الوسوم <% %>
لتنفيذ شيفرة روبي التي لا تعيد شيئًا، مثل الشروط أو الحلقات التكرارية أو الكُتَل، وتُستخدَم الوسوم <%= %>
عندما تريد الحصول على مخرجات من الشيفرة.
تأمل الحلقة التكرارية التالية للأسماء:
<h1>Names of all the people</h1>
<% @people.each do |person| %>
Name: <%= person.name %><br>
<% end %>
تنفَّذ الحلقة التكرارية باستخدام وسوم التضمين العادية (<% %>
) ويُدرَج الاسم في ملف HTML باستخدام وسوم تضمين المخرجات (<%= %>
). لاحظ أن هذا ليس مجرد اقتراح للاستخدام: لن تصيَّر دوال الإخراج العادية مثل print
و puts
في العرض باستخدام قوالب ERB. لذلك، ستكون الشيفرة التالية خطأً:
<%# WRONG %>
Hi, Mr. <% puts "Frodo" %>
لإزالة المسافات البيضاء السابقة واللاحقة، يمكنك استخدام <%- -%>
بدلًا من <%
و %>
.
Builder
القوالب Builder بديل أكثر قابلية للبرمجة عن القوالب ERB، وهي مفيدة بشكل خاص لتوليد محتوى XML. يُتَاح الكائن XmlMarkup
المسمى xml
تلقائيًا للقوالب ذات الامتداد builder.
.
هُنا بعض الأمثلة الأساسية:
xml.em("emphasized")
xml.em { xml.b("emph & bold") }
xml.a("A Link", "href" => "http://rubyonrails.org")
xml.target("name" => "compile", "option" => "fast")
التي تُنتِج:
<em>emphasized</em>
<em><b>emph & bold</b></em>
<a href="http://rubyonrails.org">A link</a>
<target option="fast" name="compile" />
سيُتَعامَل مع أي دالة تحوي كتلةً كوسم ترميز XML مع ترميز متداخل في الكتلة. على سبيل المثال، ما يلي:
xml.div {
xml.h1(@person.name)
xml.p(@person.bio)
}
قد ينتج شيئًا مثل:
<div>
<h1>David Heinemeier Hansson</h1>
<p>A product of Danish Design during the Winter of '79...</p>
</div>
فيما يلي مثال RSS كامل الطول مستخدم فعليًا في Basecamp:
xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
xml.channel do
xml.title(@feed_title)
xml.link(@url)
xml.description "Basecamp: Recent items"
xml.language "en-us"
xml.ttl "40"
for item in @recent_items
xml.item do
xml.title(item_title(item))
xml.description(item_description(item)) if item_description(item)
xml.pubDate(item_pubDate(item))
xml.guid(@person.firm.account.url + @recent_items.url(item))
xml.link(@person.firm.account.url + @recent_items.url(item))
xml.tag!("dc:creator", item.author_name) if item_has_creator?(item)
end
end
end
end
Jbuilder
إن قوالب Jbuilder عبارة عن جوهرة يُحسِّنُها فريق ريلز وتُضمَّن في Gemfile الافتراضي الخاص بريلز. هذه القوالب مشابهة للقوالب Builder، ولكنها تُستخدم لإنشاء JSON، بدلًا من XML.
إذا لم تملك هذه الجوهرة، يمكنك إضافتها إلى Gemfile بتنفيذ السطر التالي:
gem 'jbuilder'
يُتَاح كائن Jbuilder المسمى json تلقائيًا للقوالب ذات الامتداد jbuilder.
.
هنا مثال أساسي:
json.name("Alex")
json.email("alex@example.com")
ستُنتِج:
{
"name": "Alex",
"email": "alex@example.com"
}
راجع توثيق Jbuilder لمزيد من الأمثلة والمعلومات.
قالب التخزين المؤقت
بشكل افتراضي، ستُصرِّف ريلز كل قالب إلى دالة لتصييره وعرضه. عندما تُغيِّر قالبًا، سيفحص ريلز وقت تعديل الملف ويُعيد تصريفه في وضع التطوير.
الجزئيات
القوالب الجزئية (Partial templates) -تسمى "الجزئيات" (partials) عادةً- هي أداة أخرى لكسر عملية التصير إلى أجزاء أكثر قابلية للإدارة. باستخدام الجزئيات، يمكنك استخراج أجزاء من الشيفرة البرمجية من قوالبك لفصل الملفات وإعادة استخدامها أيضًا في جميع القوالب.
تسمية الجزئيات
لتصيير جزئية بفرض أنها جزءٌ من عرض، استخدم التابع render
ضمن العرض:
<%= render "menu" %>
سيصير هذا ملفًا باسم menu.html.erb_ في تلك النقطة داخل العرض الذي يصيَّر. لاحظ الشَرطة البادئة السفلية؛ تُسمَّى الجزئيات باستخدام شرطة بادئة سفلية لتمييزها عن العروض العادية، حتى لو أُشِير إليها بدون شَرطة سُفلية. هذا صحيح حتى عند سحب جزئية من مجلد آخر:
<%= render "shared/menu" %>
ستسحب هذه الشيفرة في الجزئية من app/views/shared/_menu.html.erb.
استخدام الجزئيات لتبسيط العروض
إحدى الطرق لاستخدام الجزئيات هو معاملتها على أنها مكافئةٌ للوظائف الفرعية أو طريقةٌ لنقل التفاصيل خارج العرض بحيث يمكنك فهم ما يجري بسهولة أكبر. على سبيل المثال، قد يكون لديك عرض يشبه هذا:
<%= render "shared/ad_banner" %>
<h1>Products</h1>
<p>Here are a few of our fine products:</p>
<% @products.each do |product| %>
<%= render partial: "product", locals: { product: product } %>
<% end %>
<%= render "shared/footer" %>
هنا، يمكن أن تحتوي الجزئيتان _ad_banner.html.erb و _footer.html.erb على محتوى يُشارَك بين العديد من الصفحات في تطبيقك. لست بحاجة إلى الاطلاع على تفاصيل هذه الأقسام عند التركيز على صفحة معينة.
تصيير بدون الخيارين partial
و locals
في المثال أعلاه، يأخذ render
خيارين هما: partial
و locals
. ولكن إذا كان هذان الخياران هما الخيارين اللذين تريد استعمالهما، فيمكنك تخطي استخدامهما ببساطة. على سبيل المثال، بدلًا من:
<%= render partial: "product", locals: { product: @product } %>
يمكنك أيضًا فِعل ما يلي:
<%= render "product", product: @product %>
الخياران as
و object
بشكل افتراضي، يحتوي ActionView::Partials::PartialRenderer
على كائنه الخاص في متغير محلي بنفس الاسم مثل القالب. لذلك، كتابة:
<%= render partial: "product" %>
ضمن الجزئية _product سيؤدي إلى الحصول على product@
في المتغير المحلي product
؛ أي كما لو أننا قد كتبنا:
<%= render partial: "product", locals: { product: @product } %>
يمكن استخدام الخيار object
لتحديد الكائن الذي يُعرَض مباشرة داخل الجزئية، وهو مفيد عندما يكون كائن القالب في مكان آخر (على سبيل المثال في متغير نسخة مختلف أو في متغير محلي).
على سبيل المثال، بدلًا من كتابة:
<%= render partial: "product", locals: { product: @item } %>
سنكتب:
<%= render partial: "product", object: @item %>
مع الخيار as
، يمكننا تحديد اسم مختلف للمتغير المحلي المذكور. على سبيل المثال، إذا أردنا أن يكون item
بدلًا من product
، فسنكتب ما يلي:
<%= render partial: "product", object: @item, as: "item" %>
هذا يعادل:
<%= render partial: "product", locals: { item: @item } %>
تصيير المجموعات
من الشائع جدًا أن يحتاج القالب إلى التكرار عبر مجموعة ما وأن يصيِّر قالبًا فرعيًا لكل عنصر من عناصره. يُنفِّذ هذا النمط كتابع وحيد يقبل مصفوفة ويصيِّر جزئيَّةً لكل عنصر من العناصر في تلك المصفوفة. لذلك، المثال التالي الذي يعرض جميع المنتجات:
<% @products.each do |product| %>
<%= render partial: "product", locals: { product: product } %>
<% end %>
يمكن إعادة كتابته في سطر واحد:
<%= render partial: "product", collection: @products %>
عند استدعاء جزئية ما مع مجموعة، تملك النسخ الفردية للجزئية حق الوصول إلى عضو المجموعة الذي يُصيَّر عبر متغير مسمى بعد الجزئية. في هذه الحالة، الجزئية هي product_، وضمنها يمكنك الرجوع إلى المنتج product
للحصول على عضو المجموعة الذي يُصيَّر.
يمكنك استخدام صيغة مختصرة لتصيير المجموعات. بافتراض أن @products
عبارة عن مجموعة من النسخ product
، يمكنك ببساطة كتابة ما يلي لتوليد النتيجة نفسها:
<%= render @products %>
يحدد ريلز اسم الجزئية المراد استخدامها من خلال النظر إلى اسم النموذج في المجموعة، هو Product
في هذه الحالة. في الواقع، يمكنك حتى تصيير مجموعة تتكون من نسخ لنماذج مختلفة باستخدام هذا الاختزال، وسيختار ريلز الجزئية المناسبة لكل عضو في المجموعة.
قوالب فاصلة
يمكنك أيضًا تحديد جزئية ثانية لتصييرها بين نسخ الجزئية الرئيسية باستخدام الخيار :spacer_template
:
<%= render partial: @products, spacer_template: "product_ruler" %>
سيصيِّر ريلز الجزئية product_ruler_ (مع عدم تمرير بيانات إليها) بين كل زوج من جزئيات product_.
التخطيطات
يمكن استخدام التخطيطات (Layouts) لتصيير قالب عرض شائع حول نتائج إجراءات وحدة التحكم في ريلز. عادة، سيكون لتطبيق ريلز بعض التخطيطات التي ستُصيَّر هذه الصفحات ضمنها. على سبيل المثال، قد يحتوي أحد المواقع على تخطيط واحد للمستخدم الذي سجل دخوله وآخر لأحد جوانب التسويق أو المبيعات في الموقع. قد يشمل تخطيط المستخدم المسجل على مستوى أعلى من التنقل يجب أن يكون موجودًا عبر العديد من إجراءات وحدة التحكم. قد يشمل تخطيط المبيعات لتطبيق SaaS مستوى تنقل أعلى لأشياء مثل صفحات "الأسعار" و"اتصل بنا". ينبغي أن تتوقع أن يكون لكل تخطيط شكل ومظهر مختلف. يمكنك القراءة عن التخطيطات بتفصيل أوسع في دليل التخطيطات والتصيير.
تخطيطات الجزئية
يمكن أن يكون للجزئيات (Partials) تخطيطات خاصة بهم مطبقة عليهم فقط. تختلف هذه التخطيطات عن تلك التي تُطَبَّق على إجراء وحدة التحكم، ولكنها تعمل بطريقة مماثلة.
لنفترض أننا نعرض مقالة على صفحة يجب أن تكون موجودة في <div>
لأغراض العرض. أولًا، سننشئ مقالة Article
جديدة:
Article.create(body: 'Partial Layouts are cool!')
في قالب العرض، سنعرض الجزئية article_ في تخطيط صندوقي (box layout): الملف articles/show.html.erb
<%= render partial: 'article', layout: 'box', locals: { article: @article } %>
التخطيط الصندوقي ببساطة يلف الجزئية article_ في عنصر <div>
:
الملف articles/_box.html.erb
<div class='box'>
<%= yield %>
</div>
لاحظ أن تخطيط الجزئية يمكنه الوصول إلى المتغير article
المحلي الذي مُرِّر عند استدعاء render
. ومع ذلك، على عكس التخطيطات التي على مستوى التطبيق، لا تزال التخطيطات الجزئية تحتوي على بادئة سُفلية.
يمكنك أيضًا تصيير كتلة من الشيفرة داخل تخطيط جزئية بدلًا من استدعاء yield
. على سبيل المثال، إذا لم تكن لدينا الجزئية article_، فيمكننا القيام بما يلي بدلًا من ذلك:
الملف articles/show.html.erb
<% render(layout: 'box', locals: { article: @article }) do %>
<div>
<p><%= article.body %></p>
</div>
<% end %>
لنفترض أننا نستخدم الجزئية _box نفسها مما سبق، فإن هذا سيولد نفس الناتج المولد من المثال السابق.
مسارات العرض
عند تصيير استجابة، تحتاج وحدة التحكم إلى تحديد مكان وجود العروض المختلفة. بشكل افتراضي، سيُنظر فقط داخل المجلد app/views.
يمكننا إضافة مواقع أخرى ومنحهم أولوية معينة عند استبيان المسارات باستخدام التابعين prepend_view_path
و append_view_path
.
إضافة سابقة لمسار العرض
يمكن أن يكون هذا مفيدًا على سبيل المثال، عندما نريد وضع العروض داخل مجلد مختلف عن النطاقات الفرعية.
يمكننا القيام بذلك باستخدام:
prepend_view_path "app/views/#{request.subdomain}"
بعد ذلك، سيظهر إجراء العرض أولًا في هذا المجلد عند استبيان العروض.
إضافة لاحقة لمسار العرض
وبالمثل، يمكننا إضافة لاحقة للمسارات بالشكل التالي:
append_view_path "app/views/direct"
سيضيف هذا المسار app/views/direct إلى نهاية مسارات البحث (lookup paths).
نظرة عامة على المساعدين الذين يوفرهم إجراء العرض
قيد العمل: ليس جميع المساعدين مذكورون هنا. للاطلاع على قائمة المساعدين الكاملة، انتقل إلى توثيق الواجهة البرمجية.
ما يلي هو ملخص قصير للمساعدين المتوفرين في إجراء العرض. يوصى بمراجعة توثيق الواجهة البرمجية، التي تغطي جميع المساعدين بمزيد من التفصيل، ولكن يجب أن يكون هذا بمثابة نقطة بداية جيدة.
المساعد AssetTagHelper
يوفر هذا النموذج دوالًّا لتوليد شيفرة HTML تربط العروض بالأصول (assets) مثل الصور وملفات جافاسكربت وملفات الأنماط وقارئي الخلاصات (feed readers).
بشكل افتراضي، يقترن ريلز بهذه الأصول على الاستضافة الحالية في المجلد العام، ولكن يمكنك توجيه ريلز للربط بالأصول من خادم أصول مخصص عن طريق تعيين config.action_controller.asset_host
في تكوين التطبيق، عادةً في الملف config/environments/production.rb. على سبيل المثال، لنفترض أن استضافة الأصول لديك هي assets.example.com:
config.action_controller.asset_host = "assets.example.com"
image_tag("rails.png") # => <img src="http://assets.example.com/images/rails.png" />
auto_discovery_link_tag
يعيد وسم رابط يمكن للمتصفحات وقارئي الخلاصات (feed readers) استخدامها للاكتشاف التلقائي لخلاصة RSS أو Atom أو JSON.
auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", { title: "RSS Feed" }) # =>
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="http://www.example.com/feed.rss" />
image_path
يَحسب المسار إلى أصل الصورة في المجلد app/assets/images. ستُمرر المسارات الكاملة من جذر المستند. يُستخدم داخليًا بواسطة image_tag
لبناء مسار الصورة.
image_path("edit.png") # => /assets/edit.png
ستُضاف بصمة (fingerprint) إلى اسم الملف إذا ضُبِطَ config.assets.digest إلى القيمة true.
image_path("edit.png") # => /assets/edit-2d1a2db63fc738690021fedb5a65b68e.png
image_url
يَحسب عنوان URL لأصل الصورة في المجلد app/assets/images. سيستدعي هذا التابع image_path
داخليًا ويدمجه مع استضافتك الحالية أو استضافة الأصول.
image_url("edit.png") # => http://www.example.com/assets/edit.png
image_tag
يعيد وسم HTML للصورة للمصدر. يمكن أن يكون المصدر مسارًا كاملًا أو ملفًا موجودًا في المجلد app/assets/images.
image_tag("icon.png") # => <img src="/assets/icon.png" />
javascript_include_tag
يعيد الوسم <script>
لكل من المصادر المعطاة. يمكنك تمرير اسم الملف (تحديد الامتداد .js اختياري) لملفات JavaScript الموجودة في المجلد app/assets/javascripts لتضمينها في الصفحة الحالية أو يمكنك تمرير المسار الكامل المتعلق بجذر المستند.
javascript_include_tag "common" # => <script src="/assets/common.js"></script>
javascript_path
يحسب المسار إلى أصل جافاسكربت في المجلد app/assets/javascripts. إذا لم يحتو اسم الملف المصدر على امتداد، فسيُلحَق .js
. ستُمرَّر المسارات الكاملة من جذر المستند. يستخدم داخليًا بواسطة javascript_include_tag
لإنشاء مسار شيفرة مكتوبة بلغة جافاسكربت.
javascript_path "common" # => /assets/common.js
javascript_url
يحسب عنوان URL لأصل جافاسكربت في المجلد app/assets/javascripts. سيستدعي هذا التابع javascript_path
داخليًا ويدمجه مع استضافتك الحالية أو استضافة الأصول.
javascript_url "common" # => http://www.example.com/assets/common.js
stylesheet_link_tag
يعيد وسم رابط ورقة أنماط للمصادر المحددة كوسائط. إذا لم تحدد لاحقة، فستستعمل اللاحقة .css
تلقائيًا.
stylesheet_link_tag "application" # => <link href="/assets/application.css" media="screen" rel="stylesheet" />
stylesheet_path
يحسب المسار إلى أصل ورقة الأنماط في المجلد app/assets/stylesheets. إذا لم يحتوِ اسم الملف المصدر على لاحقة، فستستعمل اللاحقة .css
. ستُمرَّر المسارات الكاملة من جذر المستند. يُستخدَم داخليًا بواسطة stylesheet_link_tag
لإنشاء مسار ورقة الأنماط.
stylesheet_path "application" # => /assets/application.css
stylesheet_url
يحسب عنوان URL لأصل ورقة أنماط في المجلد app/assets/stylesheets. سيستدعي هذا التابع stylesheet_path
داخليًا ويدمجه مع استضافتك الحالية أو استضافة الأصول.
stylesheet_url "application" # => http://www.example.com/assets/application.css
المساعد AtomFeedHelper
atom_feed
يجعل هذا المساعد بناء خلاصة Atom عمليةً سهلةً. إليك مثال كامل عن كيفية الاستخدام:
الملف config/routes.rb
resources :articles
الملف app/controllers/articles_controller.rb
def index
@articles = Article.all
respond_to do |format|
format.html
format.atom
end
end
الملف app/views/articles/index.atom.builder
atom_feed do |feed|
feed.title("Articles Index")
feed.updated(@articles.first.created_at)
@articles.each do |article|
feed.entry(article) do |entry|
entry.title(article.title)
entry.content(article.body, type: 'html')
entry.author do |author|
author.name(article.author_name)
end
end
end
end
المساعد BenchmarkHelper
benchmark
يسمح لك بقياس وقت تنفيذ كتلة برمجية في قالب ويسجل النتيجة في السجل. قم بلف هذه الكتلة حول العمليات التي تؤثر بشكل كبير على الأداء أو تسبب اختناقات محتملة لمعرفة الوقت الذي استغرقته العملية.
<% benchmark "Process data files" do %>
<%= expensive_files_operation %>
<% end %>
هذا من شأنه أن يضيف شيئًا مثل "Process data files (0.34523)" إلى السجل، والذي يمكنك استخدامه حينئذٍ لمقارنة الوقت الذي تستغرقه العملية مما يساعد على تحسين الأداء.
المساعد CacheHelper
cache
دالة للتخزين المؤقت لأجزاء من العرض بدلًا من كامل الإجراء أو الصفحة. هذه التقنية مفيدة للتخزين المؤقت مثل القوائم وقوائم مواضيع الأخبار وأجزاء من شيفرة HTML الثابتة وما إلى ذلك. تأخذ هذه دالة كتلة تحتوي على المحتوى الذي تريد تخزينه مؤقتًا. انظر AbstractController::Caching::Fragments
لمزيد من المعلومات.
<% cache do %>
<%= render "shared/footer" %>
<% end %>
المساعد CaptureHelper
capture
يتيح لك التابع capture
استخراج جزء من القالب إلى متغير. يمكنك بعد ذلك استخدام هذا المتغير في أي مكان ما في قوالبك أو تخطيطاتك.
<% @greeting = capture do %>
<p>Welcome! The date and time is <%= Time.now %></p>
<% end %>
يمكن استخدام المتغير الذي ألتُقِط في أي مكان آخر.
<html>
<head>
<title>Welcome!</title>
</head>
<body>
<%= @greeting %>
</body>
</html>
content_for
استدعاء التابع content_for
يخزن كتلة من الشيفرة في مُعرِّف لاستخدامها لاحقًا. يمكنك إجراء استدعاءات متلاحقة للمحتوى المخزن في قوالب أخرى أو في المخطط بتمرير المعرف كوسيط إلى yield
.
على سبيل المثال، لنفترض أن لدينا مخطط قياسي لتطبيق، ولكن أيضًا تتطلب صفحة خاصة شيفرة جافاسكربت محددة لا يحتاج إليها باقي الموقع. يمكننا استخدام content_for
لتضمين شيفرة جافاسكربت في صفحتنا الخاصة دون إثقال باقي الموقع بها.
الملف app/views/layouts/application.html.erb
<html>
<head>
<title>Welcome!</title>
<%= yield :special_script %>
</head>
<body>
<p>Welcome! The date and time is <%= Time.now %></p>
</body>
</html>
الملف app/views/articles/special.html.erb
<p>This is a special page.</p>
<% content_for :special_script do %>
<script>alert('Hello!')</script>
<% end %>
المساعد DateHelper
date_select
يعيد مجموعة من وسوم التحديد (واحد للسنة وواحد للشهر وواحد لليوم) المحددة مسبقًا للوصول إلى خاصية محددة تستند إلى التاريخ.
date_select("article", "published_on")
datetime_select
يعيد مجموعة من وسوم التحديد (واحد للسنة وواحد للشهر وواحد لليوم وواحد للساعة وواحد للدقيقة) محددة مسبقًا للوصول إلى خاصية محددة على أساس التاريخ والوقت.
datetime_select("article", "published_on")
distance_of_time_in_words
يُعد تقارير المسافة التقريبية في الوقت بين الكائنين Time
أو Date
أو بين أعداد صحيحة في واحدة الثانية. اضبِط include_seconds
إلى القيمة true
إذا كنت ترغب في الحصول على تقديرات تقريبية أكثر تفصيلًا.
distance_of_time_in_words(Time.now, Time.now + 15.seconds) # => less than a minute
distance_of_time_in_words(Time.now, Time.now + 15.seconds, include_seconds: true) # => less than 20 seconds
select_date
يعيد مجموعة من وسوم اختيار HTML (واحد للسنة وواحد للشهر وواحد لليوم) محددة مسبقًا مع التاريخ المعطى.
# توليد اختيار تاريخ معين افتراضيًّا إلى التاريخ المعطى (ستة أيام بعد تاريخ اليوم)
select_date(Time.today + 6.days)
# توليد اختيار تاريخ معين افتراضيًا إلى تاريخ اليوم
select_date()
select_datetime
يعيد مجموعة من وسوم اختيار HTML (واحد للسنة وواحد للشهر وواحد لليوم وواحد للساعة وواحد للدقيقة) محددة مسبقًا مع التاريخ والوقت المعطى.
# توليد اختيار تاريخ ووقت معينين افتراضيًا إلى القيمة المعطاة (أربعة أيام من اليوم)
select_datetime(Time.now + 4.days)
# توليد اختيار تاريخ ووقت معينين افتراضيًا إلى اليوم
select_datetime()
select_day
يعيد وسم اختيار يحتوي على خيارات لكل يوم من الأيام من 1 إلى 31 مع تحديد اليوم الحالي.
# توليد حقل اختيار من أجل الأيام معين افتراضيًا إلى اليوم في التاريخ المعطى
select_day(Time.today + 2.days)
# توليد حقل اختيار من أجل الأيام معين افتراضيًا إلى الرقم المعطى
select_day(5)
select_hour
يعيد وسم اختيار يحتوي على خيارات لكل ساعة من الساعات من 0 إلى 23 مع تحديد الساعة الحالية.
# توليد حقل اختيار من أجل الساعات يعين افتراضيًا إلى الساعات في الوقت المعطى
select_hour(Time.now + 6.hours)
select_minute
يعيد وسم اختيار يحتوي على خيارات لكل من الدقائق من 0 إلى 59 مع تحديد الدقيقة الحالية.
# توليد حقل اختيار من أجل الدقائق معين افتراضيًا إلى الدقائق في الوقت المعطى
select_minute(Time.now + 10.minutes)
select_month
يعيد وسم اختيار يحتوي على خيارات لكل من الأشهر من يناير حتى ديسمبر مع تحديد الشهر الحالي.
# Generates a select field for months that defaults to the current month
select_month(Date.today)
6.6.10 select_second
يعيد وسم اختيار يحتوي على خيارات لكل ثانية من الثواني من 0 إلى 59 مع تحديد الثاني الحالي.
# Generates a select field for seconds that defaults to the seconds for the time provided
select_second(Time.now + 16.seconds)
6.6.11 select_time
يعيد مجموعة من وسوم اختيار HTML (واحد للساعة وواحد للدقيقة).
# Generates a time select that defaults to the time provided
select_time(Time.now)
6.6.12 select_year
يعيد وسم اختيار مع خيارات لكل من السنوات الخمس على كل جانب من الحالية، والتي تُحدَّد. يمكن تغيير نصف قطر الخمس سنوات باستخدام: start_year و: end_year في الخيارات.
# Generates a select field for five years on either side of Date.today that defaults to the current year
select_year(Date.today)
# Generates a select field from 1900 to 2009 that defaults to the current year
select_year(Date.today, start_year: 1900, end_year: 2009)
6.6.13 time_ago_in_words
مثل distance_of_time_in_words، ولكن حيث يُعدَّل time_time إلى Time.now.
time_ago_in_words(3.minutes.from_now) # => 3 minutes
6.6.14 time_select
يعيد مجموعة من وسوم اختيار(واحد للساعة وواحد للدقيقة وواحد للثانية اختياريًا) محددة مسبقًا للدخول إلى سمة محددة تستند إلى الوقت. تُعد الإختيارات لتعيين معاملات متعددة إلى كائن سجل نشط.
# Creates a time select tag that, when POSTed, will be stored in the order variable in the submitted attribute
time_select("order", "submitted")
6.7 DebugHelper
يعيد وسم مسبق به كائن فُرِّغَ بواسطة YAML. هذا يُنشِئ طريقة سهلة القراءة لفحص كائن.
my_hash = { 'first' => 1, 'second' => 'two', 'third' => [1,2,3] }
debug(my_hash)
<pre class='debug_dump'>---
first: 1
second: two
third:
- 1
- 2
- 3
</pre>
6.8 FormHelper
صُمِّمَ مساعدو النماذج لجعل العمل مع النماذج أسهل بكثير مقارنة باستخدام عناصر HTML القياسية فقط من خلال توفير مجموعة من الدوال لإنشاء النماذج استنادًا إلى نماذجك. ينشئ هذا المساعد HTML للنماذج ، ويوفر طريقة لكل نوع من أنواع الإدخال (على سبيل المثال، نص، وكلمة المرور، واختيار، وما إلى ذلك). عند إرسال النموذج (أي عندما يضغط المستخدم على زر الإرسال أو تُستدعَى form.submit عبر جافاسكريبت) ، ستُجمع مدخلات النموذج في كائن المعاملات ثم تُعاد إلى وحدة التحكم.
هناك نوعان من مساعدي النموذج: أولئك الذين يعملون تحديدًا مع خصائص النموذج وتلك التي لا تعمل. يتعامل هذا المساعد مع تلك التي تعمل مع خصائص النموذج. لمشاهدة مثال على مساعدي النموذج الذين لا يعملون مع خصائص النموذج، راجع توثيق ActionView::Helpers::FormTagHelper.
تمنحك الدالة الأساسية لهذا المساعد، form_for، القدرة على إنشاء نموذج لمثيل نموذج ، على سبيل المثال، لنفترض أنك تمتلك نموذج شخص وتريد إنشاء مثيل جديد له:
# Note: a @person variable will have been created in the controller (e.g. @person = Person.new)
<%= form_for @person, url: { action: "create" } do |f| %>
<%= f.text_field :first_name %>
<%= f.text_field :last_name %>
<%= submit_tag 'Create' %>
<% end %>
سيكون HTML الذي أُنشِئَ لهذا:
<form class="new_person" id="new_person" action="/people" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓" />
<input type="hidden" name="authenticity_token" value="lTuvBzs7ANygT0NFinXj98tfw3Emfm65wwYLbUvoWsK2pngccIQSUorM2C035M9dZswXgWTvKwFS8W5TVblpYw==" />
<input type="text" name="person[first_name]" id="person_first_name" />
<input type="text" name="person[last_name]" id="person_last_name" />
<input type="submit" name="commit" value="Create" data-disable-with="Create" />
</form>
سيظهر كائن params الذي أُنشِئَ عند إرسال هذا النموذج:
{"utf8" => "✓", "authenticity_token" => "lTuvBzs7ANygT0NFinXj98tfw3Emfm65wwYLbUvoWsK2pngccIQSUorM2C035M9dZswXgWTvKwFS8W5TVblpYw==", "person" => {"first_name" => "William", "last_name" => "Smith"}, "commit" => "Create", "controller" => "people", "action" => "create"}
تحتوي تجزئة params على قيمة شخص متداخلة، وبالتالي يمكن الوصول إليها باستخدام params[:person] في وحدة التحكم.
6.8.1 check_box
يعيد وسم اختيار مربعات مصمم للوصول إلى خاصية محددة.
# Let's say that @article.validated? is 1:
check_box("article", "validated")
# => <input type="checkbox" id="article_validated" name="article[validated]" value="1" />
# <input name="article[validated]" type="hidden" value="0" />
6.8.2 fields_for
ينشئ نطاقًا حول كائن نموذج محدد مثل form_for، ولكن لا ينشئ وسوم النموذج نفسها. وهذا يجعل fields_for مناسبة لتحديد كائنات نماذج إضافية في نفس النموذج:
<%= form_for @person, url: { action: "update" } do |person_form| %>
First name: <%= person_form.text_field :first_name %>
Last name : <%= person_form.text_field :last_name %>
<%= fields_for @person.permission do |permission_fields| %>
Admin? : <%= permission_fields.check_box :admin %>
<% end %>
<% end %>
6.8.3 file_field
يعيد وسم إدخال تحميل ملف مصمم خصيصًا للوصول إلى خاصية محددة.
file_field(:user, :avatar)
# => <input type="file" id="user_avatar" name="user[avatar]" />
6.8.4 form_for
يُنشِئ نموذجًا ونطاقًا حول كائن نموذج محدد يُستخدم كأساس للاستعلام عن قيم الحقول.
<%= form_for @article do |f| %>
<%= f.label :title, 'Title' %>:
<%= f.text_field :title %><br>
<%= f.label :body, 'Body' %>:
<%= f.text_area :body %><br>
<% end %>
يعيد وسم إدخال مخفي مصمم للوصول إلى خاصية محددة.
hidden_field(:user, :token)
# => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />
6.8.6 label
يعيد وسم تسمية مصمم لتسمية حقل إدخال لخاصية محددة.
label(:article, :title)
# => <label for="article_title">Title</label>
6.8.7 password_field
يعيد وسم إدخال من نوع "كلمة المرور" مصممةللوصول إلى خاصية محددة.
password_field(:login, :pass)
# => <input type="text" id="login_pass" name="login[pass]" value="#{@login.pass}" />
6.8.8 radio_button
يعيد وسم زر الراديو للدخول إلى خاصية محددة.
# Let's say that @article.category returns "rails":
radio_button("article", "category", "rails")
radio_button("article", "category", "java")
# => <input type="radio" id="article_category_rails" name="article[category]" value="rails" checked="checked" />
# <input type="radio" id="article_category_java" name="article[category]" value="java" />
6.8.9 text_area
يعيد مجموعة وسوم فتح وإغلاق textarea مصممة خصيصًا للوصول لخاصية محددة.
text_area(:comment, :text, size: "20x30")
# => <textarea cols="20" rows="30" id="comment_text" name="comment[text]">
# #{@comment.text}
# </textarea>
6.8.10 text_field
يعيد وسم إدخال من النوع "نص" مخصص للوصول لخاصية محددة.
text_field(:article, :title)
# => <input type="text" id="article_title" name="article[title]" value="#{@article.title}" />
6.8.11 email_field
يعيد وسم إدخال من النوع "بريد الإلكتروني" مخصص للوصول لخاصية محددة.
email_field(:user, :email)
# => <input type="email" id="user_email" name="user[email]" value="#{@user.email}" />
6.8.12 url_field
يعيد وسم إدخال من النوع "url" مخصص للوصول لخاصية محددة.
url_field(:user, :url)
# => <input type="url" id="user_url" name="user[url]" value="#{@user.url}" />
6.9 FormOptionsHelper
يوفر عددًا من الدوال لتحويل أنواع مختلفة من الحاويات إلى مجموعة من وسم الاختيار.
6.9.1 collection_select
يعيد وسوم التحديد والاختيار لتجميع قيم الإعادة الحالية للدالة لفئة الكائن.
مثال بنية الكائن للاستخدام مع هذه الدالة:
class Article < ApplicationRecord
belongs_to :author
end
class Author < ApplicationRecord
has_many :articles
def name_with_initial
"#{first_name.first}. #{last_name}"
end
end
استخدام بسيط (تحديد المؤلف المرتبط لمقالة المادة، article@):
collection_select(:article, :author_id, Author.all, :id, :name_with_initial, { prompt: true })
إذا كان article.author_id@ واحدًا، فسيعيد هذا:
<select name="article[author_id]">
<option value="">Please select</option>
<option value="1" selected="selected">D. Heinemeier Hansson</option>
<option value="2">D. Thomas</option>
<option value="3">M. Clark</option>
</select>
6.9.2 collection_radio_buttons
يعيد وسوم radio_button لتجميع قيم الإعادة الحالية للدالة لفئة الكائن.
مثال بنية الكائن للاستخدام مع هذه الدالة:
class Article < ApplicationRecord
belongs_to :author
end
class Author < ApplicationRecord
has_many :articles
def name_with_initial
"#{first_name.first}. #{last_name}"
end
end
استخدام بسيط (تحديد المؤلف المرتبط لمقالة المادة، article@):
collection_radio_buttons(:article, :author_id, Author.all, :id, :name_with_initial)
إذا كان article.author_id@ واحدًا، فسيعيد هذا:
<input id="article_author_id_1" name="article[author_id]" type="radio" value="1" checked="checked" />
<label for="article_author_id_1">D. Heinemeier Hansson</label>
<input id="article_author_id_2" name="article[author_id]" type="radio" value="2" />
<label for="article_author_id_2">D. Thomas</label>
<input id="article_author_id_3" name="article[author_id]" type="radio" value="3" />
<label for="article_author_id_3">M. Clark</label>
6.9.3 collection_check_boxes
يعيد وسوم check_box لتجميع قيم الإعادة الحالية للدالة لفئة الكائن.
مثال بنية الكائن للاستخدام مع هذه الدالة:
class Article < ApplicationRecord
has_and_belongs_to_many :authors
end
class Author < ApplicationRecord
has_and_belongs_to_many :articles
def name_with_initial
"#{first_name.first}. #{last_name}"
end
end
استخدام بسيط (تحديد المؤلفين المرتبطين لمثيل المادة، article@):
collection_check_boxes(:article, :author_ids, Author.all, :id, :name_with_initial)
إذا كان article.author_id@ واحدًا، فسيعيد هذا:
<input id="article_author_ids_1" name="article[author_ids][]" type="checkbox" value="1" checked="checked" />
<label for="article_author_ids_1">D. Heinemeier Hansson</label>
<input id="article_author_ids_2" name="article[author_ids][]" type="checkbox" value="2" />
<label for="article_author_ids_2">D. Thomas</label>
<input id="article_author_ids_3" name="article[author_ids][]" type="checkbox" value="3" />
<label for="article_author_ids_3">M. Clark</label>
<input name="article[author_ids][]" type="hidden" value="" />
6.9.4 option_groups_from_collection_for_select
يعيد سلسلة وسوم اختيار مثل options_from_collection_for_select، لكن يجمعهم بوسوم optgroup استنادًا إلى علاقات الكائنات الخاصة بالوسائط.
مثال بنية الكائن للاستخدام مع هذه الدالة:
class Continent < ApplicationRecord
has_many :countries
# attribs: id, name
end
class Country < ApplicationRecord
belongs_to :continent
# attribs: id, name, continent_id
end
استخدام بسيط:
option_groups_from_collection_for_select(@continents, :countries, :name, :id, :name, 3)
الناتج المحتمل:
<optgroup label="Africa">
<option value="1">Egypt</option>
<option value="4">Rwanda</option>
...
</optgroup>
<optgroup label="Asia">
<option value="3" selected="selected">China</option>
<option value="12">India</option>
<option value="5">Japan</option>
...
</optgroup>
ملاحظة: يعاد فقط وسوم الخيارات و optgroup، لذلك لا يزال يتعين عليك تجميع الناتج في وسم تحديد مناسب.
6.9.5 options_for_select
يقبل حاوية (تجزئة، مصفوفة، enumerable، نوعك) ويعيد سلسلة من وسوم الخيارات.
options_for_select([ "VISA", "MasterCard" ])
# => <option>VISA</option> <option>MasterCard</option>
ملاحظة: تُعَاد وسوم الخيارات فقط، يجب عليك تجميع هذا الاستدعاء في وسم تحديد HTML العادي.
6.9.6 options_from_collection_for_select
يعيد سلسلة وسوم اختيار عولجت بواسطة التكرار عبر المجموعة وتعيين نتيجة استدعاء value_method كقيمة الخيار و text_method كنص الخيار.
# options_from_collection_for_select(collection, value_method, text_method, selected = nil)
على سبيل المثال، تخيل حلقة تتكرر على كل شخص في @project.people لتوليد وسم إدخال:
options_from_collection_for_select(@project.people, "id", "name")
# => <option value="#{person.id}">#{person.name}</option>
ملاحظة: تُعَاد وسوم الخيارات فقط، يجب عليك تجميع هذا الاستدعاء في وسم تحديد HTML العادي.
6.9.7 select
يُنشئ وسم تحديد وسلسلة من وسوم الخيارت للكائن والأسلوب المُقدَّمين.
مثال
select("article", "person_id", Person.all.collect { |p| [ p.name, p.id ] }, { include_blank: true })
إذا كان article.author_id@ واحدًا، فسيصبح هذا:
<select name="article[person_id]">
<option value=""></option>
<option value="1" selected="selected">David</option>
<option value="2">Eileen</option>
<option value="3">Rafael</option>
</select>
6.9.8 time_zone_options_for_select
يعيد سلسلة وسوم اختيار إلى حد كبير في أي منطقة زمنية في العالم.
6.9.9 time_zone_select
يعيد وسوم تحديد واختيار للكائن والدالة المعينَين، باستخدام time_zone_options_for_select لإنشاء قائمة وسوم الخيارات.
time_zone_select("user", "time_zone")
6.9.10 date_field
يعيد وسم إدخال من النوع "تاريخ" مصمم للوصول إلى خاصية محددة.
date_field("user", "dob")
6.10 FormTagHelper
يوفر عددًا من الدوال لإنشاء وسوم النموذج التي لا تعتمد على كائن Active Record المعينة إلى القالب مثل FormHelper. بدلاً من ذلك، يمكنك تقديم الأسماء والقيم يدويًا.
6.10.1 check_box_tag
ينشئ وسوم إدخال نموذج مربع الاختيار.
check_box_tag 'accept'
# => <input id="accept" name="accept" type="checkbox" value="1" />
6.10.2 field_set_tag
ينشئ مجموعة حقول لتجميع عناصر نموذج HTML.
<%= field_set_tag do %>
<p><%= text_field_tag 'name' %></p>
<% end %>
# => <fieldset><p><input id="name" name="name" type="text" /></p></fieldset>
6.10.3 file_field_tag
يُنشئ حقل تحميل الملفات.
<%= form_tag({ action: "post" }, multipart: true) do %>
<label for="file">File to Upload</label> <%= file_field_tag "file" %>
<%= submit_tag %>
<% end %>
مثال على الناتج:
file_field_tag 'attachment'
# => <input id="attachment" name="attachment" type="file" />
6.10.4 form_tag
يبدأ وسم نموذج يوجه الإجراء إلى عنوان URL هُيِّئ باستخدام url_for_options تمامًا مثل ActionController :: Base # url_for.
<%= form_tag '/articles' do %>
<div><%= submit_tag 'Save' %></div>
<% end %>
# => <form action="/articles" method="post"><div><input type="submit" name="submit" value="Save" /></div></form>
ينشئ حقل إدخال نموذج مخفي يستخدم لنقل البيانات التي قد تفقد بسبب انعدام الثبات في HTTP أو البيانات التي يجب أن تكون مخفية عن المستخدم.
hidden_field_tag 'token', 'VUBJKB23UIVI1UU1VOBVI@'
# => <input id="token" name="token" type="hidden" value="VUBJKB23UIVI1UU1VOBVI@" />
6.10.6 image_submit_tag
يعرض صورة عند النقر عليها سترسل النموذج.
image_submit_tag("login.png")
# => <input src="/images/login.png" type="image" />
6.10.7 label_tag
ينشئ حقل التسمية.
label_tag 'name'
# => <label for="name">Name</label>
6.10.8 password_field_tag
ينشئ حقل كلمة مرور ، حقل نص مُغَطَّى يخفي إدخالات المستخدمين خلف قناع.
password_field_tag 'pass'
# => <input id="pass" name="pass" type="password" />
6.10.9 radio_button_tag
ينشئ زر راديو، استخدم مجموعات من أزرار راديو المسماة أيضًا للسماح للمستخدمين بالاختيار من بين مجموعة من الخيارات.
radio_button_tag 'gender', 'male'
# => <input id="gender_male" name="gender" type="radio" value="male" />
6.10.10 select_tag
ينشئ مربع اختيار القائمة المنسدلة.
select_tag "people", "<option>David</option>"
# => <select id="people" name="people"><option>David</option></select>
6.10.11 submit_tag
ينشئ زر إرسال مع النص المقدم كتسمية توضيحية.
submit_tag "Publish this article"
# => <input name="commit" type="submit" value="Publish this article" />
6.10.12 text_area_tag
ينشئ منطقة إدخال النص؛ استخدم textarea لإدخالات نصية أطول مثل مشاركات المدونات أو الأوصاف.
text_area_tag 'article'
# => <textarea id="article" name="article"></textarea>
6.10.13 text_field_tag
ينشئ حقل نص قياسي، استخدم حقول النص هذه لإدخال أجزاء أصغر من النص مثل اسم المستخدم أو استعلام البحث.
text_field_tag 'name'
# => <input id="name" name="name" type="text" />
6.10.14 email_field_tag
ينشئ حقل إدخال قياسي لنوع البريد الإلكتروني.
email_field_tag 'email'
# => <input id="email" name="email" type="email" />
6.10.15 url_field_tag
ينشئ حقل إدخال قياسي لنوع عنوان url.
url_field_tag 'url'
# => <input id="url" name="url" type="url" />
6.10.16 date_field_tag
ينشئ حقل إدخال قياسي من نوع التاريخ.
date_field_tag "dob"
# => <input id="dob" name="dob" type="date" />
6.11 JavaScriptHelper
يوفر العمل مع JavaScript في عروضك.
6.11.1 escape_javascript
يهمل عائدات الناقل والاقتباسات الفردية والزوجية لشرائح جافاسكريبت
6.11.2 javascript_tag
يعيد وسم JavaScript يحوي الشيفرة المتوفرة.
javascript_tag "alert('All is good')"
<script>
//<![CDATA[
alert('All is good')
//]]>
</script>
6.12 NumberHelper
يوفر دوال لتحويل الأرقام إلى سلاسل منسقة. تُوفَّر دوال لأرقام الهاتف، وللعملة، وللنسبة المئوية، وللدقة، وللتدوين الموضعي، ولحجم الملف.
6.12.1 number_to_currency
ينسق رقم في سلسلة عملة (على سبيل المثال، $ 13.65).
number_to_currency(1234567890.50) # => $1,234,567,890.50
6.12.2 number_to_human_size
ينسق البايتات في الحجم إلى تمثيل أكثر قابلية للفهم. مفيد في الإبلاغ عن أحجام الملفات للمستخدمين.
number_to_human_size(1234) # => 1.2 KB
number_to_human_size(1234567) # => 1.2 MB
6.12.3 number_to_percentage
ينسق رقم كسلسلة مئوية.
number_to_percentage(100, precision: 0) # => 100%
6.12.4 number_to_phone
ينسق رقم إلى رقم هاتف (الولايات المتحدة بشكل افتراضي).
number_to_phone(1235551234) # => 123-555-1234
6.12.5 number_with_delimiter
ينسق رقم مع الآلاف مجمعة باستخدام مُحدِّد.
number_with_delimiter(12345678) # => 12,345,678
6.12.6 number_with_precision
يُنشئ رقمًا بمستوى الدقة المحدد، والذي يُعَيَّن افتراضيًا على 3.
number_with_precision(111.2345) # => 111.235
number_with_precision(111.2345, precision: 2) # => 111.23
6.13 SanitizeHelper
توفر الوحدة النمطية SanitizeHelper مجموعة من الدوال لإزالة نص عناصر HTML غير مرغوب فيها.
6.13.1 sanitize
يشفر المساعد sanitize هذا HTML كل الوسومات وتجريد كل الخصائص غير المسموح بها بشكل محدد.
sanitize @article.body
إذا مُررت خيارات إما:attributes أو:tags، لا يُسمح إلا بالخصائص والوسوم المذكورة فقط ولا شيء آخر.
sanitize @article.body, tags: %w(table tr td), attributes: %w(id class style)
لتغيير الإعدادات الافتراضية لاستخدامات متعددة، على سبيل المثال، إضافة وسوم الجدول إلى الإعدادات الافتراضية:
class Application < ريلز::Application
config.action_view.sanitized_allowed_tags = 'table', 'tr', 'td'
end
6.13.2 sanitize_css(style)
تطهير كتلة من شيفرة CSS.
6.13.3 strip_links(html
يزيل وسوم الرابط من النص وترك نص الرابط فقط .
strip_links('<a href="http://rubyonrails.org">Ruby on ريلز</a>')
# => Ruby on ريلز
strip_links('emails to <a href="mailto:me@email.com">me@email.com</a>.')
# => emails to me@email.com.
strip_links('Blog: <a href="http://myblog.com/">Visit</a>.')
# => Blog: Visit.
6.13.4 strip_tags(html)
يزيل كل وسوم HTML من html، شامِلًا التعليقات. تعمل هذه الوظيفة بواسطة جوهرة rails-html-sanitizer.
strip_tags("Strip <i>these</i> tags!")
# => Strip these tags!
strip_tags("<b>Bold</b> no more! <a href='more.html'>See more</a>")
# => Bold no more! See more
NB: قد لا يزال الناتج يحتوي على أحرف "<" و ">" و "&" غير متجاورة ويشوش المتصفحات.
6.14 CsrfHelper
يعيد وسوم meta "csrf-param" و"csrf-token" مع اسم معامل حماية طلب التزوير عبر الموقع والرمز، على التوالي.
<%= csrf_meta_tags %>
تولد النماذج العادية الحقول المخفية حتى لا تستخدم هذه الوسوم. يمكن العثور على مزيد من التفاصيل في دليل أمن ريلز.
7 عروض مُحددَّة الموقع
يحوي حدث العرض على قابلية عرض قوالب مختلفة استنادًا إلى الإعدادات المحلية الحالية.
على سبيل المثال، افترض أن لديك MaterialController مع حدث عرض. بشكل افتراضيًا، سيعرض استدعاء هذا الحدث app/views/articles/show.html.erb. ولكن إذا عيَّنت I18n.locale =: de ، فسيُعرَض app/views/articles/show.de.html.erb بدلاً من ذلك. إذا كان القالب المترجم غير موجود، فستُستخدًم النسخة غير المزخرفة. هذا يعني أنك لست مطالبًا بتقديم عروض مُحددَّة الموقع لجميع الحالات، ولكن ستُفضَّل وتستخدٍم إذا كانت متوفرة.
يمكنك استخدام نفس التقنية لتوطين ملفات الإنقاذ في دليلك العام. على سبيل المثال، يتيح لك إعداد I18n.locale =: de وإنشاء public /500.de.html و public /404.de.html الحصول على صفحات إنقاذ محلية.
نظرًا لأن ريلز لا يقيد الرموز المستخدمة لتعيين I18n.locale، يمكنك الاستفادة من هذا النظام لعرض محتوى مختلف اعتمادًا على أي شيء يعجبك. على سبيل المثال، لنفترض أن لديك بعض المستخدمين "الخبراء" الذين يمكنهم مشاهدة صفحات مختلفة من المستخدمين "العاديين". يمكنك إضافة ما يلي إلى app/controllers/application.rb:
before_action :set_expert_locale
def set_expert_locale
I18n.locale = :expert if current_user.expert?
end
بعد ذلك، يمكنك إنشاء عروض خاصة مثل app/views/articles/show.expert.html.erb والتي تُعرَض فقط للمستخدمين الخبراء.
يمكنك قراءة المزيد عن تدويل واجهة برمجة تطبيقات ريلز (I18n) هنا.