2 votes

OrchardCMS : Comment accéder au champ booléen de l'élément de menu du contenu dans la vue cshtml ?

Dans Orchard, j'ai ajouté un champ booléen appelé "IsDone" à la partie de contenu intégrée Content Menu Item via cette interface d'administration. J'ai ensuite sélectionné un élément dans la navigation et défini l'option "oui" pour le champ correspondant que j'ai ajouté.

Dans mon thème personnalisé, j'ai copié le fichier MenuItem.cshtml.

Comment puis-je obtenir la valeur de mon champ personnalisé "IsDone" ici ?

J'ai essayé quelque chose comme

 dynamic item = Model.ContentItem;
 var myValue = item.MenuItem.IsDone.Value;

mais je suis presque sûr que ma syntaxe est incorrecte (car j'obtiens des erreurs de liaison nulle au moment de l'exécution).

Merci d'avance !

4voto

ViRuSTriNiTy Points 3631

Tout d'abord, je vous suggère d'utiliser la forme alternée MenuItemLink-ContentMenuItem.cshtml au lieu de MenuItem.cshtml pour cibler directement l'élément du menu de contenu.

Deuxièmement, le champ est rattaché à la ContentPart de l'élément de menu. Le code suivant récupère le champ booléen de cette partie de contenu :

@using Orchard.ContentManagement;
@using System.Linq;

@{
  Orchard.ContentManagement.ContentItem lContentItem = Model.Content.ContentItem;

  var lBooleanField = lContentItem
    .Parts
    .Where(p => p.PartDefinition.Name == "ContentMenuItem") // *1
    .SelectMany(p => p.Fields.Where(f => f.Name == "IsDone"))
    .FirstOrDefault() as Orchard.Fields.Fields.BooleanField;

  if (lBooleanField != null)
  {
    bool? v = lBooleanField.Value;

    if (v.HasValue)
    {
      if (v.Value)
      {
        @("done")
      }
      else
      {
        @("not done")
      }
    }
    else
    {
      @("not done")
    }
  }
}

*1 Malheureusement, vous ne pouvez pas simplement écrire lContentItem.As<Orchard.ContentManagement.ContentPart>() ici car la première pièce de la liste des pièces est dérivée de ce type, vous recevriez donc la mauvaise pièce.

3voto

rtpHarry Points 5306

Si la réponse de @ViRuSTriNiTy est probablement correcte, elle ne tire pas parti de la puissance des objets dynamiques que fournit Orchard.

Ceci fonctionne pour moi mais c'est une version beaucoup plus courte :

<a href="@Model.Href">@Model.Text</a>

@{
    bool? IsDone = Model.Content.ContentMenuItem.IsDone.Value;
    var IsItDoneThough = (IsDone.HasValue ? IsDone.Value : false);
}

<p>Is it done? @IsItDoneThough</p>

Vous pouvez voir que, dans la première ligne, je tire dans les IsDone en utilisant la nature dynamique de la Model .

Pour une raison quelconque (je suis sûr qu'il y en a une bonne quelque part), la BooleanField utilise un bool? comme valeur d'appui. En d'autres termes, si vous créez un nouvel élément de menu et que vous laissez la case à cocher vide, la valeur de la case sera la suivante null lorsque vous l'interrogez. Une fois que vous l'aurez sauvegardé comme vérifié, il sera true et si vous revenez en arrière et que vous le décochez, alors il aura la valeur false .

La deuxième ligne que j'ai fournie IsItDoneThough vérifie s'il a déjà une valeur. Si c'est le cas, il l'utilise, sinon il suppose qu'il s'agit de false .

Forme alternée

L'autre conseil de @ViRuSTriNiTy, de le modifier pour utiliser la méthode de l'utilisateur. MenuItemLink-ContentMenuItem.cshtml au lieu de MenuItem.cshtml est également important.

Le champ n'existe pas dans les autres éléments du menu, ce qui entraînera une panne si vous essayez d'y accéder. Il suffit de renommer le champ .cshtml pour résoudre ce problème.

Modèle dynamique

Pour conclure avec un petit aperçu de la façon dont j'y suis arrivé (je suis encore en train d'apprendre), voici comment j'ai procédé :

.Content est un moyen de transformer l'élément de contenu actuel en élément dynamique, afin que vous puissiez utiliser les avantages dynamiques avec le reste de la ligne ;

Lorsque vous ajoutez le champ dans le panneau d'administration, il semble qu'il doive se trouver sur le ContentItem, mais il crée en fait un ContentPart invisible pour le contenir et l'appelle en fonction du type du ContentItem.

Donc, si vous aviez ajouté ce champ à un Page type de contenu que vous auriez utilisé Model.Content.Page.IsDone.Value . Si vous aviez créé un nouveau type de contenu appelé "banane", il serait le suivant Model.Content.Banana.IsDone.Value etc.

Une fois que vous êtes à l'intérieur de la partie "invisible" qui contient les champs, vous pouvez enfin accéder à IsDone . Mais cela ne vous donnera pas encore la valeur réelle. Chaque Field a ses propres propriétés, que vous pouvez consulter dans le code source. l'élément IsDone est en fait un BooleanField et il expose ses données via le Value propriété.

Essayez de faire une recherche de solutions pour : ContentField pour voir les classes pour chacun des champs disponibles.

J'espère avoir expliqué les choses clairement, mais j'ai déjà écrit sur l'utilisation des champs. dans un article de blog et dans le cadre de mon cours de démarrage avec les modules sur la documentation officielle (en bas de la partie 3 si vous êtes curieux).

Utilisation des fonctions intégrées au lieu de IsDone

Cela semble être une approche étrange de le faire de cette façon. Si vous avez un élément de contenu comme une page, vous pouvez simplement utiliser le paramètre "Afficher dans un menu" sur la page.

Allez dans admin > content > ouvrez la page > vers le bas, vous trouverez "Show on a menu" :

Show on a menu option

Cela le placera automatiquement dans votre navigation et vous pourrez ensuite le déplacer là où vous le souhaitez :

Navigation

Une fois qu'il est "terminé", vous pouvez revenir en arrière et décocher l'option "Afficher dans un menu".

Configuration de l'alternative .cshtml

Pour clarifier vos commentaires sur la façon d'utiliser l'alternative, vous devez

  1. Copiez le fichier que vous avez à Orchard.Core/Shapes/Views/MenuItem.cshtml dans le dossier de vue de votre thème pour que son /Views/MenuItem.cshtml
  2. Renommez la copie dans votre thème en MenuItem-ContentMenuItem.cshtml
  3. Supprimez pratiquement tout ce qui s'y trouve et collez mon exemple au début de cet article. Vous ne voulez pas la plupart de l'original MenuItem.cshtml car il fait des tours spéciaux pour se transformer en une forme différente, ce qui n'est pas ce que vous voulez.
  4. Réinitialisez votre Orchard.Core/Shapes/Views/MenuItem.cshtml pour revenir aux paramètres d'usine par défaut. Dépôt officiel d'Orchard

Comprendre les noms des vues

Dans vos commentaires, vous avez demandé à créer des vues plus spécifiques (connues sous le nom d'alternatives). Vous pouvez utiliser un outil appelé Shape Tracer pour les visualiser. Leur nom suit un certain modèle qui les rend de plus en plus spécifiques.

Vous pouvez vous renseigner sur les solutions de rechange sur le site officiel de la documentation :

Pour savoir quelle forme est utilisée et quelles sont les alternatives disponibles, vous pouvez utiliser le module de traçage des formes qui est documenté ici :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X