কাস্টম ব্লকগুলিতে ক্যাশে প্রসঙ্গ সেট করার সঠিক উপায় কী?


13

আমি একটি ইস্যুতে ছড়িয়েছি যেখানে প্রতি পৃষ্ঠায় অনন্য হওয়া একটি ব্লক লগ-আউট ব্যবহারকারীর জন্য নয়। ইস্যুটি একটি কাস্টম ব্লক প্লাগইন যা আমার কাছে একটি ভিউস অনুসন্ধান পৃষ্ঠায় রয়েছে যাতে কাস্টম ফিল্টার রয়েছে (সাজানো ফিল্টারগুলির জন্য পছন্দসই প্রতিস্থাপনের মতো like

ড্রুপাল 8 সম্পর্কে আমি যা শিখেছি তার উপর ভিত্তি করে আমি আমার বিল্ড অ্যারেতে ক্যাশে প্রসঙ্গগুলি যুক্ত করেছি:

  public function build() {

    $search_form = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\SearchForm');
    return [
      'search_form' => $search_form,
      '#cache' => ['contexts' => ['url.path', 'url.query_args']]
    ];

  }

তবে মনে হচ্ছে এটি অবশ্যই ভুল হতে পারে কারণ লগ-আউট করার পরে, ব্লকটি প্রথম দর্শনটিতে ক্যাশ হয়ে যায় এবং যখন ইউআরএল পরিবর্তন হয় তখন এটি ব্লকের নতুন সংস্করণ দেখায় না।

আমি ভেবেছিলাম এটি সম্ভবত ভিউ পৃষ্ঠা হতে পারে যা সমস্যার কারণ হতে পারে তবে আমি যখন ভিউ পৃষ্ঠায় ক্যাশে বন্ধ করে দিয়েছিলাম তখনও সমস্যাটি থেকেই যায়।

আমি বেশ কয়েকটি উপায়ে সমস্যার সমাধান করতে সক্ষম হয়েছি, উদাহরণস্বরূপ, একটি প্রিপ্রসেস_ব্লক হুক ব্যবহার করে:

function mymodule_preprocess_block__mycustomsearchblock(&$variables) {
  $variables['#cache']['contexts'][] = 'url.path';
  $variables['#cache']['contexts'][] = 'url.query_args';
}

তবে এটি আমাকে বিরক্ত করেছিল আমি কেবল আমার ব্লকের বিল্ড অ্যারেতে ক্যাশে প্রসঙ্গগুলি রাখতে পারি না।

যেহেতু আমার ব্লকটি ব্লকবেস প্রসারিত করেছে, তাই আমি getCacheContexts () পদ্ধতিটি চেষ্টা করার সিদ্ধান্ত নিয়েছি, বিশেষত যেহেতু আমি দেখেছি কোরের মধ্যে কিছু মডিউল এইভাবে এটি করছে।

  public function getCacheContexts() {
    return Cache::mergeContexts(parent::getCacheContexts(), ['url.path', 'url.query_args']);
  }

এটি ইস্যুটিও স্থির করে দিয়েছে, তবে মজার বিষয় হল যখন আমি প্রিপ্রসেস ব্লক ফাংশনে ভেরিয়েবলগুলি আউটপুট করি তখন এগুলি $ ভেরিয়েবল ['# ক্যাশে'] ['প্রসঙ্গ'] তে প্রদর্শিত হয় না, তবে তারা $ ভেরিয়েবল ['উপাদানগুলিতে প্রদর্শন করে) '] [' # ক্যাশে '] [' প্রেক্ষিতে ']

array:5 [▼
  0 => "languages:language_interface"
  1 => "theme"
  2 => "url.path"
  3 => "url.query_args"
  4 => "user.permissions"
]

আমি কীভাবে এটি কাজ করে, এবং কেন এটি বিল্ড ফাংশন থেকে কাজ করছে না তা জানার চেষ্টা করছি।

ভিউ মাল্টিপল () ফাংশনে / স্কোর / মডুলস / ব্লক / এসআরসি / ব্লকভিউবিল্ডার.এফপি দেখে মনে হচ্ছে এটি সত্তা এবং প্লাগইন থেকে ক্যাশে ট্যাগগুলি টানছে:

'contexts' => Cache::mergeContexts(
  $entity->getCacheContexts(),
  $plugin->getCacheContexts()
),

সুতরাং এটি ব্যাখ্যা করে কেন আমার ব্লক প্লাগইনে একটি getCacheContexts () পদ্ধতি যুক্ত করা আমার ব্লকের সাথে প্রসঙ্গগুলি যুক্ত করে। এছাড়াও, একই শ্রেণিতে প্রাক-রেন্ডার পদ্ধতিটি দেখে মনে হচ্ছে এটি ব্লক বিল্ড ফাংশনে ক্যাশে অ্যারে ব্যবহার করে না, যা আমাকে বিভ্রান্ত করে, কারণ মনে হয় ড্রুপাল 8-তে ক্যাচিং যুক্ত করার উপায়টি একটি # ক্যাশে যুক্ত করা উপাদান রেন্ডার উপাদান।

আমার প্রশ্নটি হ'ল

1) কোনও ব্লগ প্লাগইনে অ্যারেতে ক্যাশে প্রসঙ্গগুলি সরাসরি যুক্ত করা হয়?

2) যদি তাই হয়, তবে তার চারপাশে কোনও উপায় আছে, আমাদের কি এটি বিল্ড অ্যারের কোনও শিশু উপাদানকে যুক্ত করতে হবে?

3) যদি প্রসঙ্গটি সরাসরি যুক্ত করা হয় তা উপেক্ষা করা হয়, তবে কাস্টম মডিউলগুলিতে ব্লক প্লাগইনগুলিতে যাওয়ার জন্য একটি getCacheContexts () যুক্ত করা হচ্ছে?


1
1) না, আপনার ব্লক সামগ্রীটি আসলে একটি স্তর নীচে এবং এটি পরে মিশ্রিত করা উচিত। 2) প্রয়োজন নেই কারণ 1, 3) getCacheContexts () প্রয়োগ করা সহজ / ক্লিনার হতে পারে তবে এটির প্রয়োজন হবে না। আপনি স্পষ্টভাবে বেনাম ব্যবহারকারীদের উল্লেখ করেছেন, আপনি কি নিশ্চিত যে এটি সাধারণ প্রমাণীকৃত ব্যবহারকারীদের উপরও প্রভাব ফেলবে না? আপনি যদি গতিশীল_পৃষ্ঠা_ক্যাস অক্ষম করেন তবে সমস্যাটি কি চলে যাবে? কিছু আশ্চর্যজনক কিছু অবশ্যই ঘটতে হবে যদি এটি কেবল অনন ব্যবহারকারীদেরকেই প্রভাবিত করে, কারণ অভ্যন্তরীণ পৃষ্ঠার ক্যাশে সর্বদা যেভাবেই হোক url / কোয়েরি আরগগুলির দ্বারা পরিবর্তিত হয়।
বারদির

1
গতিশীল পৃষ্ঠা ক্যাশে অক্ষম করা সমস্যার সমাধান করে না।
Oknate

1
এইচএম, আপনার শীর্ষ স্তরের উপাদানটিতে # ক্যাশে ব্যতীত অন্য কিছু নেই এমনটি সমস্যা হতে পারে। আপনি কি নিজের ফর্মের মধ্যে কেবল # ক্যাশে সেট করার চেষ্টা করেছেন? এটি এমন ফর্ম যা সেগুলির দ্বারা পৃথক হওয়া প্রয়োজন, এবং যেহেতু ক্যাশে ট্যাগগুলি বুদবুদ হয়, এটি কেবল কাজ করা উচিত। এবং যদি আপনি কখনও নিজের ফর্মটি অন্য কোনও ব্লক বা অন্য জায়গায় ব্যবহার করেন তবে এটি কেবল সেখানে কাজ করা উচিত।
বারদির

1
আমি দ্রুত সিন্ডিকেটব্লকটি হ্যাক করেছি এবং এই বিল্ডটি () পদ্ধতিটি ব্যবহার করেছি: gist.github.com/Berdir/33a31b1e98caf080dae78adb731dba4c । আমার সাইটে যে ঠিক কাজ করে তা স্থাপন করে ক্যাশে প্রসঙ্গগুলি ক্যাশে_রেন্ডার সারণিতে দৃশ্যমান হয় এবং সঠিক অনুরোধ ইউআরআই প্রদর্শিত হয়। আপনি কি একই চেষ্টা করতে পারেন? আমার কাছে দেখে মনে হচ্ছে আপনার সাইটে খুব অদ্ভুত কিছু চলছে
বার্ডির

2
আপনি কি স্ট্যান্ডার্ড ব্লক টেম্পলেট বা একটি কাস্টম ব্যবহার করেন? দেখুন drupal.stackexchange.com
জিজ্ঞাসা /

উত্তর:


9

বেশিরভাগ ক্ষেত্রে, আপনি কেবল আপনার বিল্ড () পদ্ধতিতে ফিরে আসা রেন্ডার অ্যারেটিতে সরাসরি ক্যাশে প্রসঙ্গ সেট করেছিলেন।

@ বেরডির এবং @ 4 কে 4 এর সহায়তায় আমার সমস্যাটি কী ছিল তা অবশেষে খুঁজে পেয়েছি। আপনি যদি কোনও কাস্টম টেম্পলেট ব্যবহার করছেন, যেমন ব্লক - my block.html.twig এবং আপনি পৃথকভাবে ভেরিয়েবলগুলি আউটপুট করেন, যেমন {। কন্টেন্ট} like এর মতো একই সময়ে of {Content.foo} all এর পরিবর্তে, এটি উপেক্ষা করে লগ আউট হয়ে গেলে আপনার ক্যাশে প্রসঙ্গগুলি সরাসরি আপনার ব্লক বিল্ড অ্যারেতে চলে যায়। দেখুন কাস্টম ব্লকগুলিতে ক্যাশে প্রসঙ্গ সেট করার সঠিক উপায় কী?

সুতরাং, মূল প্রশ্নের উত্তর দিতে:

1) কাস্টম ব্লক প্লাগইনে সরাসরি পাস করা ক্যাশে প্রসঙ্গগুলি কখনও কখনও উপেক্ষা করা হয়। আপনি এটি সিন্ডিকেটব্লক পরিবর্তন করে এবং তারপরে আপনার থিম ব্লকে একটি কাস্টম টেম্পলেট তৈরি করে পরীক্ষা করতে পারেন - সিন্ডিকেট। Html.php যাতে আপনি পৃথকভাবে ভেরিয়েবলগুলি এভাবে আউটপুট করেন:

{% block content %}
  {{ content.foo }}
{% endblock %}

আপনি ইউআরএল আর্গুমেন্টগুলি পরিবর্তন করার সাথে সাথে আপনি দেখতে পাবেন যে ব্লকটি ক্যাশে প্রসঙ্গে সম্মান করে না।

এখন আপনি যদি এটিকে সমস্ত সামগ্রী একটি টুকরো হিসাবে আউটপুট পরিবর্তন করেন তবে এটি কাজ করে:

{% block content %}
  {{ content }}
{% endblock %}

এখন, এটি ক্যাশে প্রসঙ্গে শ্রদ্ধা করে এবং প্রতি পৃষ্ঠায় ব্লকটি অনন্য।

2) আপাতত, এটিকে কাজে লাগানোর জন্য, আপনি নিজের ব্লকটিতে যা আছে তার নিজস্ব টেমপ্লেটে আউটপুট করতে পারেন।

 public function build() {

    $search_form = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\SearchForm');
    return [
      '#theme' => 'mycustomtemplate',
      '#search_form' => $search_form,
      '#cache' => ['contexts' => ['url.path', 'url.query_args']]
    ];

  }

এটি ব্লক মডিউলটির মূল ক্যাসিটিং ব্যতিক্রমগুলি বাতিল করে এবং লগ আউট হওয়ার সময় আপনার ফর্মটি প্রতি পৃষ্ঠায় অনন্য unique

3) এটি ঠিক করার জন্য আপনার নিজের থিম টেম্পলেট তৈরি করা উচিত, বা আপনার কাস্টম ব্লক প্লাগইনে getCacheContexts () এর জন্য একটি পদ্ধতি যুক্ত করা উচিত? ক্যাশে প্রসঙ্গগুলি বুদ্বুদ্বিত করার প্রাকৃতিক ক্রমকে ওভাররাইড করে এমন একটি getCacheContexts () পদ্ধতি যুক্ত না করে একটি নতুন থিম টেমপ্লেট তৈরি করা আরও ভাল এবং আপনার বিল্ড অ্যারেতে আরও মেটাডেটা ভেঙে যেতে পারে।


এটি সমস্যার খুব ভাল সংক্ষিপ্তসার। তবে আমি মনে করি যে 3) এর উপসংহারটি সমস্যাযুক্ত, কারণ আপনি কেবল এটি ভেঙে ফেলেন না যে আপনার নিজের ক্যাশে মেটাডেটা বুদবুদ করতে পারে, তবে রেন্ডার অ্যারের আরও গভীরতর অভ্যন্তরীণ হতে পারে এবং আপনি সচেতন হতে পারেন না।
কে 4

সুতরাং আপনি একটি নতুন থিম টেম্পলেট তৈরি করার পরামর্শ দিবেন? পরিষ্কার বুদবুদ সংরক্ষণ করতে?
Oknate

হ্যাঁ, কেবল বাইরের জিনিস যুক্ত করতে ব্লক টেম্পলেটটি ব্যবহার করুন। বিল্ড () এ ব্লকের অভ্যন্তরটি তৈরি করুন। এর জন্য কাস্টম টেম্পলেটগুলি ব্যবহার করুন বা লিঙ্কের মতো কোনও টেবিল বা কোর টেম্পলেটের মতো উপাদানগুলি রেন্ডার করুন।
কে 4

ঠিক আছে, আমি উত্তর আপডেট করব।
Oknate

ওহ, আমি বুঝতে পারি নি যে টুইগের ড্রিলিং ক্যাশেযোগ্য মেটাডেটা উপেক্ষা করবে। এর অর্থ এই হতে পারে যে ড্রিল করতে আমাদের শেষ পর্যন্ত আমাদের নিজস্ব কাস্টম পদ্ধতিটি ব্যবহার করতে হবে (যা দ্বিগুণ প্রসারকে অকেজো করে তোলে) যাতে নীচের স্তরে নেমে যাওয়ার সময় আমরা মেটাডেটা সংরক্ষণ করি serve গুড ফাইন্ড!
লায়ন্সএড

4

অন্য যে কেউ এটি খুঁজে পায় ...

রেন্ডারিং content(বা content|without()) কাজ করার কারণটি হ'ল রেন্ডার অ্যারেতে content['#cache']এমন একটি উপাদান রয়েছে যা সামগ্রীর জন্য সমস্ত ক্যাশেযোগ্য মেটাডেটা ধারণ করে।

আপনি যদি এটিকে টুইগে রেন্ডার করার অনুমতি না দেন তবে, contentবা {{'#cache': content['#cache']|render }}পৃষ্ঠাটি জানেন না যে এটির ক্যাশেযোগ্য মেটাডেটা রয়েছে (যেমন, এটি কখনও বুদবুদ হয় না)।

আপনি যেমন কাস্টম পাতলা না করছেন মনে হচ্ছে। আপনি যদি বার্নিশ জাতীয় কিছু ব্যবহার করে থাকেন তবে এটি বেনাম ব্যবহারকারীদের জন্যও অপরাধী হতে পারে।


3

আমি এই ইস্যুতেও ছড়িয়ে পড়েছি এবং আমি যে কাজটি নিয়ে এসেছি তা হ'ল ম্যানুয়ালি রেন্ডার করতে চাইলে যে কোনও কাস্টম ক্ষেত্র বাদ দিয়ে মূল বিষয়বস্তু ভেরিয়েবলের ফিল্টার করা সংস্করণের উপর ভিত্তি করে একটি নতুন ব্লক_ কনটেন্ট ভেরিয়েবল তৈরি করা হয়েছিল:

{% set block_content = content|without('field_mycustomfield', 'field_mycustomfield2') %}

তারপরে সরাসরি "কন্টেন্ট.বডি" পরিবর্তনশীল রেন্ডার করার পরিবর্তে, আমি কল করি:

{{ block_content }}

আপনি যদি প্রতিটি ক্ষেত্রকে পৃথকভাবে রেন্ডার করতে চান, আপনি কেবল তাদের "বিনা" ফিল্টারে যুক্ত করা চালিয়ে যেতে পারেন যাতে ব্লক_সামেন্ট রেন্ডারিং ফিক্স ক্যাচিং ছাড়া কিছু না করে।


0

এটি অর্জনের সহজ পদ্ধতি হ'ল getCacheContexts()পদ্ধতিটি ঘোষণা এবং সংজ্ঞা দিয়ে


  public function build() {

    $search_form = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\SearchForm');
    return [
      'search_form' => $search_form
    ];

  }

  /**
   * {@inheritdoc}
   */
  public function getCacheMaxAge() {
    // If you need to redefine the Max Age for that block
    return 0;
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheContexts() {
    return ['url.path', 'url.query_args'];
  }

পরীক্ষা করে দেখুন CacheableDependency ডকুমেন্টেশন, এটি করা উচিত সবকিছু আপনি প্রয়োজন উপস্থিত রয়েছে;)


ব্লকগুলিকে এখন যেভাবে রেন্ডার করা হয় তা এটি আর কাজ করে না, দেখুন drupal.stackexchange.com/questions/288881/…
4k4
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.