আমি কীভাবে প্রোগ্রামক্রমে কোনও ব্লক প্রদর্শন করতে পারি?


33

আমি ড্রুপাল 8 বিটা -14 ব্যবহার করে একটি সাইট বিকাশ করছি। আমি বিভিন্ন পদগুলির একটি ভিউ ব্লক তৈরি করেছি এবং এখন আমি কোড ব্যবহার করে এটি প্রদর্শন করতে চাই। আমি কীভাবে এটি অগ্রগতিভাবে প্রদর্শন করতে পারি? আমি এই কোডটি ব্যবহার করে ড্রুপাল 7 এ এটি করতাম তবে আমি ড্রুপাল 8 সম্পর্কে বিভ্রান্ত।

$block = module_invoke('block', 'block_view', '4');
$text_block = render($block['content']);

উত্তর:


69

দুটি ধরণের ব্লক রয়েছে এবং দুটি সরবরাহ করার পদ্ধতিটি কিছুটা আলাদা:

সামগ্রী ব্লক

সামগ্রী ব্লকগুলি হ'ল ব্লক যা আপনি ইন্টারফেসে তৈরি করেন। এগুলি ক্ষেত্র ইত্যাদির সাথে নোডের কনফিগারযোগ্য ডেটা স্ট্রাকচারের মতো etc.

$bid = ??? // Get the block id through config, SQL or some other means
$block = \Drupal\block_content\Entity\BlockContent::load($bid);
$render = \Drupal::entityTypeManager()->
  getViewBuilder('block_content')->view($block);
return $render;

প্লাগিন ব্লক

ব্লকগুলি বিভিন্ন মডিউলগুলিতে সংজ্ঞায়িত প্লাগইনও হতে পারে। একটি উদাহরণ ব্রেডক্রাম্ব ব্লক হতে পারে। আপনি যদি এইগুলি রেন্ডার করতে চান তবে আপনাকে ব্লক প্লাগইন পরিচালক ব্যবহার করতে হবে।

$block_manager = \Drupal::service('plugin.manager.block');
// You can hard code configuration or you load from settings.
$config = [];
$plugin_block = $block_manager->createInstance('system_breadcrumb_block', $config);
// Some blocks might implement access check.
$access_result = $plugin_block->access(\Drupal::currentUser());
// Return empty render array if user doesn't have access.
// $access_result can be boolean or an AccessResult class
if (is_object($access_result) && $access_result->isForbidden() || is_bool($access_result) && !$access_result) {
  // You might need to add some cache tags/contexts.
  return [];
}
$render = $plugin_block->build();
// In some cases, you need to add the cache tags/context depending on
// the block implemention. As it's possible to add the cache tags and
// contexts in the render method and in ::getCacheTags and 
// ::getCacheContexts methods.
return $render;

সত্তা কনফিগার করুন

দুটি প্রকারের জন্য ভাগ করাগুলি হ'ল ব্লকগুলি হ'ল এটি হ'ল একবার এগুলি আপনি কোনও অঞ্চলে sertোকানোর পরে আপনি একটি কনফিগার সত্তা তৈরি করবেন যাতে ব্লকের সমস্ত সেটিংস রয়েছে। কিছু ক্ষেত্রে এটি কনফিগার সত্তাগুলি হ্যান্ডলিংয়ে আরও কার্যকর হবে। যেহেতু একই ব্লকটি বিভিন্ন কনফিগারেশন সহ এবং একাধিক অঞ্চলে থাকতে পারে, তাই এটি ব্লক কনফিগারেশন সত্তা ব্যবহার করে আরও জটিল হতে পারে। সুন্দর জিনিসটি হ'ল আপনি নির্দিষ্ট কনফিগারেশনের সাথে একটি ব্লক রেন্ডার করতে চাইতে পারেন, সবচেয়ে খারাপ বিষয় হ'ল কনফিগারেশন আইডিগুলি ইন্টারফেসের সাথে গোলযোগের মাধ্যমে পরিবর্তন করতে পারে, তাই ব্যবহারকারীরা ব্লক ইন্টারফেসটি ব্যবহার করার পরে কোডটি কাজ না করে।

$block = \Drupal\block\Entity\Block::load('config.id');
$render = \Drupal::entityTypeManager()
  ->getViewBuilder('block')
  ->view($block);
return $render;

2
প্রশ্নটি নির্দিষ্ট করে না যে এটি কোনও ব্লক কনফিগারেশন সত্তা (প্রাক-কনফিগার করা ব্লক প্লেসমেন্ট) বা হার্ডকোডযুক্ত কনফিগারেশন সহ একটি ব্লক প্লাগইন রেন্ডার করার বিষয়ে। Sense.x এ পার্থক্য বিদ্যমান না বলে কোনটি বোঝায়। এটি আরও নমনীয় কারণ অন্য একটির জন্য একটি নির্দিষ্ট ব্লকের প্রয়োজন যা একটি প্রদত্ত থিম এবং অঞ্চলে স্থাপন করা দরকার। যাইহোক, আপনার হাতে কখনও এগুলি তৈরি করা উচিত নয়। প্লাগইন আইডি দিয়ে ব্লক প্লাগইন ম্যানেজারের ক্রিয়েইনস্ট্যান্স () পদ্ধতিটি ব্যবহার করুন, যেখানে আপনি একটি $ কনফিগারেশন
অ্যারেও সরবরাহ

2
এছাড়াও, আপনি যদি ব্লক অ্যাক্সেসের ক্ষেত্রে সীমাবদ্ধ থাকে তবে প্রথমে অ্যাক্সেস () পদ্ধতিটি কল করার বিষয়ে বিবেচনা করতে পারেন that ব্লকের নির্দিষ্ট কোনও অনুমতি। আপনি কি নিজের উত্তরটি কিছুটা উন্নত করতে পারেন? তখন একটি দরকারী সংস্থান হতে পারে :)
বার্ডির

1
@ বারডির কিছুক্ষণ হয়ে গেছে, তবে শেষ পর্যন্ত উত্তরটি উন্নত করতে পেরেছি। সমস্ত বিভিন্ন ক্যাশে চলার সাথে সাথে সরাসরি প্লাগইন ব্যবহার করা কেবলমাত্র সীমাবদ্ধ পরিস্থিতিতে কার্যকর।
googletorp

4
ব্লক প্লাগইন ম্যানেজার ক্রিয়েইনস্ট্যান্স () ব্যবহার করে ক্ষতিটি হ'ল ফলস্বরূপ রেন্ডার অ্যারেটি ব্লক থেরিংয়ের মাধ্যমে সঞ্চালিত হয় না, উদাহরণস্বরূপ আপনি ব্লক - blockname.twig.html ব্যবহার করতে পারবেন না। বিকল্পটি হ'ল আপনার থিমের জন্য একটি ব্লক তৈরি করা, তবে এটিকে অক্ষম করুন এবং তারপরে আপনার কোডটিতে করুন: `` `$ block = \ দ্রুপাল \ ব্লক \ সত্তা \ ব্লক :: লোড ('মাইব্লক'); $ বিল্ড = rup দ্রুপাল :: অ্যান্টিমিঞ্জার () -> getViewBuilder ('ব্লক') -> দর্শন ($ ব্লক); `` `
জোচিম

1
নাহ - আরেকটি খরগোশের গর্ত। কনটেন্টের কোডটি সাদা পর্দার ব্লক করে (কুখ্যাত সাথে "ওয়েবসাইটটি একটি অপ্রত্যাশিত ত্রুটির মুখোমুখি হয়েছিল Please দয়া করে পরে আবার চেষ্টা করুন" ") দ্বিতীয়টি কাছাকাছি আসে - তবে ব্লকটি অনুপস্থিত বা কিছু হারিয়ে যাওয়ার বিষয়ে একটি গুপ্তচর বার্তা প্রদর্শন করে ... সত্য নয় কারণ আমি একটি সিস্টেম ব্লক চেষ্টা করছি - ড্রুপাল জিনিস দ্বারা চালিত)।
সমুদ্র 26.2

16

প্রিপ্র্রোসেস সহ কেবলমাত্র আপনার টেমপ্লেটগুলিতে আপনার ব্লক প্রদর্শনের জন্য সবচেয়ে ভাল উপায়

$block = \Drupal\block\Entity\Block::load('my_block_id');
$variables['My_region'] = \Drupal::entityManager()
          ->getViewBuilder('block')
          ->view($block);

আর তোমার মধ্যে page.html.twigবা node.html.twigবা xxx.html.twigএই মত আপনার পরিবর্তনশীল My_region ব্যবহার করুন:

{% if page.My_region %}
    {{ page.My_region }}
{% endif %}

এবং উপস্থাপনযোগ্য অ্যারে (কাস্টম মডিউল) উদাহরণস্বরূপ বিষয়বস্তুতে একটি নিয়ামক কাস্টম হিসাবে ():

public function content() {
    $block = \Drupal\block\Entity\Block::load('my_block_id');
    $block_content = \Drupal::entityManager()
      ->getViewBuilder('block')
      ->view($block);

          return array(
        '#type' => 'container',
        '#attributes' => array(
          'class' => array("Myclass"),
        ),
        "element-content" => $block_content,
        '#weight' => 0,
      );
}

ব্যবহার drupal_renderযেমন Drupal এর ইতিমধ্যে D8 মধ্যে রেন্ডার অনুমান এবং এই হল দরকারী নয় অবচিত\Drupal::service('renderer')->renderRoot()পরিবর্তে আপনার ব্যবহার করা উচিত ।

এটি কিছুটা ভারী, সর্বাধিক অঞ্চল ব্যবস্থাটি ব্যবহার করা আরও ভাল এবং প্রিপ্রসেস থেকে লোড ব্লক যুক্ত করবেন না। আপনার মডিউলগুলিতে একটি নিয়ামক ব্যবহার করার ক্ষেত্রে এটি ন্যায়সঙ্গত ব্যবহার বলে মনে হচ্ছে।


এই নিয়ামক বাস্তবায়ন হ'ল আমি যা খুঁজছিলাম। ধন্যবাদ!
মিঃউইনার

আমি যে আচরণ করছি তার সাথে একই ব্যবহারের জন্য আমি এই নিয়ামক বাস্তবায়নে আগ্রহী। কিন্তু আমি কোনও element-contentরেন্ডার অ্যারেতে সম্পত্তি সম্পর্কে কোনও ডকুমেন্টেশন পাই না । আপনি এটি জানেন যেখানে এটি নথিভুক্ত?
এরিয়া

কেন জানি না, তবে \Drupal\block\Entity\Block::loadসারাক্ষণ কোনও ব্লক ফেরায় না। এটি কেবল তখনই ফেরত দেয় যখন আমি লোড করা ব্লকটিকে ব্লক বিন্যাসে দৃশ্যের মধ্যে রাখা হয় । যদি এটি স্থাপন না করা হয় তবে এটি শূন্য হয়।
আর্থার অ্যাটআউট

এই উত্তরটি ব্যবহার করতে আপডেট করা উচিত\Drupal::entityTypeManager()->getViewBuilder('block')->view($block);
রায়ান হার্টম্যান

6

শীর্ষস্থানীয় উত্তরের পাশাপাশি ... আপনি যদি কোনও ভিউ থেকে একটি ব্লক রেন্ডার করতে চান তবে আপনাকে কিছুটা আলাদাভাবে করতে হতে পারে।

$view = views_embed_view('my_view_name', 'my_display_name');

(প্রদর্শনের নাম যেমন -> ব্লক_1)

যেহেতু আমরা এটিকে পাতলা করতে চলেছি, তাই আমাদের রেন্ডার করার প্রয়োজন নেই (রেন্ডার পরিষেবা ব্যবহার করে)।

সুতরাং আপনি এটি দ্বিগুণ করার জন্য একটি পরিবর্তনশীল হিসাবে এটি পাস করতে পারেন (উদাহরণস্বরূপ, এটি একটি নিয়ামকের ফেরত):

return [
  ['description' => [
    '#theme' => 'your_theme_hook',
    '#your_variable => $view
  ]
]

আপনার মডিউলটিতে আপনার ভেরিয়েবলের জন্য একটি হুক_থেম () দরকার:

function hook_theme($existing, $type, $theme, $path) {
  return array(
    'your_theme_hook' => array(
      'variables' => [
        'your_variable' => NULL,
      ]
    )
  )
}

এবং অবশেষে আপনার টুইগ টেমপ্লেটে:

{{ your_variable }}

5

আমার একটি কাস্টম ব্লকের এইচটিএমএল পাওয়ার দরকার ছিল এবং এটি ব্যবহার করে পেয়েছি:

$con = \Drupal\block\BlockViewBuilder::lazyBuilder('bartik_search', 'full');
$d   = \Drupal::service('renderer')->renderPlain($con);

print $d->__toString();

1
আমার এটিকে রেন্ডার অ্যারেতে যুক্ত করার দরকার ছিল এবং সেখানে এটি ছাড়া কাজ করে __toString()
লেইম্যানেক্স

1
একটি ব্লকের কমপক্ষে "অক্ষম ব্লক" অঞ্চলে স্থাপন করা দরকার তা উল্লেখ করা গুরুত্বপূর্ণ। বা অন্য কোনও সক্রিয় অঞ্চল।
leymannx

1
// You need a block_id! to get it just click configure in the desire block and you'll get url like this /admin/structure/block/manage/bartik_search   the last part of the parameter is the block id
$block = \Drupal\block\Entity\Block::load('bartik_search');
$block_content = \Drupal::entityManager()
  ->getViewBuilder('block')
  ->view($block);

return array('#markup' => \Drupal::service('renderer')->renderRoot($block_content));

সম্ভব হলে আপনার ব্যবহার drupal_renderবা রেন্ডার পরিষেবা এড়ানো উচিত । drupal_renderচিত্রিত করা হয়েছে তবে রেন্ডারযুক্ত সামগ্রীর সাথে একটি অ্যারের রেন্ডার পুনরুদ্ধার করা খুব খারাপ, আপনার $block_contentপরিবর্তে ফিরে আসা উচিত , রেন্ডার অ্যারে প্রকৃত রেন্ডারের আগে পরিবর্তন করা যেতে পারে এবং আপনি দ্রুপালকে রেন্ডারিংকে যতটা প্রতিক্রিয়াযুক্ত তত বদলে তার নিজের কাজটি করতে দেওয়া উচিত।
googletorp

এটি কেবল তখনই কাজ করবে যদি ব্লকটি ইতিমধ্যে ব্লক বিন্যাসের মাধ্যমে পৃষ্ঠায় স্থাপন করা হয়।
hugronaphor

1

মূলত, দুটি ধরণের রেন্ডার রয়েছে।

  1. যখন বিন্যাসে ব্লকের কোনও বিদ্যমান উদাহরণ উপস্থিত থাকে। প্রিপ্রোসেস হিসাবে ব্লকটি টুইগে রেন্ডার করা যেতে পারে

    $ ব্লক = ব্লক :: লোড ('ব্লক_আইডি'); $ ভেরিয়েবল ['social_links'] = \ দ্রুপাল :: অ্যান্টিটাইপম্যানেজার () -> getViewBuilder ('ব্লক') -> দেখুন ($ ব্লক);

  2. ব্লকের জন্য কোনও উদাহরণ বা কনফিগারেশন নেই। তারপরে প্রিপ্রসেসরগুলিতে আমাদের উদাহরণটি তৈরি করতে হবে, ব্লকটি তৈরি করতে হবে এবং তারপরে এটি রেন্ডার করতে হবে

    $ block_manager = \ দ্রুপাল :: পরিষেবা ('প্লাগইন.ম্যানেজ.ব্লক'); $ config = []; $ প্লাগইন_ব্লক = $ ব্লক_ম্যানেজার-> createInstance ('ফার্মজর্নাল_সোকিয়াল_শারিং', $ কনফিগারেশন); $ রেন্ডার = $ প্লাগইন_ব্লক-> বিল্ড (); $ ভেরিয়েবল ['ফার্মজর্নাল_সোকিয়াল_শারিং'] = রেন্ডার (nder রেন্ডার);


0

মনে হচ্ছে এটি প্লাগইন ব্লকগুলির জন্য কাজ করে ..

$block = \Drupal\block\Entity\Block::load('some_block_id_3');
  $pluin = $block->getPlugin();
  $build = $pluin->build();
  $build['#weight'] = 4;
  $form['block'] = $build;

-2

আপনি ব্লক আউটপুট পাবেন:

$block = \Drupal\block\Entity\Block::load ('my_bock_id');
$block_content = \Drupal::entityManager ()->
  getViewBuilder ('block')->
  view ($block);

এবং তারপরে আপনি বিভিন্ন উপায়ে আউটপুট ফিরে আসতে পারেন:

return array (
    '#type' => 'container',
    'element-content' => $block_content
);

বা:

return ['#markup' => \Drupal::service ('renderer')->render ($block_content)];

\Drupal::service ('renderer')->render ($block_content)হিসাবে করা যেতে পারে drupal_render ($block_content)তবে
উত্তরটি

সম্ভব হলে আপনার ব্যবহার drupal_renderবা রেন্ডার পরিষেবা এড়ানো উচিত । drupal_renderচিত্রিত করা হয়েছে তবে রেন্ডারযুক্ত সামগ্রীর সাথে একটি অ্যারের রেন্ডার পুনরুদ্ধার করা খুব খারাপ, আপনার $block_contentপরিবর্তে ফিরে আসা উচিত , রেন্ডার অ্যারে প্রকৃত রেন্ডারের আগে পরিবর্তন করা যেতে পারে এবং আপনি দ্রুপালকে রেন্ডারিংকে যতটা প্রতিক্রিয়াযুক্ত তত বদলে তার নিজের কাজটি করতে দেওয়া উচিত। আপনি যা ফিরিয়ে দেন তা আবার রেন্ডার করা দরকার যা প্রকৃত রেন্ডারিংকে অর্থহীন করে তোলে
googletorp

-2

আমার গবেষণার উপর ভিত্তি করে, আপনি ড্রুপাল 8-তে প্রোগ্রামিকভাবে কোনও ব্লক কীভাবে রেন্ডার করবেন তা থেকে কোডটি বেস করতে পারেন । আপনি পরিবর্তন করতে পারে

return array('#markup' => \Drupal::service('renderer')->renderRoot($block_content));

হিসাবে সহজ কিছু মধ্যে:

$output .= \Drupal::service('renderer')->renderRoot($block_content);

এটি কোনও পৃষ্ঠার রিটার্ন ভেরিয়েবলের উদাহরণস্বরূপ সংযুক্ত করতে।


সম্ভব হলে আপনার ব্যবহার drupal_renderবা রেন্ডার পরিষেবা এড়ানো উচিত । drupal_renderচিত্রিত করা হয়েছে তবে রেন্ডারযুক্ত সামগ্রীর সাথে একটি অ্যারের রেন্ডার পুনরুদ্ধার করা খুব খারাপ, আপনার $block_contentপরিবর্তে ফিরে আসা উচিত , রেন্ডার অ্যারে প্রকৃত রেন্ডারের আগে পরিবর্তন করা যেতে পারে এবং আপনি দ্রুপালকে রেন্ডারিংকে যতটা প্রতিক্রিয়াযুক্ত তত বদলে তার নিজের কাজটি করতে দেওয়া উচিত।
googletorp

তুমি ঠিক বলছো. এটি প্রস্তাবিত এবং সর্বাধিক নমনীয় সমাধান নয়।
লিওলান্ডো টান

আপনার লিঙ্কটি মারা গেছে "কীভাবে একটি ব্লক রেন্ডার করব ..."
সমুদ্র 26.2
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.