1

On Drupal 8, there is a page on /node/add. I want to customize this page by replacing the links with buttons, but I have not found a template to do that.

I have also enabled the debug mode, but there is no template suggestion.

How do I customize the page?

<div role="main" class="main-container container js-quickedit-main-content">
    <div class="row">

        <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12" role="heading">
            <div class="region region-header">
            </div>
        </div>

        <section class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
            <a id="main-content"></a>
            <div class="region region-content">
                <h1 class="page-header">Ajouter du contenu</h1>
                <dl>
                    <dt><a href="/node/add/annonce">Annonce</a></dt>
                    <dd></dd>
                    <dt><a href="/node/add/article">Article</a></dt>
                    <dd></dd>
                    <dt><a href="/node/add/discussion">Discussion</a></dt>
                    <dd></dd>
                    <dt><a href="/node/add/recette">Recette</a></dt>
                    <dd></dd>
                </dl>
            </div>
        </section>

    </div>
</div>
2

As very first step try the Adminimal - Responsive Administration Theme. Maybe this does already what you want. If no, then I see two options:

  1. Create a sub-theme of your current back-end theme to add custom CSS.
  2. Create a custom module to add your CSS to just that page.

I normally choose option 2.

The following snippet adds a custom library to the node/add page. And the rest is just CSS. To make certain links look like buttons.

MYMODULE.module

/**
 * Implements hook_page_attachments().
 */
function MYMODULE_page_attachments(array &$attachments) {

  $route_name = \Drupal::routeMatch()->getRouteName();

  if ($route_name == 'node.add_page') {
    $attachments['#attached']['library'][] = 'MYMODULE/foobar';
  }
}

MYMODULE.libraries.yml

foobar:
  css:
    theme:
      css/foobar.css: {}

css/foobar.css

a.some-link {
  background-color: crimson;  
  border-radius: 5px;
  color: white;
  padding: .5em;
  text-decoration: none;
}

a.some-link:focus,
a.some-link:hover {
  background-color: firebrick;
  color: white;
}

After you've updated your question it seems you want completely customized markup. Which would make your question too broad. But there are two things you need to accomplish for that. From your new custom module at best.

  1. Create a new custom form with your buttons.
  2. Create a new custom route to place your form.
  3. Attach your CSS to your form or your route.
  • I updated my question with the HTML code of my page. Yes I replaced with the article content type. – user90818 Dec 1 '18 at 12:53
  • I would like to get this (markup for this page) demo.getopensocial.com/node/add – user90818 Dec 1 '18 at 13:06
  • @marmath – What do you really want? First you said you want to make some links to be buttons? Now you say you want a totally different form? – leymannx Dec 1 '18 at 14:54
  • @marmath – I updated my answer to add the custom CSS to the node/add page. And not to the form. – leymannx Dec 1 '18 at 15:06
2

Forms are manipulated in Drupal 8 predominantly by using services, twig templates and yaml files, rather than hooks. Hooks are still used, but the code in the hooks is limited in comparison with Drupal 7.

On the other hand, new D8 concepts such as Services and Event Subscribers have become much more important.

Here's a good tutorial showing how to alter the Drupal 8 login form:

https://www.foreach.be/blog/how-manipulate-forms-drupal-8

Follow the steps in the tutorial to create a simple form_overwrite module.

When you get to the step where you create the src/Routing/RouteSubscriber.php file, you'll diverge slightly from the tutorial.

Instead of altering the routeSubscriber for user.login, you'll want to alter the one for node.add:

<?php

/**
 * @file
 * Contains \Drupal\form_overwrite\Routing\RouteSubscriber.
 */

namespace Drupal\form_overwrite\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class RouteSubscriber extends RouteSubscriberBase {
  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    // This is the one from the linked article
    if ($route = $collection->get('user.login')) {
      $route->setDefault('_form', '\Drupal\form_overwrite\Form\NewUserLoginForm');
    }
    // This is the one you want to write
    if ($route = $collection->get('node.add')) {
      $route->setDefault('_form', '\Drupal\form_overwrite\Form\NewNodeAddForm');
    }
  }
}

Armed with this knowledge, you should be able to adapt the linked tutorial to suit your needs. Good luck!

  • 2
    Hm, your example doesn't describe how to alter the form, or certain elements. But to replace the entire form. Which I think is not what OP asked for. To alter forms hook_form_alter still is the way to go. – leymannx Dec 1 '18 at 2:53
  • 1
    Turned out, after OP updated their question, your answer is much closer to what they want. – leymannx Dec 1 '18 at 15:53
  • 1
    @leymannx, yes, this is a good answer, but as you said to replace a form alter hook it is missing the last step, extending the original form class and overriding buidForm() from where you can get the existing form elements with parent::buildForm(). – 4k4 Dec 2 '18 at 9:08