Wie füge ich eine benutzerdefinierte Registerkarte auf der Benutzerprofilseite hinzu?

11

Ich muss eine benutzerdefinierte Registerkarte in der Benutzerprofilseite hinzufügen. Ich habe meine Route wie folgt definiert:

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

Nach dem Löschen des Caches wird auf der Profilseite die Registerkarte angezeigt. Wenn ich jedoch die URL / user / 1 / custom öffne, wird die Meldung "Seite nicht gefunden" angezeigt.

ARUN
quelle
1
Benutzer: \ d + sollte unter die Anforderungen fallen - nehmen Sie diese Änderung vor, leeren Sie den gesamten Cache und prüfen Sie, ob die Seite immer noch nicht gefunden wird.
Kevin

Antworten:

5

Ihr Problem liegt in der mymodule.routing.ymlDatei, das große Problem ist der Ort user: \d+, diese Zeile muss sich unter dem requirements:Abschnitt befinden, das andere Problem ist der Einzug. Der endgültige Code sollte also lauten:

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

Und natürlich benötigen Sie die Formularklassendefinition in 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) {  }

}

Und eine mymodule.info.ymlDatei zur Vervollständigung Ihres Moduls (in diesem Fall mymodule)

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

Referenz: Struktur der Routen

Adrian Cid Almaguer
quelle
Interessant, dass in der Struktur der Routen weder der Schlüssel erwähnt wird, user:noch wohin er gehen soll ... Vielleicht müssen die Dokumente verbessert / bearbeitet werden? oder habe ich etwas verpasst
Kein Sssweat
Ich sehe, nvm, es ist unter _entity_access: und sie haben dort den Knoten als Beispiel verwendet, weshalb mein STRG + F "Benutzer:" nichts gefunden hat.
Kein Sssweat
3

Es gibt zwei Möglichkeiten, ein Formular über eine Route zu laden. Sie können entweder einen Rückruf laden, der ein Formular lädt und als Teil des Build-Arrays zurückgibt, oder Sie können das Formular direkt laden, indem Sie den Parameter _form unter den Standardeinstellungen festlegen.

Sie können die Codebasis durchsuchen, um Arbeitsbeispiele zu finden, sie in Ihre Datei mymodule.routing.yml kopieren, sie nach Ihren Wünschen bearbeiten und dann den Cache neu erstellen.

Formular vom Rückruf laden:

Im Kontaktmodul gibt es ein funktionierendes Beispiel:

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

Dann in /core/modules/contact/src/Controller/ContactController.php

Im Rückruf sehen Sie ein Beispiel zum Laden eines Formulars:

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

Formular direkt von der Route laden:

Wenn Sie das Formular direkt mit der Standardeinstellung _form laden möchten, finden Sie ein Beispiel im Verknüpfungsmodul unter /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+

In diesem Fall wird der Benutzer als Parameter an das Formular übergeben (siehe /core/modules/shortcut/src/Form/SwitchShortcutSet.php)

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

Ein paar Dinge, die ich sofort erkennen kann ...

Du hast ALLES mit dem Namen mymodule.account. Ich würde das ein bisschen diversifizieren. Ziehen Sie dies für die Aufgabenseite in Betracht:

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

Ich glaube auch nicht, dass Sie dafür etwas im Menü brauchen.

Zwischen diesen beiden sollten Sie gut zu gehen sein! Sie können sich gerne direkt an mich wenden, wenn Sie dies nicht herausfinden können, da ich - NUR - dies für meinen D8-Port von Apply For Role verwendet habe!

Jnicola
quelle
1

In modulename.routing.yml müssen Sie das Benutzerargument wie unten übergeben

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

und in modulename.links.task.yml haben Sie den Code wie unten

profile.user_information:
  title: User profile
  route_name: profile.user_information
  base_route: entity.user.canonical
Entmutigen
quelle