2015-09-05 1 views
1

Je construis une application pyramidale en utilisant des templates mako.Comment enregistrer une fonction mako globale dans une pyramide depuis l'extérieur du modèle?

Comment est-ce que je peux rendre une fonction accessible dans tous mes modèles de mako sans devoir <%namespace /> un fichier dans chaque modèle?

Ce n'est pas que l'ajout de l'étiquette d'espace de nom soit mauvais en soi, mais dans ce cas, j'essaie d'ajouter une fonction de filtre (pour le traitement des démarques). Cela n'appartient pas à un fichier de modèle, mais plutôt à une bibliothèque et appartient à un fichier .py.

Je veux écrire dans mon modèle mako:

<div class="main-content"> 
    {page_content | markdown } 
</div> 

Affirmer que page_content contient le code Markdown et doivent être traités en tant que tels.

+0

Vous pouvez également enregistrer des fonctions globales (helpers) qui peuvent être utilisées dans vos modèles comme indiqué ici: http://docs.pylonsproject.org/pro jects/pyramid-cookbook/fr/latest/templates/templates.html – webjunkie

+0

@webjunkie J'aime beaucoup mieux votre solution que la mienne. Si vous écrivez une réponse avec '@subscriber (BeforeRender)', je l'accepterai. C'est ce que j'utilise maintenant. – kratenko

Répondre

2

Comme demandé par @kratenko vous pouvez utiliser un abonné BeforeRender comme détaillé here

Vous pouvez ajouter l'abonné suivant dans votre vue

@subscriber(BeforeRender) 
def add_base_template(event): 
    request = event.get('request') 
    if request.user: 
    base = 'myapp:templates/logged_in_layout.mako' 
    event.update({'base': base}) 
    else: 
    base = 'myapp:templates/layout.mako' 
    event.update({'base': base}) 

Et dans votre modèle mako appeler comme ceci:

<%inherit file="${context['base']}" /> 
+0

J'utilise @subsriber (BeforeRender) 'maintenant, mais différemment: le mien n'a qu'une seule ligne:' event ['markdown'] = markdown'. Maintenant, je peux utiliser quelque chose de la ligne '

${page.text|n,markdown}
' pour déclencher le rendu markdown dans le modèle (comme je l'ai fait dans [ma propre réponse] (http://stackoverflow.com/a/32413231/1358283)). Votre solution pour rendre la fonction disponible est meilleure, puisque ce truc n'a pas sa place dans le fichier config.ini. – kratenko

2

Vous pouvez spécifier des lignes de code python, qui doivent être incluses dans la partie supérieure des modules, qui seront créées à partir de vos modèles mako. Ceci est destiné à faire juste cela. Comme les templates mako sont réellement traduits en modules python, tout nom importé par ces lignes sera disponible en tant que nom dans votre template. Les filtres sont simplement des fonctions qui acceptent une chaîne et retournent une nouvelle chaîne (ou unicode).

Vous pouvez ajouter un module spécial dans votre projet pyramide pour contenir de telles fonctions, par ex. comme mako_imports.py

# mako_imports.py 
from markdown import markdown 

def remove_all_a(text): 
    # just a useless example for when you want to do 
    # something different with a custom function 
    return text.replace('a', '') 

Maintenant, pour inclure cette fonction, vous ajoutez à vos fichiers de configuration (development.ini, production.ini, ...) ce qui suit à votre section mako.:

mako.imports = from <project_name>.mako_imports import markdown, remove_all_a 

Vous devez spécifier le importe explicitement, car from ... import * n'est pas supporté ici.

Maintenant, vous devriez être en mesure de le faire dans vos modèles mako:

<div class="main-content"> 
    ${page_content | n,markdown } 
</div> 
<div class="disfunct-main-content"> 
    ${page_content | remove_all_a } 
</div> 

et vous devriez obtenir rendu démarquage (sans filtrage pour HTML malveillant bien sûr – assurez-vous de prendre soin de cela, si nécessaire!). Le filtre supplémentaire n est nécessaire car, par défaut, mako échapperait au code HTML créé.

Je pense qu'il doit y avoir un moyen de déplacer la pièce dans les fichiers .ini vers votre code de programme (par exemple dans la fonction main() de votre application), mais je ne l'ai pas encore compris.

Modifier: il existe un moyen, voir la réponse acceptée.