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

11

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 lorsque j'ouvre l'url / user / 1 / custom, je vois le message de page introuvable.

ARUN
la source
1
utilisateur: \ d + devrait être soumis aux exigences - apportez cette modification, videz tout le cache, voyez si vous obtenez toujours une page introuvable.
Kevin

Réponses:

5

Votre problème est dans le mymodule.routing.ymlfichier, le gros problème est l'endroit où user: \d+, cette ligne doit être sous la 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.ymlfichier pour compléter 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

Adrian Cid Almaguer
la source
Il est intéressant de noter que la structure des itinéraires ne mentionne pas la clé user:ni où elle doit aller ... Peut-être que les documents doivent être améliorés / édités? ou ai-je raté quelque chose?
Pas de Sssweat le
nvm, je vois, c'est sous _entity_access: et ils ont utilisé node comme exemple là-bas, d'où pourquoi mon "utilisateur:" CTRL + F n'a rien trouvé.
Pas de Sssweat le
3

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;
  }

Formulaire de chargement 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) {
oknate
la source
1

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!

Jnicola
la source
1

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
Debasish
la source