web-dev-qa-db-fra.com

Comment ajouter un onglet personnalisé dans la page de profil utilisateur?

Je dois ajouter un onglet personnalisé dans la page de profil utilisateur. J'ai défini mon itinéraire comme ci-dessous:

mymodule.routing.yml

mymodule.account:
path: '/user/{user}/custom'
defaults: 
  _form: '\Drupal\mymodule\Form\MyModuleUserSettingsForm'
  _title: 'Custom Settings'
  user: \d+
requirements:
  _permission: 'access content'

mymodule.links.task.yml

mymodule.account:
  title: Mymodule Settings
  route_name: mymodule.account
  base_route: entity.user.canonical

mymodule.links.menu.yml

mymodule.account:
  title: My module Settings
  parent: entity.user.canonical
  route_name: mymodule.account

Ensuite, après l'effacement de l'onglet cache apparaît dans la page de profil. Mais quand j'ouvre l'url / user/1/custom je vois le message de page non trouvée.

11
ARUN

Votre problème est dans le mymodule.routing.yml fichier, le gros problème est la place de user: \d+, cette ligne doit se trouver sous le requirements: section, l'autre problème est l'indentation. Le code final devrait donc être:

mymodule.account:
  path: '/user/{user}/custom'
  defaults: 
    _form: '\Drupal\mymodule\Form\MyModuleUserSettingsForm'
    _title: 'Custom Settings'
  requirements:
    _permission: 'access content'
    user: \d+

Et bien sûr, vous avez besoin de la définition de classe de formulaire dans src/Form/MyModuleUserSettingsForm.php

<?php

namespace Drupal\mymodule\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Class MyModuleUserSettingsForm.
 *
 * @package Drupal\mymodule\Form
 */
class MyModuleUserSettingsForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'simple_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['title'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Title'),
      '#maxlength' => 64,
      '#size' => 64,
      '#required' => TRUE,
    ];
    $form['submit'] = [
      '#type' => 'submit',
      '#value' => t('Submit'),
    ];

    return $form;
  }

  public function validateForm(array &$form, FormStateInterface $form_state) {  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {  }

}

Et un mymodule.info.yml fichier pour terminer votre module (dans ce cas nommé mymodule)

name: My Module
type: module
description: 'My module'
core: 8.x
package: Custom

Référence: Structure des itinéraires

5
Adrian Cid Almaguer

Il existe deux façons de charger un formulaire à l'aide d'un itinéraire. Vous pouvez soit charger un rappel qui charge un formulaire et le renvoie dans le cadre du tableau de génération, soit charger directement le formulaire en définissant le paramètre _form sous les valeurs par défaut.

Vous pouvez rechercher la base de code pour trouver des exemples de travail, les copier dans votre mymodule.routing.yml, les modifier selon vos besoins, puis reconstruire le cache.

Chargement du formulaire depuis le rappel:

Il y a un exemple de travail dans le module de contact:

/core/modules/contact/contact.routing.yml

entity.user.contact_form:
  path: '/user/{user}/contact'
  defaults:
    _title: 'Contact'
    _controller: '\Drupal\contact\Controller\ContactController::contactPersonalPage'
  requirements:
    _access_contact_personal_tab: 'TRUE'
    user: \d+

Puis dans /core/modules/contact/src/Controller/ContactController.php

vous pouvez voir un exemple de chargement d'un formulaire dans le rappel:

  public function contactPersonalPage(UserInterface $user) {
    // Do not continue if the user does not have an email address configured.
    if (!$user->getEmail()) {
      throw new NotFoundHttpException();
    }

    $message = $this->entityManager()->getStorage('contact_message')->create(array(
      'contact_form' => 'personal',
      'recipient' => $user->id(),
    ));

    $form = $this->entityFormBuilder()->getForm($message);
    $form['#title'] = $this->t('Contact @username', array('@username' => $user->getDisplayName()));
    $form['#cache']['contexts'][] = 'user.permissions';
    return $form;
  }

Chargement du formulaire directement depuis l'itinéraire:

Si vous souhaitez charger le formulaire directement en utilisant le _form par défaut, il y a un exemple dans le module de raccourci à /core/modules/shortcut/shortcut.routing.yml

shortcut.set_switch:
  path: '/user/{user}/shortcuts'
  defaults:
    _form: 'Drupal\shortcut\Form\SwitchShortcutSet'
    _title: 'Shortcuts'
  requirements:
    _custom_access: 'Drupal\shortcut\Form\SwitchShortcutSet::checkAccess'
  options:
    _admin_route: TRUE
    user: \d+

Dans ce cas, l'utilisateur est transmis en tant que paramètre au formulaire, voir /core/modules/shortcut/src/Form/SwitchShortcutSet.php

  public function buildForm(array $form, FormStateInterface $form_state, UserInterface $user = NULL) {
3
oknate

Quelques choses que je peux repérer ...

Vous avez TOUT nommé mymodule.account. Je diversifierais un peu cela. Pensez à aller avec cela pour la page des tâches:

mymodule.account_tab:
  title: Mymodule Settings
  route_name: mymodule.account
  base_route: entity.user.canonical

Je ne pense pas non plus que vous ayez besoin de quoi que ce soit dans le menu pour cela.

Entre ces deux, tu devrais être prêt à partir! N'hésitez pas à me contacter directement si vous ne pouvez pas comprendre cela parce que j'ai - JUSTE - réussi à le faire fonctionner sur mon port D8 de Apply For Role!

1
Jnicola

Dans modulename.routing.yml, vous devez passer l'argument utilisateur comme ci-dessous

profile.user_information:
  path: '/user/{user}/profile'
  defaults:
    _form: '\Drupal\profile\Form\UserInformation'
    _title: 'UserInformation'
  requirements:
    _permission: 'access content'
  options:
    user: \d+

et dans modulename.links.task.yml vous avez le code comme ci-dessous

profile.user_information:
  title: User profile
  route_name: profile.user_information
  base_route: entity.user.canonical
1
Debasish