Construire un menu dynamique

Information importante

En raison d'un grand nombre d'inscriptions de spammers sur notre site, polluant sans relache notre forum, nous suspendons la création de compte via le formulaire de "sign up".

Il est néanmoins toujours possible de devenir adhérent•e en faisant la demande sur cette page, rubrique "Inscription" : https://www.drupal.fr/contact


De plus, le forum est désormais "interdit en écriture". Il n'est plus autorisé d'y écrire un sujet/billet/commentaire.

Pour contacter la communauté, merci de rejoindre le slack "drupalfrance".

Si vous voulez contacter le bureau de l'association, utilisez le formulaire disponible ici, ou envoyez-nous un DM sur twitter.

Bonjour,

J’ai une demande un peu particulière dont je ne me sors pas depuis un moment, j’espère donc que vous pourrez m'aider.
Le contexte :
Un utilisateur ne peut créer qu'un seul nœud dont il sera propriétaire.
Ne souhaitant pas utiliser le menu d'admin standard, je voudrais construire un menu qui me permettrait de créer / modifier / dépublier son noeud.

Le souci :
Comment créer le lien de menu qui me permet de récupérer l'id du noeud comme le fait le menu local task de base de drupal ? (ou alors dans quel bout de code est construit ce menu pour en copier le principe ?

Le but étant d'avoir un lien du type : www.domain.fr/modifier/ 'node_id' et que ça me renvoie sur le lien de base de drupal : www.domain.fr/node/{node_id}/edit

Merci beaucoup beaucoup

Forum : 
Version de Drupal : 

Il faut créer un module. A l'intérieur, tu définis un bloc qui contiendra les options que tu veux utiliser. Ce bloc, tu pourras ensuite l'inclure dans le bloc layout de l'ui de Drupal8.

Concernant les options, par exemple la publication et la dépublication d'un noeud, il faut créer des routes (fichier : ton_module.routing.yml). Cela te mène vers le controlleur de ton module. Là, il suffit juste de charger l'objet du noeud, faire un $ton_node->setPublished() ou $ton_node->setUnpublished() puis un $ton_node->save() et enfin rediriger vers la page d'où tu viens.

Merci, le module est déjà crée ainsi que le block menu.
Ce qui me pose problème c'est justement le chargement du nœud dans le contrôleur qui correspond au propriétaire (donc à la personne logguée)
En gros comment on reconstruit le menu "local_task" d'un noeud presque en générant un lien qui reprend cet id de noeud
Je ne sais pas si je suis clair désolé si ce n'est pas le cas :(

Ce n'est pas très clair surtout que j'ai fait récemment quelque chose comme ça donc il est probable que j'entrevois ta problématique sous le prisme de la mienne ce qui n'est pas nécessairement une bonne chose.

Pour m'assurer que la personne loggué est la propriétaire de l'article (node), je fais simplement ça :

$uid = \Drupal::currentUser()->id();
$node = \Drupal::routeMatch()->getParameter('node');
if ($node->getUntranslated()->getOwnerid()==$uid) {
// tes options pour la gestion du noeud par l'utilisateur
}

Notes que l'on peut aussi simplement faire :
$node->getOwnerid()==$uid
Mais dans mon cas, je travaille sur un site en 4 langues et les traductions faites par des traducteurs sont curieusement attribuées non pas à l'auteur original mais aux traducteurs. Le getUntranslated() me permet seulement de m'assurer que c'est bien l'auteur original qui tente de modifier le noeud (ou l'une des traductions du noeud).

Pas sûr que je répondes réellement à ta question. C'est d'ailleurs mon premier projet Drupal et je butes sans arrêt sur son aspect extrêmement peu intuitif.

En relisant, tu parles de construction de liens... C'est peut-être plutôt ça qu'il te faut :

$url = \Drupal\Core\Url::fromRoute('TA_ROUTE', array('id' => $node->id()));
$lien = $url->toString();

Sur ce, je vais continuer à galérer de mon côté ! ;)

Tu as bien cerné mon souci merci !
Les traductions seront faites par le propriétaire du nœud donc aucun souci de ce côté là.

Pour le routing oui j'ai du mal à comprendre comment construire le lien mais je suis encore loin d'être un expert :(

Je vais creuser ça merci beaucoup !

Une précision : je cherche à générer ce menu sur tout le site donc le lien "dynamique" de son nœud ne devra pas seulement apparaitre sur le nœud en question mais sur n'importe lequel du site (ou vue ou autre)

Dans tonmodule.routing.yml

tu mets par exemple :

TONMODULE.modifier_noeud:
path: '/modifier/{id}'
defaults:
_controller: '\Drupal\TONMODULE\Controller\TONMODULEController::modifier_noeud'
_title: ''
requirements:
_permission: 'access content'

Du coup, quand tu veux créer ton lien, tu fais :
$url = \Drupal\Core\Url::fromRoute('TONMODULE.modifier_noeud', array('id' => $node->id()));
$lien = $url->toString();
En sortie, tu auras un lien formaté par Drupal construit comme tu le désires.

Je te conseille de re-tester que l'utilisateur est bien l'auteur du noeud avant d'afficher le formulaire. Un test de plus ne mange pas de pain !

Et pour obtenir l'ID du noeud, tu indiques qu'il n'y en aura qu'un, tu peux faire ça :

$query = \Drupal::entityQuery('node')
->condition('uid', $uid);
$nid = $query->execute();

Ca te sort un tableau ($nid) de tous les noeuds de l'utilisateur dont l'id est $uid. Donc, si les utilisateurs n'en ont qu'un, ça ne doit sortir qu'un résultat dans le tableau.

Ah c'est super, du coup j'ai généré mon lien, j'ai juste dû modifier une ligne car le toString me mettais une erreur.
Du coup j'ai ça :

                $uid = $this->currentUser()->id();
     $query = \Drupal::entityQuery('node')
            ->condition('uid', $uid)
          ->condition('type', 'page');
        $nid = $query->execute();
       $url = \Drupal\Core\Url::fromRoute('MONMODULE.ROUTE_NAME', array($nid));
     $link = Link::fromTextAndUrl(t('lien généré'), $url);
        $link = $link->toRenderable();

     print render($project_link);

Ce qui me donne un lien du genre : http://domain.local/modification?6 (c'est pas très beau mais j'ai pas trouver pour mettre modification/6 à la place...

Le truc c'est qu'il faut l'affecter à mon lien de départ dans mon menu maintenant :) (et là drupal 7 et son hook_menu tout simple est regrettable)

Désolé du retard mais pour ceux qui chercherait la solution

$uid = $this->currentUser()->id();
      $query = \Drupal::entityQuery('node')
            ->condition('uid', $uid)
          ->condition('type', 'page');
        $nid = $query->execute();
       $id = array_values($nid)[0];
       $url = Url::fromRoute('entity.node.edit_form', ['node' => $id]);

       return new RedirectResponse($url->toString());