Rails/action view overview

من موسوعة حسوب
< Rails
مراجعة 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 &amp; 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="&#x2713;" />

 <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 %>

6.8.5 hidden_field

يعيد وسم إدخال مخفي مصمم للوصول إلى خاصية محددة.

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>

6.10.5 hidden_field_tag

ينشئ حقل إدخال نموذج مخفي يستخدم لنقل البيانات التي قد تفقد بسبب انعدام الثبات في 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) هنا.