¿Cómo agrego una pestaña personalizada en la página de perfil de usuario?

11

Necesito agregar una pestaña personalizada en la página de perfil de usuario. Definí mi ruta como a continuación:

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

Luego, después de que aparece la pestaña borrar caché en la página de perfil. Pero cuando abro la url / user / 1 / custom veo el mensaje de página no encontrada.

ARUN
fuente
1
usuario: \ d + debe cumplir los requisitos: realice ese cambio, borre todo el caché, vea si aún no se encuentra la página.
Kevin

Respuestas:

5

Su problema está en el mymodule.routing.ymlarchivo, el gran problema es el lugar user: \d+, esta línea debe estar debajo de la requirements:sección, el otro problema es la sangría. Entonces el código final debería ser:

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

Y, por supuesto, necesita la definición de clase de formulario en 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) {  }

}

Y un mymodule.info.ymlarchivo para completar su módulo (en este caso llamado mymodule)

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

Referencia: Estructura de rutas.

Adrian Cid Almaguer
fuente
Es interesante que la Estructura de rutas no mencione la clave user:ni a dónde debería ir ... ¿Quizás los documentos necesitan ser mejorados / editados? o me perdí algo?
No Sssweat
nvm, ya veo, está bajo _entity_access: y usaron nodo como ejemplo allí, de ahí que mi "usuario" CTRL + F no haya encontrado nada.
No Sssweat
3

Hay dos formas de cargar un formulario utilizando una ruta. Puede cargar una devolución de llamada que carga un formulario y lo devuelve como parte de la matriz de compilación, o puede cargar el formulario directamente configurando el parámetro _form en los valores predeterminados.

Puede buscar en la base de código para encontrar ejemplos de trabajo, copiarlos en su mymodule.routing.yml, editarlos según sus necesidades y luego reconstruir el caché.

Cargando formulario de devolución de llamada:

Hay un ejemplo de trabajo en el módulo de contacto:

/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+

Luego en /core/modules/contact/src/Controller/ContactController.php

Puede ver un ejemplo de cómo cargar un formulario en la devolución de llamada:

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

Cargando formulario directamente desde la ruta:

Si desea cargar el formulario directamente utilizando el _form predeterminado, hay un ejemplo en el módulo de acceso directo en /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+

En este caso, el usuario se pasa como un parámetro al formulario, consulte /core/modules/shortcut/src/Form/SwitchShortcutSet.php

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

Algunas cosas que puedo detectar de la mano ...

Tienes TODO llamado mymodule.account. Lo diversificaría un poco. Considere ir con esto para la página de tareas:

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

Tampoco creo que necesites nada en el menú para esto.

¡Entre esos dos, deberías estar listo! ¡Siéntase libre de comunicarse conmigo directamente si no puede resolver esto porque, SOLO, conseguí que esto funcione en mi puerto D8 de Solicitud de rol!

Jnicola
fuente
1

En modulename.routing.yml debe pasar el argumento del usuario como a continuación

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

y en modulename.links.task.yml tienes el código como a continuación

profile.user_information:
  title: User profile
  route_name: profile.user_information
  base_route: entity.user.canonical
Denigrar
fuente