1111use Drupal \layout_builder \Context \LayoutBuilderContextTrait ;
1212use Drupal \layout_builder \SectionStorageInterface ;
1313use Symfony \Component \DependencyInjection \ContainerInterface ;
14+ use Drupal \Core \Entity \EntityTypeRepositoryInterface ;
1415
1516/**
1617 * Defines a controller to choose a new block.
@@ -37,17 +38,27 @@ class ChooseBlockController implements ContainerInjectionInterface {
3738 */
3839 protected $ entityTypeManager ;
3940
41+ /**
42+ * The entity type repository.
43+ *
44+ * @var \Drupal\Core\Entity\EntityTypeRepositoryInterface
45+ */
46+ protected $ entityTypeRepository ;
47+
4048 /**
4149 * ChooseBlockController constructor.
4250 *
4351 * @param \Drupal\Core\Block\BlockManagerInterface $block_manager
4452 * The block manager.
4553 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
4654 * The entity type manager.
55+ * @param \Drupal\Core\Entity\EntityTypeRepositoryInterface $entity_type_repository
56+ * The entity type repository.
4757 */
48- public function __construct (BlockManagerInterface $ block_manager , EntityTypeManagerInterface $ entity_type_manager ) {
58+ public function __construct (BlockManagerInterface $ block_manager , EntityTypeManagerInterface $ entity_type_manager, EntityTypeRepositoryInterface $ entity_type_repository ) {
4959 $ this ->blockManager = $ block_manager ;
5060 $ this ->entityTypeManager = $ entity_type_manager ;
61+ $ this ->entityTypeRepository = $ entity_type_repository ;
5162 }
5263
5364 /**
@@ -56,7 +67,8 @@ public function __construct(BlockManagerInterface $block_manager, EntityTypeMana
5667 public static function create (ContainerInterface $ container ) {
5768 return new static (
5869 $ container ->get ('plugin.manager.block ' ),
59- $ container ->get ('entity_type.manager ' )
70+ $ container ->get ('entity_type.manager ' ),
71+ $ container ->get ('entity_type.repository ' )
6072 );
6173 }
6274
@@ -74,6 +86,7 @@ public static function create(ContainerInterface $container) {
7486 * A render array.
7587 */
7688 public function build (SectionStorageInterface $ section_storage , $ delta , $ region ) {
89+ $ entity_type_label = $ this ->getEntityFieldCategoryLabels ();
7790 if ($ this ->entityTypeManager ->hasDefinition ('block_content_type ' ) && $ types = $ this ->entityTypeManager ->getStorage ('block_content_type ' )->loadMultiple ()) {
7891 if (count ($ types ) === 1 ) {
7992 $ type = reset ($ types );
@@ -132,13 +145,16 @@ public function build(SectionStorageInterface $section_storage, $delta, $region)
132145 'delta ' => $ delta ,
133146 'region ' => $ region ,
134147 ]);
148+ $ field_block_category_weight = -200 ;
149+ $ non_view_configurable_field_links = [];
150+ $ links = [];
135151 $ grouped_definitions = $ this ->blockManager ->getGroupedDefinitions ($ definitions );
136152 foreach ($ grouped_definitions as $ category => $ blocks ) {
137153 $ block_categories [$ category ]['#type ' ] = 'details ' ;
138154 $ block_categories [$ category ]['#attributes ' ]['class ' ][] = 'js-layout-builder-category ' ;
139- $ block_categories [$ category ]['#open ' ] = TRUE ;
155+ $ block_categories [$ category ]['#open ' ] = FALSE ;
140156 $ block_categories [$ category ]['#title ' ] = $ category ;
141- $ block_categories [$ category ][ ' links ' ] = $ this -> getBlockLinks ( $ section_storage , $ delta , $ region , $ blocks );
157+ $ this -> addBlockLinks ( $ block_categories [$ category ], $ section_storage , $ delta , $ region , $ blocks );
142158 }
143159 $ build ['block_categories ' ] = $ block_categories ;
144160 return $ build ;
@@ -166,7 +182,7 @@ public function inlineBlockList(SectionStorageInterface $section_storage, $delta
166182 $ blocks = $ this ->blockManager ->getGroupedDefinitions ($ definitions );
167183 $ build = [];
168184 if (isset ($ blocks ['Inline blocks ' ])) {
169- $ build [ ' links ' ] = $ this ->getBlockLinks ( $ section_storage , $ delta , $ region , $ blocks ['Inline blocks ' ]);
185+ $ this ->addBlockLinks ( $ build , $ section_storage , $ delta , $ region , $ blocks ['Inline blocks ' ]);
170186 $ build ['links ' ]['#attributes ' ]['class ' ][] = 'inline-block-list ' ;
171187 $ build ['back_button ' ] = [
172188 '#type ' => 'link ' ,
@@ -186,8 +202,10 @@ public function inlineBlockList(SectionStorageInterface $section_storage, $delta
186202 }
187203
188204 /**
189- * Gets a render array of block links.
205+ * Adds a render array of block links.
190206 *
207+ * @param array $render_array
208+ * Render array to add links to.
191209 * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
192210 * The section storage.
193211 * @param int $delta
@@ -200,9 +218,14 @@ public function inlineBlockList(SectionStorageInterface $section_storage, $delta
200218 * @return array
201219 * The block links render array.
202220 */
203- protected function getBlockLinks (SectionStorageInterface $ section_storage , $ delta , $ region , array $ blocks ) {
221+ protected function addBlockLinks (&$ render_array , SectionStorageInterface $ section_storage , $ delta , $ region , array $ blocks ) {
222+ static $ field_block_category_weight = -200 ;
204223 $ links = [];
224+ $ category = NULL ;
205225 foreach ($ blocks as $ block_id => $ block ) {
226+ if (!$ category ) {
227+ $ category = $ block ['category ' ];
228+ }
206229 $ attributes = $ this ->getAjaxAttributes ();
207230 $ attributes ['class ' ][] = 'js-layout-builder-block-link ' ;
208231 $ link = [
@@ -218,10 +241,40 @@ protected function getBlockLinks(SectionStorageInterface $section_storage, $delt
218241 ),
219242 'attributes ' => $ attributes ,
220243 ];
221-
222- $ links [] = $ link ;
244+ if ($ block ['id ' ] === 'field_block ' && empty ($ block ['_is_view_configurable ' ])) {
245+ $ non_view_configurable_field_links [] = $ link ;
246+ }
247+ else {
248+ $ links [] = $ link ;
249+ }
250+ }
251+ if ($ non_view_configurable_field_links ) {
252+ if (empty ($ links )) {
253+ // If no other links exist add these links as top level links for the
254+ // category.
255+ $ links = $ non_view_configurable_field_links ;
256+ }
257+ else {
258+ $ render_array ['more_fields ' ] = [
259+ '#type ' => 'details ' ,
260+ '#title ' => $ this ->t ('More+ ' ),
261+ '#open ' => FALSE ,
262+ 'links ' => [
263+ '#theme ' => 'links ' ,
264+ '#links ' => $ non_view_configurable_field_links ,
265+ ],
266+ '#weight ' => 100 ,
267+ ];
268+ }
269+ }
270+ // If this a entity category and there are links besides non 'view'
271+ // configurable field blocks move the category to the top and open it.
272+ if (in_array ($ category , $ this ->getEntityFieldCategoryLabels ()) && $ links ) {
273+ $ render_array ['#open ' ] = TRUE ;
274+ $ render_array ['#weight ' ] = $ field_block_category_weight ;
275+ $ field_block_category_weight += 10 ;
223276 }
224- return [
277+ $ render_array [ ' links ' ] = [
225278 '#theme ' => 'links ' ,
226279 '#links ' => $ links ,
227280 ];
@@ -244,4 +297,19 @@ protected function getAjaxAttributes() {
244297 return [];
245298 }
246299
300+ /**
301+ * Gets the category labels used for entity fields.
302+ *
303+ * @return string[]
304+ * The category labels.
305+ */
306+ protected function getEntityFieldCategoryLabels () {
307+ $ entity_type_labels = $ this ->entityTypeRepository ->getEntityTypeLabels ();
308+ foreach ($ entity_type_labels as &$ entity_type_label ) {
309+ $ entity_type_label = $ this ->t ('@entity fields ' , ['@entity ' => $ entity_type_label ])
310+ ->render ();
311+ }
312+ return $ entity_type_labels ;
313+ }
314+
247315}
0 commit comments