Ruby on Rails 5.2 - ActionView::Layouts

मॉड्यूल एक्शन व्यू :: लेआउट




ruby

मॉड्यूल एक्शन व्यू :: लेआउट

शामिल मॉड्यूल:
ActionView::Rendering

बार-बार सेटअप में बदलाव को अलग-अलग करने के लिए Layouts कई हेडर में साझा हेडर और फुटर सहित आम पैटर्न को उलट देते हैं। समावेशन पैटर्न में इस तरह दिखने वाले पृष्ठ हैं:

<%= render "shared/header" %>
Hello World
<%= render "shared/footer" %>

यह दृष्टिकोण सामान्य संरचनाओं को बदलती सामग्री से अलग रखने का एक सभ्य तरीका है, लेकिन यह क्रिया है और यदि आप कभी भी इन दोनों की संरचना को बदलना चाहते हैं, तो आपको सभी टेम्पलेट्स को बदलना होगा।

लेआउट के साथ, आप इसे चारों ओर फ्लिप कर सकते हैं और सामान्य संरचना को जान सकते हैं कि बदलती सामग्री कहां डालनी है। इसका अर्थ है कि शीर्ष लेख और पाद लेख केवल एक ही स्थान पर उल्लिखित हैं, जैसे:

// The header part of this layout
<%= yield %>
// The footer part of this layout

और फिर आपके पास सामग्री पृष्ठ हैं जो इस तरह दिखते हैं:

hello world

रेंडरिंग समय में, सामग्री पृष्ठ की गणना की जाती है और फिर उसे इस तरह लेआउट में डाला जाता है:

// The header part of this layout
hello world
// The footer part of this layout

साझा किए गए चर तक पहुंच

Layouts में सामग्री पृष्ठों में निर्दिष्ट चर तक पहुंच है और इसके विपरीत। यह आपको उन संदर्भों के साथ लेआउट करने की अनुमति देता है, जो समय प्रदान करने से पहले नहीं होगा:

<h1><%= @page_title %></h1>
<%= yield %>

... और सामग्री पृष्ठ जो इन सन्दर्भों को पूरा करने के समय प्रदान करते हैं:

<% @page_title = "Welcome" %>
Off-world colonies offers you a chance to start a new life

प्रतिपादन के बाद परिणाम है:

<h1>Welcome</h1>
Off-world colonies offers you a chance to start a new life

लेआउट असाइनमेंट

आप या तो लेआउट घोषित कर सकते हैं (लेआउट क्लास विधि का उपयोग करके) या इसे अपने नियंत्रक के समान नाम दें, और इसे app/views/layouts । यदि एक उपवर्ग में निर्दिष्ट लेआउट नहीं है, तो यह सामान्य रूबी विरासत का उपयोग करके अपने लेआउट को विरासत में देता है।

उदाहरण के लिए, यदि आपके पास PostController और app/views/layouts/posts.html.erb नाम का कोई टेम्प्लेट है, तो उस टेम्पलेट का उपयोग पोस्टकंट्रोलर में सभी क्रियाओं के लिए किया जाएगा और पोस्टकंट्रोलर से प्राप्त होने वाले नियंत्रकों के लिए।

यदि आप एक मॉड्यूल का उपयोग करते हैं, उदाहरण के लिए वेबलॉग :: पोस्टकंट्रोलर, तो आपको app/views/layouts/weblog/posts.html.erb नामक टेम्पलेट की आवश्यकता होगी।

चूंकि आपके सभी कंट्रोलर ApplicationController से विरासत में मिले हैं, इसलिए यदि कोई अन्य लेआउट निर्दिष्ट या प्रदान नहीं किया गया है, तो वे app/views/layouts/application.html.erb उपयोग करेंगे।

वंशानुक्रम उदाहरण

class BankController < ActionController::Base
  # bank.html.erb exists

class ExchangeController < BankController
  # exchange.html.erb exists

class CurrencyController < BankController

class InformationController < BankController
  layout "information"

class TellerController < InformationController
  # teller.html.erb exists

class EmployeeController < InformationController
  # employee.html.erb exists
  layout nil

class VaultController < BankController
  layout :access_level_layout

class TillController < BankController
  layout false

इन उदाहरणों में, हमारे पास तीन निहित लुकअप परिदृश्य हैं:

  • BankController "बैंक" लेआउट का उपयोग करता है।

  • ExchangeController "एक्सचेंज" लेआउट का उपयोग करता है।

  • CurrencyController BankController से लेआउट विरासत में मिला है।

हालाँकि, जब कोई लेआउट स्पष्ट रूप से सेट होता है, तो स्पष्ट रूप से सेट लेआउट जीत जाता है:

  • InformationController स्पष्ट रूप से सेट "सूचना" लेआउट का उपयोग करता है।

  • TellerController "सूचना" लेआउट का भी उपयोग करता है, क्योंकि माता-पिता ने इसे स्पष्ट रूप से निर्धारित किया है।

  • EmployeeController "कर्मचारी" लेआउट का उपयोग करता है, क्योंकि यह अभिभावक विन्यास को रीसेट करने के लिए लेआउट को nil सेट करता है।

  • VaultController एक लेआउट को गतिशील रूप से access_level_layout विधि VaultController चुनता है।

  • TillController एक लेआउट का उपयोग नहीं करता है।

लेआउट के प्रकार

Layouts मूल रूप से केवल नियमित टेम्पलेट हैं, लेकिन इस टेम्पलेट का नाम सांख्यिकीय रूप से निर्दिष्ट करने की आवश्यकता नहीं है। कभी-कभी आप रनटाइम जानकारी के आधार पर लेआउट को वैकल्पिक करना चाहते हैं, जैसे कि कोई व्यक्ति लॉग इन है या नहीं। यह या तो एक प्रतीक के रूप में एक विधि संदर्भ निर्दिष्ट करके या एक इनलाइन विधि (एक खरीद के रूप में) का उपयोग करके किया जा सकता है।

विधि संदर्भ परिवर्तनीय लेआउट के लिए पसंदीदा तरीका है और इसका उपयोग इस तरह किया जाता है:

class WeblogController < ActionController::Base
  layout :writers_and_readers

  def index
    # fetching posts
  end

  private
    def writers_and_readers
      logged_in? ? "writer_layout" : "reader_layout"
    end
end

अब जब सूचकांक कार्रवाई के लिए एक नया अनुरोध संसाधित किया जाता है, तो लेआउट इस बात पर निर्भर करेगा कि एक्सेस करने वाला व्यक्ति लॉग इन है या नहीं।

यदि आप इनलाइन विधि का उपयोग करना चाहते हैं, जैसे कि एक खरीद, कुछ इस तरह से करें:

class WeblogController < ActionController::Base
  layout proc { |controller| controller.logged_in? ? "writer_layout" : "reader_layout" }
end

यदि किसी तर्क को खरीद के लिए नहीं दिया जाता है, तो इसका मूल्यांकन वैसे भी वर्तमान नियंत्रक के संदर्भ में किया जाता है।

class WeblogController < ActionController::Base
  layout proc { logged_in? ? "writer_layout" : "reader_layout" }
end

बेशक, एक लेआउट को निर्दिष्ट करने का सबसे आम तरीका अभी भी एक सादे टेम्पलेट नाम के रूप में है:

class WeblogController < ActionController::Base
  layout "weblog_standard"
end

टेम्पलेट हमेशा app/views/layouts/ फ़ोल्डर में देखा जाएगा। लेकिन आप layouts फ़ोल्डर को सीधे भी इंगित कर सकते हैं। layout "layouts/demo" layout "demo"

लेआउट को nil सेट करने के लिए इसे फाइल सिस्टम में देखा जाना चाहिए और यदि कोई मौजूद नहीं है तो अभिभावक के व्यवहार में कमियां हैं। माता-पिता में पिछले कॉन्फ़िगरेशन को सेट करते हुए टेम्पलेट लुकअप को फिर से सक्षम करने के लिए इसे nil सेट करना उपयोगी है:

class ApplicationController < ActionController::Base
  layout "application"
end

class PostsController < ApplicationController
  # Will use "application" layout
end

class CommentsController < ApplicationController
  # Will search for "comments" layout and fallback "application" layout
  layout nil
end

सशर्त लेआउट

यदि आपके पास एक लेआउट है जो डिफ़ॉल्ट रूप से नियंत्रक की सभी क्रियाओं पर लागू होता है, तो आपके पास लेआउट के बिना दिए गए कार्यों या कार्यों को सेट करने या लेआउट को केवल एक ही कार्रवाई या कार्यों के सेट तक सीमित करने का विकल्प होता है। । :only और :except विकल्पों को :except लेआउट कॉल में पास किया जा सकता है। उदाहरण के लिए:

class WeblogController < ActionController::Base
  layout "weblog_standard", except: :rss

  # ...

end

यह "वेबलॉग_स्टैंडर्ड" को आरएसएल एक्शन को छोड़कर सभी कार्यों के लिए वेबलॉगकंट्रोलर के लेआउट के रूप में असाइन करेगा, जो कि रेंडर किए गए दृश्य के चारों ओर एक लेआउट लपेटे बिना, सीधे प्रदान किया जाएगा।

दोनों :only और :except स्थिति को :except , विधि संदर्भों की एक मनमानी संख्या को स्वीकार कर सकते हैं, इसलिए # except: [ :rss, :text_only ] मान्य है, जैसा कि except: :rss

एक्शन रेंडर कॉल में एक अलग लेआउट का उपयोग करना

यदि आपके अधिकांश कार्य एक ही लेआउट का उपयोग करते हैं, तो यह ऊपर वर्णित के रूप में एक नियंत्रक-चौड़ा लेआउट को परिभाषित करने के लिए एकदम सही समझ में आता है। कभी-कभी आपके पास अपवाद होंगे जहां एक क्रिया बाकी नियंत्रक की तुलना में एक अलग लेआउट का उपयोग करना चाहती है। आप ऐसा कर सकते हैं :layout render कॉल करने के लिए :layout विकल्प। उदाहरण के लिए:

class WeblogController < ActionController::Base
  layout "weblog_standard"

  def help
    render action: "help", layout: "help"
  end
end

यह कंट्रोलर-वाइड "weblog_standard" लेआउट को ओवरराइड करेगा, और इसके बजाय "सहायता" लेआउट के साथ सहायता कार्रवाई को प्रस्तुत करेगा।

सार्वजनिक प्रवृत्ति के तरीके

# File actionview/lib/action_view/layouts.rb, line 370
def action_has_layout?
  @_action_has_layout
end

नियंत्रित करता है कि क्या लेआउट का उपयोग करके कोई कार्रवाई की जानी चाहिए। यदि आप वर्तमान कार्रवाई के लिए किसी भी layout सेटिंग्स को अक्षम करना चाहते हैं ताकि यह बिना लेआउट के प्रदान किया जाए, तो या तो अपने नियंत्रक में इस क्रिया को ओवरराइड करें ताकि उस कार्रवाई के लिए गलत वापस आए या action_has_layout करने से पहले action_has_layout विशेषता को गलत पर सेट करें।