Score:0

จะเรนเดอร์โหนดตามธีมที่ใช้งานได้อย่างไร

ธง jp

ใน hook_entity_postsave() ฟังก์ชั่นในโมดูล D7 ที่กำหนดเองของฉัน ฉันกำลังทำสิ่งต่อไปนี้เมื่อบันทึกโหนด:

$_ = node_view($entity, 'เต็ม');   
$html = drupal_render($_);         

แต่ดูเหมือนว่า HTML ที่แสดงผลจะพลาดเทมเพลตของธีมที่ใช้งานอยู่ เช่น. ฉันได้เปิดการแก้ไขข้อบกพร่องของธีมแล้ว

 คำแนะนำชื่อไฟล์:
   * ย่อหน้า-รายการ--ฟิลด์-ส่วน--full.tpl.php
   * วรรค-รายการ--field-sections.tpl.php
   x วรรค-items.tpl.php

ยัง ย่อหน้า-รายการ--ฟิลด์-ส่วน--full.tpl.php ถูกกำหนดในธีมที่ใช้งานของไซต์ (และใช้อย่างถูกต้องในการนำเสนอหน้าโหนดปกติ)

แก้ไข: ฉันคิดว่าอาจเป็นเพราะธีมผู้ดูแลระบบเปิดใช้งานเมื่อรหัสนี้ทำงาน มีวิธีเปลี่ยนหรือไม่?

Score:1
ธง bd

เป็นเพราะธีมผู้ดูแลระบบของคุณทำงานเมื่อคุณเรนเดอร์

ไม่มีวิธีที่ตรงไปตรงมาและง่ายในการเปลี่ยนธีมระหว่างคำขอ และคุณอาจพบปัญหาเพิ่มเติม

ฉันจะพิจารณาตัวเลือกอื่นๆ เช่น การสร้างโหนดมาร์กอัปผ่านการเรียกกลับเมนูที่ใช้ธีมส่วนหน้าโดยตรงในของคุณ hook_entity_postsave หรือในงาน cron เป็นต้น

หากคุณยังต้องการลองใช้โดยการเปลี่ยนธีม นี่เป็นวิธีที่ได้ผลสำหรับฉันในตอนนี้ หลังจากปรับแต่งโค้ดเล็กน้อยจาก https://stackoverflow.com/a/56358189/368479 และขอยืมรหัสจาก drupal_theme_initialize(). การเปลี่ยนแปลงที่โดดเด่นที่สุดคือการล้างแคชเมื่อสิ้นสุดฟังก์ชันสวิตช์ ในด้านประสิทธิภาพนี่แย่มาก แต่ฉันไม่สามารถทำงานได้หากไม่มีมัน

/**
 * สลับไปยังหรือจากธีมอื่นในช่วงกลางของคำขอ
 *
 * สิ่งนี้มีประโยชน์หากคุณต้องการเรนเดอร์บางอย่าง (เช่น โหนด) ในโหนดอื่น
 * ธีมโดยไม่ต้องเปลี่ยนธีมของทั้งหน้า ตัวอย่างการใช้งานคือ
 * เมื่อคุณต้องการเรนเดอร์บางอย่างสำหรับผู้ใช้ส่วนหน้าจากหน้าผู้ดูแลระบบ
 *
 * ตัวอย่างการใช้งาน:
 * my_module_switch_theme('บาร์ติก');
 * $node = node_load(1);
 * $renderable = node_view($โหนด);
 * $rendered = เรนเดอร์($renderable);
 * my_module_switch_theme();
 *
 * @param สตริง|null $ถึง
 * ชื่อของธีมที่จะเปลี่ยนไปใช้ หากเป็น NULL ก็จะเปลี่ยนกลับไปเป็น
 * ธีมเดิม
 */
ฟังก์ชัน my_module_switch_theme (สตริง $to = NULL) {
  $theme ทั่วโลก, $theme_key;

  // สำรองข้อมูลธีมเดิม
  คง $original_theme;
  ถ้า (ว่าง ($ original_theme)) {
    $original_theme = $ธีม;
  }

  // ทำการสลับ
  $ธีม = $ถึง ?? $original_theme;
  $theme_key = $ธีม;

  // ค้นหาธีมดั้งเดิมของเราทั้งหมดและใส่ไว้ในอาร์เรย์
  $themes = list_themes();
  $base_theme = อาร์เรย์ ();
  $บรรพบุรุษ = $ธีม;
  ในขณะที่ ($ancestor && isset($themes[$ancestor]->base_theme)) {
    $ancestor = $themes[$ancestor]->base_theme;
    $base_theme[] = $themes[$บรรพบุรุษ];
  }
  _drupal_theme_initialize($themes[$theme], array_reverse($base_theme));

  // ธีมสามารถปรับเปลี่ยนฟังก์ชันได้ ดังนั้นให้รีเซ็ตแคช drupal_alter()
  drupal_static_reset('drupal_alter');

  // ล้างแคช
  drupal_flush_all_caches();
}

โปรดทราบว่าสิ่งนี้อาจไม่ทำงานหากคุณนำไปใช้ hook_custom_theme สำหรับเพจที่มีการดำเนินการ แต่ถ้าคุณใช้ธีมของผู้ดูแลระบบ ฉันเดาว่าไม่เป็นเช่นนั้น

โค้ดข้างต้นสามารถใช้ได้เหมือนในตัวอย่างต่อไปนี้ และใช้อย่างถูกต้อง node.tpl.php จากธีม bartik แทนที่จะเป็นธีมปัจจุบันที่ใช้ อย่างน้อยก็ในการตั้งค่าทดสอบของฉัน

my_module_switch_theme('บาร์ติก');
$โหนด = node_load(1);
$renderable = node_view($โหนด);
$rendered = เรนเดอร์($renderable);
my_module_switch_theme();
jp flag
ขอบคุณ ฉันลองแล้ว แต่มันใช้งานไม่ได้ ฉันได้ลองเวอร์ชันเต็มแล้วที่ https://stackoverflow.com/a/20476484/623519 ด้วยไม่ใช่แค่การเลือกเทมเพลตจากธีม :-(
berliner avatar
bd flag
@artfulrobot คุณพูดถูก นอกจากนี้ยังไม่มีตัวแปร `$ custom_theme` ส่วนกลาง ฉันถูกหลอกโดยสิ่งที่ฉันเห็นและไม่ได้ตรวจสอบ ฉันได้อัปเดตคำตอบของฉันแล้ว ฉันขอแนะนำอย่างยิ่งให้ทำการเรนเดอร์ในภายหลังหากเป็นไปได้ การเปลี่ยนธีมระหว่างคำขอที่ใช้งานอยู่จะทำให้เกิดปัญหาได้ง่าย
jp flag
ขอบคุณ! มันได้ผล! ฉันพบประสิทธิภาพที่เพิ่มขึ้น: แทนที่ `drupal_flush_all_caches()` ด้วย `system_rebuild_theme_data();drupal_theme_rebuild();'

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา