<?php // create the container for settings $form['layouts'] = array('#type' => 'details', '#attributes' => array('class' => array('debug')), '#title' => t('Layout Builder'), '#description' => t('<p class="description">You are able to configure your layouts based on any breakpoint defined in your Omega subtheme, or any base theme that the theme uses. Each layout is assigned to a single breakpoint, and then will be able to be used in Layout Configuration when choosing a layout to use for default or particular page types.</p>'), '#weight' => -799, '#group' => 'omega', '#tree' => TRUE); // the active layout we are editing. // this var will be unset during submit $form['layouts']['edit_this_layout'] = array('#prefix' => '<div id="layout-editor-select">', '#suffix' => '</div>', '#type' => 'radios', '#attributes' => array('class' => array('layout-select', 'clearfix')), '#title' => 'Select Layout to Edit', '#description' => t('<p class="description">You are able to edit only one layout at a time.</p><p class="description"> The amount of configurations passed through the form requires limiting this ability until Drupal core issue <a href="https://www.drupal.org/node/1565704" target="_blank"><strong>#1565704</strong></a> can be resolved. </p>'), '#options' => $availableLayouts, '#default_value' => isset($edit_this_layout) ? $edit_this_layout : theme_get_setting('default_layout', $theme), '#tree' => FALSE, '#states' => $omegaGSon); $breakpoint_options = _omega_getAvailableBreakpoints($theme); foreach ($layouts as $lid => $ldata) { $form['layouts'][$lid] = array('#type' => 'fieldset', '#title' => $lid, '#prefix' => '<div id="layout-' . $lid . '-config">', '#suffix' => '</div>', '#group' => 'layouts', '#collapsible' => TRUE, '#collapsed' => FALSE, '#tree' => TRUE, '#states' => array('visible' => array(':input[name="edit_this_layout"]' => array('value' => $lid)))); $active_breakpoint_group = theme_get_setting('breakpoint_group_' . $lid, $theme); //dsm($active_breakpoint_group); $current_breakpoint_group = isset($active_breakpoint_group) ? $active_breakpoint_group : 'omega.standard'; $form['layouts'][$lid]['breakpoint_group_' . $lid] = array('#type' => 'select', '#options' => $breakpoint_options, '#title' => t('Breakpoint group'), '#description' => t('<p class="description">This breakpoint group will apply to this layout any time it is used. This allows you to use a different breakpoint group for different layouts.</p>'), '#default_value' => $current_breakpoint_group, '#tree' => FALSE, '#states' => $omegaGSon); $form['layouts'][$lid]['breakpoint_group_updated'] = array('#type' => 'item', '#prefix' => '', '#markup' => '<div class="messages messages--warning omega-styles-info">By changing the breakpoint group for the "<strong>' . $lid . '</strong>" layout, You will need to save the form in order to then configure the theme regions based on the new breakpoint group.</div>', '#suffix' => '', '#states' => array('invisible' => array(':input[name="breakpoint_group_' . $lid . '"]' => array('value' => $current_breakpoint_group)))); $breakpoints = _omega_getActiveBreakpoints($lid, $theme); // foreach breakpoint we have, we will create a form element group and appropriate settings for region layouts per breakpoint. foreach ($breakpoints as $breakpoint) { //kint($breakpoint->getBaseId()); // create a 'clean' version of the id to use to match what we want in our yml structure $idtrim = omega_return_clean_breakpoint_id($breakpoint); $form['layouts'][$lid]['region_groups'][$idtrim] = array('#type' => 'details', '#attributes' => array('class' => array('layout-breakpoint')), '#title' => $breakpoint->getLabel() . ' -- ' . $breakpoint->getMediaQuery() . '', '#weight' => $breakpoint->getWeight(), '#group' => 'layout', '#states' => array('invisible' => array(':input[name="enable_omegags_layout"]' => array('checked' => FALSE)), 'visible' => array(':input[name="breakpoint_group_' . $lid . '"]' => array('value' => $current_breakpoint_group)))); //dsm($breakpoints); foreach ($region_groups as $gid => $info) { // determine if configuration says region group should be collapsed or not $open = TRUE; $collapseVal = $layouts[$lid]['region_groups'][$idtrim][$gid]['collapsed']; //krumo($info); if (isset($collapseVal) && $collapseVal == 'TRUE') { $open = FALSE; }
/** * Custom function to generate layout SCSS from layout variables * Currently performs the following operations: * - Cycles a given layout for breakpoints * - Cycles a breakpoint for region groups * - Cycles a region group for regions * - Cycles a region for various settings to apply to the region * - Returns SCSS designed to be passed to _omega_compile_layout_css */ function _omega_compile_layout_sass($layout, $layoutName, $theme = 'omega', $options) { //dsm($layout); // get a list of themes $themes = \Drupal::service('theme_handler')->listInfo(); // get the current settings/info for the theme $themeSettings = $themes[$theme]; // get the default layout/breakpoint group $defaultLayout = $layoutName; // get all the active breakpoints we'll be editing $breakpoints = _omega_getActiveBreakpoints($theme); // get the stored layout data // $layouts = theme_get_setting('layouts', $theme); // pull an array of "region groups" based on the "all" media query that should always be present // @todo consider adjusting this data to be stored in the top level of the $theme.layout.$layout.yml file instead $region_groups = $layout['region_groups']['all']; //dsm($region_groups); //dsm($layouts); $theme_regions = $themeSettings->info['regions']; // create variable to hold all SCSS we need $scss = ''; $parser = new SassParser($options); // get the variables for the theme $vars = realpath(".") . base_path() . drupal_get_path('theme', 'omega') . '/style/scss/vars.scss'; $omegavars = new SassFile(); $varscss = $omegavars->get_file_contents($vars, $parser); // set the grid to fluid $varscss .= '$twidth: 100%;'; // get the SCSS for the grid system $gs = realpath(".") . base_path() . drupal_get_path('theme', 'omega') . '/style/scss/grids/omega.scss'; $omegags = new SassFile(); $gsscss = $omegags->get_file_contents($gs, $parser); $scss = $varscss . $gsscss; // loop over the media queries foreach ($breakpoints as $breakpoint) { // create a clean var for the scss for this breakpoint $breakpoint_scss = ''; $idtrim = omega_return_clean_breakpoint_id($breakpoint); // loop over the region groups foreach ($region_groups as $gid => $info) { // add row mixin // @todo change $layout['region_groups'][$idtrim][$gid] to $info $rowname = str_replace("_", "-", $gid) . '-layout'; $rowval = $layout['region_groups'][$idtrim][$gid]['row']; $primary_region = $layout['region_groups'][$idtrim][$gid]['primary_region']; $total_regions = count($layout['region_groups'][$idtrim][$gid]['regions']); $maxwidth = $layout['region_groups'][$idtrim][$gid]['maxwidth']; if ($layout['region_groups'][$idtrim][$gid]['maxwidth_type'] == 'pixel') { $unit = 'px'; } else { $unit = '%'; } // FORMATTED INTENTIONALLY $breakpoint_scss .= ' // Breakpoint: ' . $breakpoint->getLabel() . '; Region Group: ' . $gid . '; .' . $rowname . ' { @include row(' . $rowval . '); max-width: ' . $maxwidth . $unit . '; '; // END FORMATTED INTENTIONALLY // loop over regions for basic responsive configuration foreach ($layout['region_groups'][$idtrim][$gid]['regions'] as $rid => $data) { $regionname = str_replace("_", "-", $rid); // FORMATTED INTENTIONALLY $breakpoint_scss .= ' // Breakpoint: ' . $breakpoint->getLabel() . '; Region Group: ' . $gid . '; Region: ' . $rid . '; .region--' . $regionname . ' { @include column(' . $layout['region_groups'][$idtrim][$gid]['regions'][$rid]['width'] . ', ' . $layout['region_groups'][$idtrim][$gid]['row'] . '); '; if ($layout['region_groups'][$idtrim][$gid]['regions'][$rid]['prefix'] > 0) { $breakpoint_scss .= ' @include prefix(' . $layout['region_groups'][$idtrim][$gid]['regions'][$rid]['prefix'] . '); '; } if ($layout['region_groups'][$idtrim][$gid]['regions'][$rid]['suffix'] > 0) { $breakpoint_scss .= ' @include suffix(' . $layout['region_groups'][$idtrim][$gid]['regions'][$rid]['suffix'] . '); '; } if ($layout['region_groups'][$idtrim][$gid]['regions'][$rid]['push'] > 0) { $breakpoint_scss .= ' @include push(' . $layout['region_groups'][$idtrim][$gid]['regions'][$rid]['push'] . '); '; } if ($layout['region_groups'][$idtrim][$gid]['regions'][$rid]['pull'] > 0) { $breakpoint_scss .= ' @include pull(' . $layout['region_groups'][$idtrim][$gid]['regions'][$rid]['pull'] . '); '; } $breakpoint_scss .= ' margin-bottom: $regionSpacing; } '; // end of initial region configuration // END FORMATTED INTENTIONALLY } // check to see if primary region is set if ($primary_region && $total_regions <= 3) { // FORMATTED INTENTIONALLY $breakpoint_scss .= ' // A primary region exists for the ' . $gid . ' region group. // so we are going to iterate over combinations of available/missing // regions to change the layout for this group based on those scenarios. // 1 missing region '; // END FORMATTED INTENTIONALLY // loop over the regions that are not the primary one again $mainRegion = $layout['region_groups'][$idtrim][$gid]['regions'][$primary_region]; $otherRegions = $layout['region_groups'][$idtrim][$gid]['regions']; unset($otherRegions[$primary_region]); $num_otherRegions = count($otherRegions); $cols = $layout['region_groups'][$idtrim][$gid]['row']; $classMatch = array(); // in order to ensure the primary region we want to assign extra empty space to // exists, we use the .with--region_name class so it would only apply if the // primary region is present. $classCreate = array('.with--' . $primary_region); foreach ($otherRegions as $orid => $odata) { $classCreate[] = '.without--' . $regionname; $regionname = str_replace("_", "-", $orid); // combine the region widths $adjust = _omega_layout_generation_adjust($mainRegion, array($otherRegions[$orid]), $cols); // FORMATTED INTENTIONALLY $breakpoint_scss .= ' &.with--' . $primary_region . '.without--' . $regionname . ' { .region--' . $primary_region . ' { @include column-reset(); @include column(' . $adjust['width'] . ', ' . $cols . ');'; // END FORMATTED INTENTIONALLY // @todo need to adjust for push/pull here // ACK!!! .sidebar-first would need push/pull adjusted if // the sidebar-second is gone // this might be IMPOSSIBLE $pushPullAltered = FALSE; if ($adjust['pull'] >= 1) { // FORMATTED INTENTIONALLY $pushPullAltered = TRUE; $breakpoint_scss .= ' @include pull(' . $adjust['pull'] . ');'; // END FORMATTED INTENTIONALLY } if ($adjust['push'] >= 1) { // FORMATTED INTENTIONALLY $pushPullAltered = TRUE; $breakpoint_scss .= ' @include push(' . $adjust['push'] . ');'; // END FORMATTED INTENTIONALLY } // FORMATTED INTENTIONALLY $breakpoint_scss .= ' }'; // end of iteration of condition missing one region // END FORMATTED INTENTIONALLY // now what if we adjusted the push/pull of the main region, or the // remaining region had a push/pull, we need to re-evaluate the layout for that region if ($pushPullAltered) { // find that other remaining region. $region_other = $otherRegions; unset($region_other[$orid]); $region_other_keys = array_keys($region_other); $region_other_id = $region_other_keys[0]; $regionname_other = str_replace("_", "-", $region_other_id); $otherRegionWidth = $region_other[$region_other_id]['width']; $breakpoint_scss .= ' .region--' . $regionname_other . ' { @include column-reset(); @include column(' . $region_other[$region_other_id]['width'] . ', ' . $cols . ');'; // END FORMATTED INTENTIONALLY // APPEARS to position the remaining (not primary) region // BUT the primary region is positioned wrong with push/pull // if there is a pull on the primary region, we adjust the push on the remaining one if ($adjust['pull'] >= 1) { // FORMATTED INTENTIONALLY $pushPullAltered = TRUE; $breakpoint_scss .= ' @include push(' . $adjust['width'] . ');'; // END FORMATTED INTENTIONALLY } // if there is a push on the primary region, we adjust the pull on the remaining one if ($adjust['push'] >= 1) { // FORMATTED INTENTIONALLY $pushPullAltered = TRUE; $breakpoint_scss .= ' @include pull(' . $adjust['width'] . ');'; // END FORMATTED INTENTIONALLY } // FORMATTED INTENTIONALLY $breakpoint_scss .= ' }'; // end of iteration of condition missing one region // END FORMATTED INTENTIONALLY } // FORMATTED INTENTIONALLY $breakpoint_scss .= ' } '; // end of intial loop of regions to assign individual cases of missing regions first in the scss/css // END FORMATTED INTENTIONALLY } // end foreach loop // FORMATTED INTENTIONALLY // throw a comment in the scss $breakpoint_scss .= ' // 2 missing regions '; // END FORMATTED INTENTIONALLY // here we are beginning to loop again, assuming more than just // one region might be missing and to assign to the primary_region accordingly $classMatch = array(); //$classCreate = array(); // loop the "other" regions that aren't the primary one again foreach ($otherRegions as $orid => $odata) { $regionname = str_replace("_", "-", $orid); //$classCreate[] = '.with--'. $primary_region . '.without--' . $regionname; // now that we are looping, we will loop again to then create // .without--sidebar-first.without--sidebar-second.without--sidebar-second foreach ($otherRegions as $orid2 => $odata2) { $regionname2 = str_replace("_", "-", $orid2); $notYetMatched = TRUE; if ($regionname != $regionname2) { $attemptedTest = array('.with--' . $primary_region, '.without--' . $regionname, '.without--' . $regionname2); asort($attemptedTest); //dsm($attemptedTest); $attemptedMatch = implode('', $attemptedTest); //asort() if (in_array($attemptedMatch, $classMatch)) { $notYetMatched = FALSE; } $adjust = _omega_layout_generation_adjust($mainRegion, array($otherRegions[$orid], $otherRegions[$orid2]), $cols); if ($notYetMatched) { $classCreate = '.with--' . $primary_region . '.without--' . $regionname . '.without--' . $regionname2; $classMatch[] = $attemptedMatch; if (count($classMatch) >= 1) { //dsm($classMatch); } // FORMATTED INTENTIONALLY $breakpoint_scss .= ' &' . $classCreate . ' { .region--' . $primary_region . ' { @include column-reset(); @include column(' . $adjust['width'] . ', ' . $cols . '); '; // END FORMATTED INTENTIONALLY // @todo need to adjust for push/pull here // FORMATTED INTENTIONALLY $breakpoint_scss .= ' }'; // END FORMATTED INTENTIONALLY // FORMATTED INTENTIONALLY $breakpoint_scss .= ' } '; // END FORMATTED INTENTIONALLY } // end if ($notYetMatched) } // end if ($regionname != $regionname2) } // end foreach $otherRegions (2nd loop) } // end foreach $otherRegions (1st loop) } // end if($primary_region) // FORMATTED INTENTIONALLY $breakpoint_scss .= ' } '; // end of region group // END FORMATTED INTENTIONALLY } // if not the defualt media query that should apply to all screens // we will wrap the scss we've generated in the appropriate media query. if ($breakpoint->getLabel() != 'all') { $breakpoint_scss = '@media ' . $breakpoint->getMediaQuery() . ' { ' . $breakpoint_scss . ' } '; } // add in the SCSS from this breakpoint and add to our SCSS $scss .= $breakpoint_scss; //dsm($breakpoint_scss); } return $scss; }