ManagesComponents.php 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <?php
  2. namespace Illuminate\View\Concerns;
  3. use Illuminate\Support\HtmlString;
  4. trait ManagesComponents
  5. {
  6. /**
  7. * The components being rendered.
  8. *
  9. * @var array
  10. */
  11. protected $componentStack = [];
  12. /**
  13. * The original data passed to the component.
  14. *
  15. * @var array
  16. */
  17. protected $componentData = [];
  18. /**
  19. * The slot contents for the component.
  20. *
  21. * @var array
  22. */
  23. protected $slots = [];
  24. /**
  25. * The names of the slots being rendered.
  26. *
  27. * @var array
  28. */
  29. protected $slotStack = [];
  30. /**
  31. * Start a component rendering process.
  32. *
  33. * @param string $name
  34. * @param array $data
  35. * @return void
  36. */
  37. public function startComponent($name, array $data = [])
  38. {
  39. if (ob_start()) {
  40. $this->componentStack[] = $name;
  41. $this->componentData[$this->currentComponent()] = $data;
  42. $this->slots[$this->currentComponent()] = [];
  43. }
  44. }
  45. /**
  46. * Render the current component.
  47. *
  48. * @return string
  49. */
  50. public function renderComponent()
  51. {
  52. $name = array_pop($this->componentStack);
  53. return $this->make($name, $this->componentData($name))->render();
  54. }
  55. /**
  56. * Get the data for the given component.
  57. *
  58. * @param string $name
  59. * @return array
  60. */
  61. protected function componentData($name)
  62. {
  63. return array_merge(
  64. $this->componentData[count($this->componentStack)],
  65. ['slot' => new HtmlString(trim(ob_get_clean()))],
  66. $this->slots[count($this->componentStack)]
  67. );
  68. }
  69. /**
  70. * Start the slot rendering process.
  71. *
  72. * @param string $name
  73. * @param string|null $content
  74. * @return void
  75. */
  76. public function slot($name, $content = null)
  77. {
  78. if (count(func_get_args()) === 2) {
  79. $this->slots[$this->currentComponent()][$name] = $content;
  80. } else {
  81. if (ob_start()) {
  82. $this->slots[$this->currentComponent()][$name] = '';
  83. $this->slotStack[$this->currentComponent()][] = $name;
  84. }
  85. }
  86. }
  87. /**
  88. * Save the slot content for rendering.
  89. *
  90. * @return void
  91. */
  92. public function endSlot()
  93. {
  94. last($this->componentStack);
  95. $currentSlot = array_pop(
  96. $this->slotStack[$this->currentComponent()]
  97. );
  98. $this->slots[$this->currentComponent()]
  99. [$currentSlot] = new HtmlString(trim(ob_get_clean()));
  100. }
  101. /**
  102. * Get the index for the current component.
  103. *
  104. * @return int
  105. */
  106. protected function currentComponent()
  107. {
  108. return count($this->componentStack) - 1;
  109. }
  110. }