/**
  * Ajax callback to remove a field collection from a multi-valued field.
  *
  * @param array $form
  * @param \Drupal\Core\Form\FormStateInterface $form_state
  *
  * @return \Drupal\Core\Ajax\AjaxResponse
  *   An AjaxResponse object.
  */
 function ajaxRemove(array $form, FormStateInterface &$form_state)
 {
     // Process user input. $form and $form_state are modified in the process.
     //\Drupal::formBuilder()->processForm($form['#form_id'], $form, $form_state);
     // Retrieve the element to be rendered.
     $trigger = $form_state->getTriggeringElement();
     $form_parents = explode('/', $trigger['#ajax']['options']['query']['element_parents']);
     $address = array_slice($form_parents, 0, -1);
     $form = NestedArray::getValue($form, $address);
     $status_messages = array('#theme' => 'status_messages');
     $renderer = \Drupal::service('renderer');
     $form['#prefix'] = empty($form['#prefix']) ? $renderer->render($status_messages) : $form['#prefix'] . $renderer->render($status_messages);
     $output = $renderer->render($form);
     drupal_process_attached($form);
     // TODO: Preserve javascript.  See https://www.drupal.org/node/2502743 .
     $response = new AjaxResponse();
     return $response->addCommand(new ReplaceCommand(NULL, $output));
 }
 /**
  * {@inheritdoc}
  */
 public function render(array $render_array)
 {
     $content = $this->drupalRenderRoot($render_array);
     if (!empty($render_array)) {
         drupal_process_attached($render_array);
     }
     $cache = !empty($render_array['#cache']['tags']) ? ['tags' => $render_array['#cache']['tags']] : [];
     $fragment = new HtmlFragment($content, $cache);
     if (isset($render_array['#title'])) {
         $fragment->setTitle($render_array['#title'], Title::FILTER_XSS_ADMIN);
     }
     $attached = isset($render_array['#attached']) ? $render_array['#attached'] : [];
     $attached += ['feed' => [], 'html_head' => [], 'html_head_link' => []];
     // Add feed links from the page content.
     foreach ($attached['feed'] as $feed) {
         $fragment->addLinkElement(new FeedLinkElement($feed[1], $this->urlGenerator->generateFromPath($feed[0])));
     }
     // Add generic links from the page content.
     foreach ($attached['html_head_link'] as $link) {
         $fragment->addLinkElement(new LinkElement($this->urlGenerator->generateFromPath($link[0]['href']), $link[0]['rel']));
     }
     // @todo Also transfer the contents of "_drupal_add_html_head" once
     // https://www.drupal.org/node/2296951 lands.
     // @todo Transfer CSS and JS over to the fragment once those are supported
     // on the fragment object.
     return $fragment;
 }
 /**
  * Verifies that the datepicker can be localized.
  *
  * @see locale_library_info_alter()
  */
 public function testLibraryInfoAlter()
 {
     $attached['#attached']['library'][] = 'core/jquery.ui.datepicker';
     drupal_render($attached);
     drupal_process_attached($attached);
     $scripts = drupal_get_js();
     $this->assertTrue(strpos($scripts, 'locale.datepicker.js'), 'locale.datepicker.js added to scripts.');
 }
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     if ($form_state->getValue('add_files')) {
         $path = drupal_get_path('module', 'system');
         $attached = array('#attached' => array('css' => array($path . '/css/system.admin.css' => array()), 'js' => array(0 => array('type' => 'setting', 'data' => array('ajax_forms_test_lazy_load_form_submit' => 'executed')), $path . '/system.js' => array())));
         drupal_render($attached);
         drupal_process_attached($attached);
     }
     $form_state->setRebuild();
 }
Example #5
0
 /**
  * Tests drupal_process_attached().
  */
 public function testDrupalProcessAttached()
 {
     // Specify invalid attachments in a render array.
     $build['#attached']['library'][] = 'core/drupal.states';
     $build['#attached']['drupal_process_states'][] = [];
     try {
         drupal_process_attached($build);
         $this->fail("Invalid #attachment 'drupal_process_states' allowed");
     } catch (\Exception $e) {
         $this->pass("Invalid #attachment 'drupal_process_states' not allowed");
     }
 }
 /**
  * {@inheritdoc}
  */
 public function build()
 {
     // Grab test attachment fixtures from
     // Drupal\render_attached_test\Controller\TestController.
     $controller = new TestController();
     $attached = BubbleableMetadata::mergeAttachments($controller->feed(), $controller->head());
     $attached = BubbleableMetadata::mergeAttachments($attached, $controller->header());
     $attached = BubbleableMetadata::mergeAttachments($attached, $controller->teapotHeaderStatus());
     // Use drupal_process_attached() to attach all the #attached stuff.
     drupal_process_attached($attached);
     // Return some arbitrary markup so the block doesn't disappear.
     return ['#markup' => 'Headers handled by drupal_process_attached().'];
 }
 /**
  * Processes AJAX file uploads and deletions.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The current request object.
  *
  * @return \Drupal\Core\Ajax\AjaxResponse
  *   An AjaxResponse object.
  */
 public function upload(Request $request)
 {
     $form_parents = explode('/', $request->query->get('element_parents'));
     $form_build_id = $request->query->get('form_build_id');
     $request_form_build_id = $request->request->get('form_build_id');
     if (empty($request_form_build_id) || $form_build_id !== $request_form_build_id) {
         // Invalid request.
         drupal_set_message(t('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (@size) that this server supports.', array('@size' => format_size(file_upload_max_size()))), 'error');
         $response = new AjaxResponse();
         $status_messages = array('#theme' => 'status_messages');
         return $response->addCommand(new ReplaceCommand(NULL, drupal_render($status_messages)));
     }
     try {
         /** @var $ajaxForm \Drupal\system\FileAjaxForm */
         $ajaxForm = $this->getForm($request);
         $form = $ajaxForm->getForm();
         $form_state = $ajaxForm->getFormState();
         $commands = $ajaxForm->getCommands();
     } catch (HttpExceptionInterface $e) {
         // Invalid form_build_id.
         drupal_set_message(t('An unrecoverable error occurred. Use of this form has expired. Try reloading the page and submitting again.'), 'error');
         $response = new AjaxResponse();
         $status_messages = array('#theme' => 'status_messages');
         return $response->addCommand(new ReplaceCommand(NULL, drupal_render($status_messages)));
     }
     // Get the current element and count the number of files.
     $current_element = NestedArray::getValue($form, $form_parents);
     $current_file_count = isset($current_element['#file_upload_delta']) ? $current_element['#file_upload_delta'] : 0;
     // Process user input. $form and $form_state are modified in the process.
     drupal_process_form($form['#form_id'], $form, $form_state);
     // Retrieve the element to be rendered.
     $form = NestedArray::getValue($form, $form_parents);
     // Add the special Ajax class if a new file was added.
     if (isset($form['#file_upload_delta']) && $current_file_count < $form['#file_upload_delta']) {
         $form[$current_file_count]['#attributes']['class'][] = 'ajax-new-content';
     } else {
         $form['#suffix'] .= '<span class="ajax-new-content"></span>';
     }
     $status_messages = array('#theme' => 'status_messages');
     $form['#prefix'] .= drupal_render($status_messages);
     $output = drupal_render($form);
     drupal_process_attached($form);
     $js = _drupal_add_js();
     $settings = drupal_merge_js_settings($js['settings']['data']);
     $response = new AjaxResponse();
     foreach ($commands as $command) {
         $response->addCommand($command, TRUE);
     }
     return $response->addCommand(new ReplaceCommand(NULL, $output, $settings));
 }
 /**
  * Tests attaching feeds with paths, URLs, and titles.
  */
 function testBasicFeedAddNoTitle()
 {
     $path = $this->randomMachineName(12);
     $external_url = 'http://' . $this->randomMachineName(12) . '/' . $this->randomMachineName(12);
     $fully_qualified_local_url = Url::fromUri('base:' . $this->randomMachineName(12), array('absolute' => TRUE))->toString();
     $path_for_title = $this->randomMachineName(12);
     $external_for_title = 'http://' . $this->randomMachineName(12) . '/' . $this->randomMachineName(12);
     $fully_qualified_for_title = Url::fromUri('base:' . $this->randomMachineName(12), array('absolute' => TRUE))->toString();
     $urls = array('path without title' => array('url' => Url::fromUri('base:' . $path, array('absolute' => TRUE))->toString(), 'title' => ''), 'external URL without title' => array('url' => $external_url, 'title' => ''), 'local URL without title' => array('url' => $fully_qualified_local_url, 'title' => ''), 'path with title' => array('url' => Url::fromUri('base:' . $path_for_title, array('absolute' => TRUE))->toString(), 'title' => $this->randomMachineName(12)), 'external URL with title' => array('url' => $external_for_title, 'title' => $this->randomMachineName(12)), 'local URL with title' => array('url' => $fully_qualified_for_title, 'title' => $this->randomMachineName(12)));
     $build = [];
     foreach ($urls as $feed_info) {
         $build['#attached']['feed'][] = [$feed_info['url'], $feed_info['title']];
     }
     drupal_process_attached($build);
     $this->setRawContent(drupal_get_html_head());
     foreach ($urls as $description => $feed_info) {
         $this->assertPattern($this->urlToRSSLinkPattern($feed_info['url'], $feed_info['title']), format_string('Found correct feed header for %description', array('%description' => $description)));
     }
 }
Example #9
0
 /**
  * Tests AjaxResponse::prepare() AJAX commands ordering.
  */
 public function testOrder()
 {
     $path = drupal_get_path('module', 'system');
     $expected_commands = array();
     // Expected commands, in a very specific order.
     $expected_commands[0] = new SettingsCommand(array('ajax' => 'test'), TRUE);
     drupal_static_reset('_drupal_add_css');
     $attached = array('#attached' => array('css' => array($path . '/css/system.admin.css' => array(), $path . '/css/system.maintenance.css' => array())));
     drupal_render($attached);
     drupal_process_attached($attached);
     $expected_commands[1] = new AddCssCommand(drupal_get_css(_drupal_add_css(), TRUE));
     drupal_static_reset('_drupal_add_js');
     $attached = array('#attached' => array('js' => array($path . '/system.js' => array())));
     drupal_render($attached);
     drupal_process_attached($attached);
     $expected_commands[2] = new PrependCommand('head', drupal_get_js('header', _drupal_add_js(), TRUE));
     drupal_static_reset('_drupal_add_js');
     $attached = array('#attached' => array('js' => array($path . '/system.modules.js' => array('scope' => 'footer'))));
     drupal_render($attached);
     drupal_process_attached($attached);
     $expected_commands[3] = new AppendCommand('body', drupal_get_js('footer', _drupal_add_js(), TRUE));
     $expected_commands[4] = new HtmlCommand('body', 'Hello, world!');
     // Load any page with at least one CSS file, at least one JavaScript file
     // and at least one #ajax-powered element. The latter is an assumption of
     // drupalPostAjaxForm(), the two former are assumptions of
     // AjaxReponse::ajaxRender().
     // @todo refactor AJAX Framework + tests to make less assumptions.
     $this->drupalGet('ajax_forms_test_lazy_load_form');
     // Verify AJAX command order — this should always be the order:
     // 1. JavaScript settings
     // 2. CSS files
     // 3. JavaScript files in the header
     // 4. JavaScript files in the footer
     // 5. Any other AJAX commands, in whatever order they were added.
     $commands = $this->drupalPostAjaxForm(NULL, array(), NULL, 'ajax-test/order', array(), array(), NULL, array());
     $this->assertCommand(array_slice($commands, 0, 1), $expected_commands[0]->render(), 'Settings command is first.');
     $this->assertCommand(array_slice($commands, 1, 1), $expected_commands[1]->render(), 'CSS command is second (and CSS files are ordered correctly).');
     $this->assertCommand(array_slice($commands, 2, 1), $expected_commands[2]->render(), 'Header JS command is third.');
     $this->assertCommand(array_slice($commands, 3, 1), $expected_commands[3]->render(), 'Footer JS command is fourth.');
     $this->assertCommand(array_slice($commands, 4, 1), $expected_commands[4]->render(), 'HTML command is fifth.');
 }
 /**
  * {@inheritdoc}
  */
 public function render(HtmlFragmentInterface $fragment, $status_code = 200)
 {
     // Converts the given HTML fragment which represents the main content region
     // of the page into a render array.
     $page_content['main'] = array('#markup' => $fragment->getContent());
     $page_content['#title'] = $fragment->getTitle();
     if ($fragment instanceof CacheableInterface) {
         $page_content['main']['#cache']['tags'] = $fragment->getCacheTags();
     }
     // Build the full page array by calling drupal_prepare_page(), which invokes
     // hook_page_build(). This adds the other regions to the page.
     $page_array = drupal_prepare_page($page_content);
     // Build the HtmlPage object.
     $page = new HtmlPage('', array(), $fragment->getTitle());
     $page = $this->preparePage($page, $page_array);
     $page->setBodyTop(drupal_render($page_array['page_top']));
     $page->setBodyBottom(drupal_render($page_array['page_bottom']));
     $page->setContent(drupal_render($page_array));
     $page->setStatusCode($status_code);
     drupal_process_attached($page_array);
     if (isset($page_array['page_top'])) {
         drupal_process_attached($page_array['page_top']);
     }
     if (isset($page_array['page_bottom'])) {
         drupal_process_attached($page_array['page_bottom']);
     }
     if ($fragment instanceof CacheableInterface) {
         // Persist cache tags associated with this page. Also associate the
         // "rendered" cache tag. This allows us to invalidate the entire render
         // cache, regardless of the cache bin.
         $cache_tags = $page_array['#cache']['tags'];
         $cache_tags[] = 'rendered';
         // Only keep unique cache tags. We need to prevent duplicates here already
         // rather than only in the cache layer, because they are also used by
         // reverse proxies (like Varnish), not only by Drupal's page cache.
         $page->setCacheTags(array_unique($cache_tags));
     }
     return $page;
 }
Example #11
0
 /**
  * Test attached feed rendering as a side-effect.
  *
  * @return array
  *   A render array using the 'feed' directive.
  */
 public function feedDpa()
 {
     drupal_process_attached($this->feed());
     return ['#markup' => "I'm some markup here to fool the kernel into rendering this page."];
 }
 /**
  * Renders a render array.
  *
  * @param array $elements
  *   The elements to render.
  *
  * @return string
  *   The rendered string output (typically HTML).
  */
 protected function render(array &$elements)
 {
     $content = drupal_render($elements);
     drupal_process_attached($elements);
     $this->setRawContent($content);
     $this->verbose('<pre style="white-space: pre-wrap">' . String::checkPlain($content));
     return $content;
 }
 /**
  * Wraps drupal_render.
  *
  * @param array $elements
  *   The structured array describing the data to be rendered.
  *
  * @return string
  *   The rendered HTML.
  *
  * @todo Remove once drupal_render is converted to autoloadable code.
  * @see https://drupal.org/node/2171071
  */
 protected function drupalRender(array $elements)
 {
     $output = drupal_render($elements);
     drupal_process_attached($elements);
     return $output;
 }
Example #14
0
 /**
  * Returns AJAX commands to load in-place editors' attachments.
  *
  * Given a list of in-place editor IDs as POST parameters, render AJAX
  * commands to load those in-place editors.
  *
  * @return \Drupal\Core\Ajax\AjaxResponse
  *   The Ajax response.
  */
 public function attachments(Request $request)
 {
     $response = new AjaxResponse();
     $editors = $request->request->get('editors');
     if (!isset($editors)) {
         throw new NotFoundHttpException();
     }
     $elements['#attached'] = $this->editorSelector->getEditorAttachments($editors);
     drupal_process_attached($elements);
     return $response;
 }
 /**
  * {@inheritdoc}
  */
 public function processAttachments(AttachmentsInterface $response)
 {
     // @todo Convert to assertion once https://www.drupal.org/node/2408013 lands
     if (!$response instanceof HtmlResponse) {
         throw new \InvalidArgumentException('\\Drupal\\Core\\Render\\HtmlResponse instance expected.');
     }
     // First, render the actual placeholders; this may cause additional
     // attachments to be added to the response, which the attachment
     // placeholders rendered by renderHtmlResponseAttachmentPlaceholders() will
     // need to include.
     $response = $this->renderPlaceholders($response);
     $attached = $response->getAttachments();
     // Get the placeholders from attached and then remove them.
     $attachment_placeholders = $attached['html_response_attachment_placeholders'];
     unset($attached['html_response_attachment_placeholders']);
     $variables = $this->processAssetLibraries($attached, $attachment_placeholders);
     // Handle all non-asset attachments. This populates drupal_get_html_head().
     $all_attached = ['#attached' => $attached];
     drupal_process_attached($all_attached);
     // Get HTML head elements - if present.
     if (isset($attachment_placeholders['head'])) {
         $variables['head'] = drupal_get_html_head(FALSE);
     }
     // Now replace the attachment placeholders.
     $this->renderHtmlResponseAttachmentPlaceholders($response, $attachment_placeholders, $variables);
     // Finally set the headers on the response if any bubbled.
     if (!empty($attached['http_header'])) {
         $this->setHeaders($response, $attached['http_header']);
     }
     return $response;
 }
 /**
  * {@inheritdoc}
  */
 public function processAttachments(AttachmentsInterface $response)
 {
     // @todo Convert to assertion once https://www.drupal.org/node/2408013 lands
     if (!$response instanceof HtmlResponse) {
         throw new \InvalidArgumentException('\\Drupal\\Core\\Render\\HtmlResponse instance expected.');
     }
     // First, render the actual placeholders; this may cause additional
     // attachments to be added to the response, which the attachment
     // placeholders rendered by renderHtmlResponseAttachmentPlaceholders() will
     // need to include.
     //
     // @todo Exceptions should not be used for code flow control. However, the
     //   Form API does not integrate with the HTTP Kernel based architecture of
     //   Drupal 8. In order to resolve this issue properly it is necessary to
     //   completely separate form submission from rendering.
     //   @see https://www.drupal.org/node/2367555
     try {
         $response = $this->renderPlaceholders($response);
     } catch (EnforcedResponseException $e) {
         return $e->getResponse();
     }
     $attached = $response->getAttachments();
     // Get the placeholders from attached and then remove them.
     $attachment_placeholders = $attached['html_response_attachment_placeholders'];
     unset($attached['html_response_attachment_placeholders']);
     $variables = $this->processAssetLibraries($attached, $attachment_placeholders);
     // Handle all non-asset attachments. This populates drupal_get_html_head().
     $all_attached = ['#attached' => $attached];
     drupal_process_attached($all_attached);
     // Get HTML head elements - if present.
     if (isset($attachment_placeholders['head'])) {
         $variables['head'] = drupal_get_html_head(FALSE);
     }
     // Now replace the attachment placeholders.
     $this->renderHtmlResponseAttachmentPlaceholders($response, $attachment_placeholders, $variables);
     // Finally set the headers on the response if any bubbled.
     if (!empty($attached['http_header'])) {
         $this->setHeaders($response, $attached['http_header']);
     }
     return $response;
 }
 /**
  * Wraps drupal_render.
  *
  * @param string $name
  *   The name of the library.
  *
  * @todo Remove once drupal_render is converted to autoloadable code.
  * @see https://drupal.org/node/2171071
  */
 protected function drupalAttachLibrary($name)
 {
     $attached['#attached']['library'][] = $name;
     drupal_process_attached($attached);
 }
Example #18
0
 /**
  * Wraps drupal_render_root().
  *
  * @todo: Remove as part of https://drupal.org/node/2182149
  */
 protected function drupalRenderRoot(&$elements)
 {
     $output = drupal_render_root($elements);
     drupal_process_attached($elements);
     return $output;
 }
 /**
  * Tests css/js storage and restoring mechanism.
  */
 function testHeaderStorage()
 {
     // Create a view with output caching enabled.
     // Some hook_views_pre_render in views_test_data.module adds the test css/js file.
     // so they should be added to the css/js storage.
     $view = Views::getView('test_view');
     $view->setDisplay();
     $view->storage->set('id', 'test_cache_header_storage');
     $view->display_handler->overrideOption('cache', array('type' => 'time', 'options' => array('output_lifespan' => '3600')));
     $output = $view->preview();
     drupal_render($output);
     unset($view->pre_render_called);
     $view->destroy();
     $view->setDisplay();
     $output = $view->preview();
     drupal_render($output);
     $css_path = drupal_get_path('module', 'views_test_data') . '/views_cache.test.css';
     $js_path = drupal_get_path('module', 'views_test_data') . '/views_cache.test.js';
     $this->assertTrue(in_array($css_path, $output['#attached']['css']), 'Make sure the css is added for cached views.');
     $this->assertTrue(in_array($js_path, $output['#attached']['js']), 'Make sure the js is added for cached views.');
     $this->assertFalse(!empty($view->build_info['pre_render_called']), 'Make sure hook_views_pre_render is not called for the cached view.');
     // Now add some css/jss before running the view.
     // Make sure that this css is not added when running the cached view.
     $view->storage->set('id', 'test_cache_header_storage_2');
     $attached = array('#attached' => array('css' => array(drupal_get_path('module', 'system') . '/css/system.maintenance.css' => array()), 'js' => array(drupal_get_path('module', 'user') . '/user.permissions.js' => array())));
     drupal_render($attached);
     drupal_process_attached($attached);
     $view->destroy();
     $output = $view->preview();
     drupal_render($output);
     $this->assertTrue(empty($output['#attached']['css']), 'The view does not have attached CSS.');
     $this->assertTrue(empty($output['#attached']['js']), 'The view does not have attached JS.');
     $view->destroy();
     $output = $view->preview();
     drupal_render($output);
     $this->assertTrue(empty($output['#attached']['css']), 'The cached view does not have attached CSS.');
     $this->assertTrue(empty($output['#attached']['js']), 'The cached view does not have attached JS.');
 }
 /**
  * {@inheritdoc}
  */
 public function render(array $output, $status_code = 200)
 {
     if (!isset($output['#title'])) {
         $output['#title'] = $this->titleResolver->getTitle(\Drupal::request(), \Drupal::routeMatch()->getRouteObject());
     }
     $page = new HtmlPage('', isset($output['#cache']) ? $output['#cache'] : array(), $output['#title']);
     $page_array = drupal_prepare_page($output);
     $page = $this->fragmentRenderer->preparePage($page, $page_array);
     $page->setBodyTop(drupal_render($page_array['page_top']));
     $page->setBodyBottom(drupal_render($page_array['page_bottom']));
     $page->setContent(drupal_render($page_array));
     drupal_process_attached($page_array);
     if (isset($page_array['page_top'])) {
         drupal_process_attached($page_array['page_top']);
     }
     if (isset($page_array['page_bottom'])) {
         drupal_process_attached($page_array['page_bottom']);
     }
     $page->setStatusCode($status_code);
     return $page;
 }
Example #21
0
/**
 * Theme callback for rendering an Omega layout.
 */
function theme_omega_page_layout($variables)
{
    // Clean up the theme hook suggestion so we don't end up in an infinite loop.
    unset($variables['theme_hook_suggestion'], $variables['theme_hook_suggestions']);
    $layout = $variables['omega_layout'];
    drupal_process_attached(array('#attached' => $layout['attached']));
    omega_layout_load_theme_assets($layout['name']);
    $hook = str_replace('-', '_', $variables['omega_layout']['template']);
    return theme($hook, $variables);
}
 /**
  * Displays content in a dialog.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request object.
  * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  *   The route match.
  * @param mixed $_content
  *   A controller definition string, or a callable object/closure.
  * @param bool $modal
  *   (optional) TRUE to render a modal dialog. Defaults to FALSE.
  *
  * @return \Drupal\Core\Ajax\AjaxResponse
  *   AjaxResponse to return the content wrapper in a dialog.
  */
 public function dialog(Request $request, RouteMatchInterface $route_match, $_content, $modal = FALSE)
 {
     $page_content = $this->getContentResult($request, $_content);
     // Allow controllers to return a HtmlPage or a Response object directly.
     if ($page_content instanceof HtmlPage) {
         $page_content = $page_content->getContent();
     }
     if ($page_content instanceof Response) {
         $page_content = $page_content->getContent();
     }
     // Most controllers return a render array, but some return a string.
     if (!is_array($page_content)) {
         $page_content = array('#markup' => $page_content);
     }
     $content = drupal_render($page_content);
     drupal_process_attached($page_content);
     $title = isset($page_content['#title']) ? $page_content['#title'] : $this->titleResolver->getTitle($request, $route_match->getRouteObject());
     $response = new AjaxResponse();
     // Fetch any modal options passed in from data-dialog-options.
     $options = $request->request->get('dialogOptions', array());
     // Set modal flag and re-use the modal ID.
     if ($modal) {
         $options['modal'] = TRUE;
         $target = '#drupal-modal';
     } else {
         // Generate the target wrapper for the dialog.
         if (isset($options['target'])) {
             // If the target was nominated in the incoming options, use that.
             $target = $options['target'];
             // Ensure the target includes the #.
             if (substr($target, 0, 1) != '#') {
                 $target = '#' . $target;
             }
             // This shouldn't be passed on to jQuery.ui.dialog.
             unset($options['target']);
         } else {
             // Generate a target based on the route id.
             $route_name = $route_match->getRouteName();
             $target = '#' . drupal_html_id("drupal-dialog-{$route_name}");
         }
     }
     $response->addCommand(new OpenDialogCommand($target, $title, $content, $options));
     return $response;
 }
Example #23
0
 /**
  * Renders a render array.
  *
  * @param array $elements
  *   The elements to render.
  *
  * @return string
  *   The rendered string output (typically HTML).
  */
 protected function render(array &$elements)
 {
     $content = $this->container->get('renderer')->renderRoot($elements);
     drupal_process_attached($elements);
     $this->setRawContent($content);
     $this->verbose('<pre style="white-space: pre-wrap">' . SafeMarkup::checkPlain($content));
     return $content;
 }
Example #24
0
/**
 * Theme callback for rendering an Omega layout.
 */
function omega_omega_layout($variables)
{
    drupal_process_attached(array('#attached' => $variables['omega_layout']['attached']));
    // Clean up the theme hook suggestion so we don't end up in an infinite loop.
    unset($variables['theme_hook_suggestion'], $variables['theme_hook_suggestions']);
    return theme($variables['omega_layout']['template'], $variables);
}
 /**
  * Renders a page using a custom page theme hook and optional region content.
  *
  * Temporary shim to facilitate modernization progress for special front
  * controllers (install.php, update.php, authorize.php), maintenance mode, and
  * the exception handler.
  *
  * Do NOT use this method in your code. This method will be removed as soon
  * as architecturally possible.
  *
  * This is functionally very similar to DefaultHtmlFragmentRenderer::render()
  * but with the following important differences:
  *
  * - drupal_prepare_page() and hook_page_build() cannot be invoked on the
  *   maintenance and install pages, since possibly enabled page layout/block
  *   modules would replace the main page content with configured region
  *   content.
  * - This function composes a complete page render array including a page
  *   template theme suggestion (as opposed to the main page content only).
  * - The render cache and cache tags is skipped.
  *
  * @param array|string $main
  *   A render array or string containing the main page content.
  * @param string $title
  *   (optional) The page title.
  * @param string $theme
  *   (optional) The theme hook to use for rendering the page.  Defaults to
  *   'maintenance'. The given value will be appended with '_page' to compose
  *   the #theme property for #type 'page' currently; e.g., 'maintenance'
  *   becomes 'maintenance_page'. Ultimately this parameter will be converted
  *   into a page template theme suggestion; i.e., 'page__$theme'.
  * @param array $regions
  *   (optional) Additional region content to add to the page. The given array
  *   is added to the page render array, so this parameter may also be used to
  *   pass e.g. the #show_messages property for #type 'page'.
  *
  * @return string
  *   The rendered HTML page.
  *
  * @internal
  */
 public static function renderPage($main, $title = '', $theme = 'maintenance', array $regions = array())
 {
     // Automatically convert the main page content into a render array.
     if (!is_array($main)) {
         $main = array('#markup' => $main);
     }
     $page = new HtmlPage('', array(), $title);
     $page_array = array('#type' => 'page', '#theme' => $theme . '_page', '#title' => $title, 'content' => array('system_main' => $main));
     // Append region content.
     $page_array += $regions;
     // Add default properties.
     $page_array += element_info('page');
     // hook_page_build() cannot be invoked on the maintenance and install pages,
     // because the application is in an unknown or special state.
     // In particular on the install page, invoking hook_page_build() directly
     // after e.g. Block module has been installed would *replace* the installer
     // output with the configured blocks of the installer theme (loaded from
     // default configuration of the installation profile).
     // Allow modules and themes to alter the page render array.
     // This allows e.g. themes to attach custom libraries.
     \Drupal::moduleHandler()->alter('page', $page_array);
     // @todo Move preparePage() before alter() above, so $page_array['#page'] is
     //   available in hook_page_alter(), so that HTML attributes can be altered.
     $page = \Drupal::service('html_fragment_renderer')->preparePage($page, $page_array);
     $page->setBodyTop(drupal_render($page_array['page_top']));
     $page->setBodyBottom(drupal_render($page_array['page_bottom']));
     $page->setContent(drupal_render($page_array));
     drupal_process_attached($page_array);
     if (isset($page_array['page_top'])) {
         drupal_process_attached($page_array['page_top']);
     }
     if (isset($page_array['page_bottom'])) {
         drupal_process_attached($page_array['page_bottom']);
     }
     return \Drupal::service('html_page_renderer')->render($page);
 }
 /**
  * {@inheritdoc}
  */
 public function processAttachments(AttachmentsInterface $response)
 {
     // @todo Convert to assertion once https://www.drupal.org/node/2408013 lands
     if (!$response instanceof HtmlResponse) {
         throw new \InvalidArgumentException('\\Drupal\\Core\\Render\\HtmlResponse instance expected.');
     }
     $attached = $response->getAttachments();
     // Get the placeholders from attached and then remove them.
     $placeholders = $attached['html_response_placeholders'];
     unset($attached['html_response_placeholders']);
     $variables = $this->processAssetLibraries($attached, $placeholders);
     // Handle all non-asset attachments. This populates drupal_get_html_head()
     // and drupal_get_http_header().
     $all_attached = ['#attached' => $attached];
     drupal_process_attached($all_attached);
     // Get HTML head elements - if present.
     if (isset($placeholders['head'])) {
         $variables['head'] = drupal_get_html_head(FALSE);
     }
     // Now replace the placeholders in the response content with the real data.
     $this->renderPlaceholders($response, $placeholders, $variables);
     // Finally set the headers on the response.
     $headers = drupal_get_http_header();
     $this->setHeaders($response, $headers);
     return $response;
 }
Example #27
0
 /**
  * Wrapper for handling AJAX forms.
  *
  * Wrapper around \Drupal\Core\Form\FormBuilderInterface::buildForm() to
  * handle some AJAX stuff automatically.
  * This makes some assumptions about the client.
  *
  * @param \Drupal\Core\Form\FormInterface|string $form_class
  *   The value must be one of the following:
  *   - The name of a class that implements \Drupal\Core\Form\FormInterface.
  *   - An instance of a class that implements \Drupal\Core\Form\FormInterface.
  * @param \Drupal\Core\Form\FormStateInterface $form_state
  *   The current state of the form.
  *
  * @return \Drupal\Core\Ajax\AjaxResponse|string|array
  *   Returns one of three possible values:
  *   - A \Drupal\Core\Ajax\AjaxResponse object.
  *   - The rendered form, as a string.
  *   - A render array with the title in #title and the rendered form in the
  *   #markup array.
  */
 protected function ajaxFormWrapper($form_class, FormStateInterface &$form_state)
 {
     /** @var \Drupal\Core\Render\RendererInterface $renderer */
     $renderer = \Drupal::service('renderer');
     // This won't override settings already in.
     if (!$form_state->has('rerender')) {
         $form_state->set('rerender', FALSE);
     }
     $ajax = $form_state->get('ajax');
     // Do not overwrite if the redirect has been disabled.
     if (!$form_state->isRedirectDisabled()) {
         $form_state->disableRedirect($ajax);
     }
     $form_state->disableCache();
     // Builds the form in a render context in order to ensure that cacheable
     // metadata is bubbled up.
     $render_context = new RenderContext();
     $callable = function () use($form_class, &$form_state) {
         return \Drupal::formBuilder()->buildForm($form_class, $form_state);
     };
     $form = $renderer->executeInRenderContext($render_context, $callable);
     if (!$render_context->isEmpty()) {
         BubbleableMetadata::createFromRenderArray($form)->merge($render_context->pop())->applyTo($form);
     }
     $output = $renderer->renderRoot($form);
     drupal_process_attached($form);
     // These forms have the title built in, so set the title here:
     $title = $form_state->get('title') ?: '';
     if ($ajax && (!$form_state->isExecuted() || $form_state->get('rerender'))) {
         // If the form didn't execute and we're using ajax, build up an
         // Ajax command list to execute.
         $response = new AjaxResponse();
         // Attach the library necessary for using the OpenModalDialogCommand and
         // set the attachments for this Ajax response.
         $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
         $response->setAttachments($form['#attached']);
         $display = '';
         $status_messages = array('#type' => 'status_messages');
         if ($messages = $renderer->renderRoot($status_messages)) {
             $display = '<div class="views-messages">' . $messages . '</div>';
         }
         $display .= $output;
         $options = array('dialogClass' => 'views-ui-dialog', 'width' => '75%');
         $response->addCommand(new OpenModalDialogCommand($title, $display, $options));
         if ($section = $form_state->get('#section')) {
             $response->addCommand(new Ajax\HighlightCommand('.' . Html::cleanCssIdentifier($section)));
         }
         return $response;
     }
     return $title ? ['#title' => $title, '#markup' => $output] : $output;
 }
 /**
  * Wraps drupal_render().
  *
  * @todo: Remove as part of https://drupal.org/node/2182149
  */
 protected function drupalRender(&$elements, $is_recursive_call = FALSE)
 {
     $output = drupal_render($elements, $is_recursive_call);
     drupal_process_attached($elements);
     return $output;
 }