ทำไมไฟล์เส้นทางจึงเต็มไปด้วยขีดล่าง?


24

การจัดการกับพารามิเตอร์ทั้งหมดที่มีและไม่มีอักขระขีดล่างนำหน้าคืออะไร?

Drupal ตัดสินใจว่าจะประมวลผลพารามิเตอร์เหล่านี้ได้ที่ไหน

แนวคิดนี้ได้รับการแนะนำจาก Symfony หรือไม่หรือเป็นเรื่องใหม่สำหรับ Drupal

ตัวอย่าง ( node.routing.yml ):

node.overview_types:
  path: '/admin/structure/types'
  defaults:
    _controller: '\Drupal\Core\Entity\Controller\EntityListController::listing'
    entity_type: 'node_type'
    _title: 'Content types'
  requirements:
    _permission: 'administer content types'

2
มันเป็นประชุม Symfony มีบทความที่ดีที่นี่หาบิตที่ระบุว่าสิ่งสุดท้ายที่ต้องใส่ใจคือความหมายพิเศษของอักขระขีดล่างในชื่อพารามิเตอร์ พารามิเตอร์ที่ขึ้นต้นด้วยตัวละครตัวนี้มีความหมายพิเศษ
ไคลฟ์

1
ขอบคุณไคลฟ์ บทความนี้กล่าวถึง "ความหมายพิเศษ" แต่ไม่ได้อธิบายสิ่งนี้เลย ทำไมลาดเทพารามิเตอร์ที่ไม่ใช่ขีดล่างเป็นพิเศษเช่นกัน?
Daniel

1
lol ทำไมพารามิเตอร์ที่ไม่ใช่ขีดล่างไม่สามารถเป็นพิเศษเช่นกัน? ดูเหมือนว่าเป็นคำถามที่มีอยู่จริง! โดยปกติ (ปกติแล้ว) ตัวแปรนำหน้าจะทำเพื่อระบุ var 'ส่วนตัว' (ไม่น่าจะอยู่ที่นี่) หรือเพื่อหลีกเลี่ยงการตั้งชื่อการชนกับคลาส / วิธีการ / สิ่งอื่นในระบบ คงจะดีถ้าได้เห็นเอกสารอย่างเป็นทางการใช่
ไคลฟ์

คำตอบ:


41

นี่คือคำอธิบายที่ดีหวังว่าเบื้องหลังแนวคิดของระบบเส้นทางรวมถึงส่วนเพิ่มเติมเฉพาะของ drupal

ภาพรวมทั่วไป

องค์ประกอบ Symfony มีแนวคิดสำคัญสองประการที่นี่ http kernel เป็นระบบที่ได้รับการร้องขออย่างใดขอให้ระบบอื่นผลิตเพื่อกำหนดชิ้นส่วนของรหัสที่สร้างผลลัพธ์ที่ร้องขอ (วัตถุตอบสนอง) และส่งการตอบสนองกลับไปยังลูกค้า รหัสชิ้นนี้เรียกว่าคอนโทรลเลอร์ดังนั้นจึงสามารถเป็นได้ทั้ง php4 บริสุทธิ์เช่นฟังก์ชั่นวิธีการบนวัตถุหรือแม้กระทั่งฟังก์ชั่นที่ไม่ระบุชื่อ

ระบบที่รู้ว่าคอนโทรลเลอร์ตัวใดรับผิดชอบต่อคำขอปัจจุบันคือระบบการเราต์

ป้อนคำอธิบายรูปภาพที่นี่

ไฟล์การกำหนดเส้นทางพื้นฐาน

ในฐานะนักพัฒนาโมดูลคุณกำหนดรายการเส้นทางและตัวควบคุมที่เกี่ยวข้อง

นี่คือตัวอย่างสำหรับการตอบสนอง json:

taxonomy.autocomplete_vid:
  path: '/taxonomy/autocomplete_vid/{taxonomy_vocabulary}'
  defaults:
    _controller: '\Drupal\taxonomy\Controller\TermAutocompleteController::autocompletePerVid'
  requirements:
    taxonomy_vocabulary: \d+

รูปแบบเอกสารของ symfony ส่วนใหญ่พูดถึง แต่ drupal ตัดสินใจที่จะยอมให้ใช้คีย์ "path" ที่ไม่สนับสนุนในไฟล์การกำหนดเส้นทาง

แนวคิดหลักคือตัวควบคุมที่รับพารามิเตอร์บางอย่างจากระบบและแปลงให้เป็นการตอบสนอง ในตัวอย่างนี้คุณมีพารามิเตอร์ 'taxonomy_vocabulary' ดังนั้นทุกอย่างที่ไม่มีขีดล่างจะถือว่าเป็นพารามิเตอร์ของคอนโทรลเลอร์ หากคุณต้องการระบุค่าเริ่มต้นคุณจะต้องใส่ค่าเริ่มต้นลงในอาร์เรย์ ในอาร์เรย์ yml เดียวกันคุณระบุคลาสและวิธีการที่เชื่อมต่อกับ '::' เพื่อบอกให้ระบบค้นหาตำแหน่งต่างๆ คุณสมบัติอื่น ๆ ไม่มีส่วนเกี่ยวข้องกับพารามิเตอร์คอนโทรลเลอร์ดังนั้นจึงถือว่าเป็นภายในและมีขีดล่างเป็นส่วนนำหน้า

Symfony เองยังอนุญาตให้คุณกำหนดนิพจน์ทั่วไปเพื่อตรวจสอบว่าพารามิเตอร์ขาเข้านั้นถูกต้อง (โดยใช้ 'ข้อกำหนด') ตรงนี้มันจะจับคู่กับตัวเลขเท่านั้น

ตัวแก้ไขตัวควบคุม

เมื่อพบว่าตัวควบคุม symfony ตัวใดที่ทำงานอยู่บนคำร้องขอปัจจุบันก็จะถามตัวแก้ไขตัวควบคุมที่เรียกว่าสร้างอินสแตนซ์ของตัวควบคุมที่สามารถดำเนินการผ่านทาง call_user_func_array ตัวแก้ไขตัวควบคุมมีวิธีหนึ่งในการรับค่า callable (วัตถุ + วิธี, ฟังก์ชั่นที่ไม่ระบุชื่อ) และวิธีหนึ่งในการรับพารามิเตอร์ที่ส่งผ่านไปยังตัวควบคุมให้ดูตัวแก้ไขตัวควบคุม

ส่วนขยาย Drupal

นี่คือสิ่งที่ symfony ให้คุณ

แม้ว่า Drupal นั้นซับซ้อนกว่าเล็กน้อย:

  • คุณสามารถตรวจสอบการเข้าถึงเส้นทาง ตัวอย่างเช่นการเรียก user_access () เป็นเรื่องธรรมดามากใน Drupal 7 และต่ำกว่า
  • คุณไม่ต้องการแปลง taxonomy_vocabulary เป็นวัตถุเอนทิตีที่แท้จริง
  • คุณไม่ต้องการที่จะสร้างการตอบสนองแบบเต็มหน้า แต่เพียงแค่ "เนื้อหาหลัก"

ตรวจสอบการเข้าถึง

Drupal ได้แนะนำระบบด้านบนของส่วน symfony ที่ตรวจสอบว่าผู้ใช้มีการเข้าถึงเส้นทางปัจจุบันและมีทางเลือกอื่นยกเว้นข้อยกเว้น 403 (ปฏิเสธการเข้าถึง) ผู้จัดการการเข้าถึง

ในไฟล์เส้นทางคุณระบุสิ่งนี้ในส่วนข้อกำหนด บิตที่พบบ่อยที่สุดแสดงอยู่ในตัวอย่าง:

  path: '/user/{user}'
  options:
    _access_mode: 'ANY'
  requirements:
    _permission: 'access user profiles'
    _entity_access: 'user.view'
    _role: 'administrator'

_permission กำหนดการเรียกไปยัง user_access (), _role ทำให้แน่ใจว่าผู้ใช้มีบทบาทที่แน่นอน (คุณสามารถระบุหลายคนผ่านทางสำหรับหรือและ + สำหรับและตรรกะ) _entity_access ถามระบบเอนทิตีว่าคุณมีสิทธิ์เข้าถึงเพื่อดูเอนทิตีผู้ใช้หรือไม่ ตามค่าเริ่มต้น drupal ช่วยให้มั่นใจว่าคุณเพิ่มตัวตรวจสอบการเข้าถึงอนุญาตให้คุณดำเนินการต่อ แต่คุณสามารถสลับได้ในตัวเลือกผ่านทาง _access_mode

Upcasting

ดังที่กล่าวไว้ในรายชื่อที่คุณไม่ต้องการให้ความสนใจในการโหลดเอนทิตีดู / user / {user} เป็นตัวอย่าง สำหรับเอนทิตีคุณเพียงแค่ใช้ชื่อของประเภทเอนทิตีและมันจะรันเอนทิตีที่โหลดด้วยรหัสผ่านใน URL ผู้จัดการแปลง Param

การตอบสนองหน้า

ดังที่เขียนไว้ก่อนที่คอนโทรลเลอร์จะรับผิดชอบในการสร้างออบเจ็กต์การตอบสนอง สิ่งนี้น่ากลัวใน Drupal เนื่องจากหน้าเว็บประกอบด้วยบล็อกที่ปรากฏในภูมิภาคเทมเพลต html และเทมเพลตเป็นต้นดังนั้น drupal จึงระบุคีย์อื่นเพื่อระบุตัวควบคุมที่ส่งคืนเนื้อหาของหน้า:

user.page:
  path: '/user'
  defaults:
    _content: '\Drupal\user\Controller\UserController::userPage'
  requirements:
    _access: 'TRUE'

สตริงที่กำหนดคือตัวควบคุมที่ใช้ในการสร้างเรนเดอร์เรนเดอร์สำหรับพื้นที่เนื้อหาหลักของหน้าของคุณ

การเพิ่มอีกวิธีคือวิธีจัดการกับฟอร์มเนื่องจากการส่งคืนหน้าที่มีฟอร์มนั้นซับซ้อนกว่าเพียงแค่เรนเดอร์เรนเดอร์เล็กน้อยดังนั้นคุณจึงสามารถกำหนด _form ด้วย FormInterface ที่รับผิดชอบฟอร์มปัจจุบัน

user.pass:
  path: '/user/password'
  defaults:
    _form: '\Drupal\user\Form\UserPasswordForm'
  requirements:
    _access: 'TRUE'

หมายเหตุ: สิ่งนี้ครอบคลุมประเด็นที่สำคัญที่สุดจากมุมมองของฉันแม้ว่าจะมีประเด็นอีกมากมายที่จะพูดถึง

TL; DR

  • ขีดล่างมีการระบุไว้สำหรับทุกสิ่งที่ไม่ใช่พารามิเตอร์ของคอนโทรลเลอร์ นี่คือสิ่งที่มาจาก "มาตรฐาน" จาก symfony
  • พารามิเตอร์เหล่านี้ถูกถ่ายทอดผ่านตัวแปลงพารามิเตอร์และส่งผ่านไปยังตัวควบคุมโดยใช้ตัวแก้ไขตัวควบคุม
  • Drupal มีการเพิ่มเติมบางส่วนเพื่อให้ผู้คนสามารถโต้ตอบกับระบบการจัดเส้นทาง symfony ได้ง่ายขึ้น

ว้าว. คำตอบที่น่าประทับใจ เหตุใดพารามิเตอร์บางอย่างจึงมีระยะเวลาในการเปรียบเทียบกับการใช้เครื่องหมายขีดล่าง เช่นuser.pass(ในตัวอย่างข้างต้น) user_passเมื่อเทียบกับ นั่นคือการประชุม symfony เช่นกัน?
chrisjlee

2
มีวิธีการบางอย่างที่จะใช้ $ module $ name เป็นชื่อเครื่องของเส้นทาง แม้ว่าจะไม่มีอะไรสันนิษฐานว่าภายใน
Daniel Wehner

ตามปัญหาด้านล่าง _content จะไม่ถูกใช้อีกต่อไป แต่ _controller คือ ดังนั้นตัวอย่างในส่วนการตอบกลับหน้าเว็บจึงไม่ทันสมัย drupal.org/node/2378809หากเราต้องการแสดงข้อมูลในพื้นที่เนื้อหาของหน้าของเราผู้ควบคุมจะกำหนดเรนเดอร์เรนเดอร์ซึ่งคล้ายกับวิธีที่มันทำใน Drupal 7 หากเราต้องการข้ามมันและสร้างหน้าของเรา จากศูนย์แล้วเราสามารถส่งคืนวัตถุการตอบสนอง
benelori

แน่นอนคุณไม่สามารถคาดหวังได้ว่า 1.5 ปีจะไม่เกิดขึ้น
Daniel Wehner
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.