Introduction à la construction d'applications web avec Framework Nevow pour Python


Télécharger Introduction à la construction d'applications web avec Framework Nevow pour Python

★★★★★★★★★★3.5 étoiles sur 5 basé sur 1 votes.
Votez ce document:

Télécharger aussi :


Introduction à la construction d'applications web avec Framework Nevow pour Python

Pourquoi Nevow?

Nevow a été créé pour aider l'auteur à créer plusieurs applications Web très volumineuses et complexes. Il s'appuie sur de nombreuses idées auxquelles l'auteur a été exposé lors de l'utilisation de divers autres cadres Web et tente d'emprunter des concepts utiles à chacun d'eux tout en restant aussi légers et aussi discrets que possible.

La sémantique des modèles de Nevow utilise des idées de divers autres langages de modèles, notamment Quichote, ZPT et XMLC (du projet Enhydra). Il permet l’utilisation de modèles XHTML valides, étiquetés avec des attributs spéciaux appelés 'directives', similaires à ZPT. Il permet aux programmeurs de restituer les vues HTML en Python pur au lieu de les forcer à apprendre un nouveau langage incorporé au format HTML, similaire à Quixote. Enfin, il utilise un DOM, ou Document Object Model, pour représenter le document en mémoire pendant le processus de rendu, de manière similaire à XMLC.

Nevow contient également un cadre de publication d’objets similaire aux idées présentes dans twisted.web et Zope. Chaque URL est mappée sur une instance de la classe Page à l'aide d'une interface de traversée simple. Un serveur d'applications et un serveur HTTP construits à l'aide de twisted.web sont inclus, ce qui vous permet de démarrer très rapidement.

Nevow est conçu pour être intégré dans un environnement utilisant des E / S asynchrones, telles que twisted.web. Il construit une pile d'objets 'context' qu'il utilise pour suivre l'état du processus de rendu et l'utilise pour fournir un support pour "suspendre" le rendu et le reprendre à la fin d'une opération d'E / S.

Nevow Tutorial

La suite de ce document vous guidera dans la création d’une application Web utilisant Nevow. L'application que nous avons choisie de créer est une application simple de calendrier et de planification, capable de générer un calendrier pour tous les mois et toutes les années et de l'intégrer à un module tiers d'analyse iCalendar pour alimenter le calendrier en événements. Pour voir le résultat final, accédez au répertoire Example4 et exécutez la commande suivante:

twistd -noy sched.tac

Ensuite, accédez à l'URL suivante à l'aide du navigateur Web de votre choix:

http: // localhost: 8080 /

Vous devriez alors voir un calendrier pour le mois en cours. Vous devriez pouvoir choisir n'importe quel mois à afficher, cliquer sur un lien d'événements pour voir les événements de ce jour et ajouter un événement à n'importe quel jour. Maintenant, nous allons suivre le processus de construction de cette application, en introduisant des éléments de continuité dans le processus.

Modèles basés sur HTML

Nevow inclut la possibilité de charger des modèles HTML sur un disque. Ces modèles peuvent avoir des directives de traitement qui entraînent l'exécution de méthodes python lors du rendu. La technique des attributs a été inspirée par les attributs utilisés par ZPT. Cependant, aucun code réel ne peut être incorporé dans le modèle HTML.

Une directive est une commande de Nevow pour appeler du code Python. Nevow utilise des directives de données et des directives de rendu. La présence d'un attribut nevow: data ou nevow: render sur un nœud HTML d'un modèle entraîne la localisation et l'appel de la méthode data_ * ou render_ * associée.

Un modèle est un nœud que le code Python peut localiser par son nom. Lorsqu'un noeud a un attribut nevow: pattern, le code Python peut utiliser les méthodes de contexte onePattern (name), AllPatterns (name) et PatternGenerator (name) pour localiser et cloner ce nœud.

Un emplacement est un faux noeud que le code Python peut remplacer par un contenu réel. Lorsqu'un nœud a un attribut nevow: slot, le code Python peut utiliser la méthode de contexte 'fillSlot (nom, valeur)' pour qu'un emplacement se remplace lui-même avec la valeur donnée lors du rendu de l'emplacement.

Le premier modèle HTML que nous utiliserons dans notre exemple de planification est un document HTML complet qui, lorsqu'il est affiché dans un navigateur, affiche une approximation de l'apparence de l'application finale, avec des données factices en place. Ouvrez le fichier Example1 / Month.html dans un navigateur et observez comment il donne un aperçu raisonnable de l'application finale. Un concepteur peut ouvrir ce modèle dans un éditeur HTML graphique et le styler. Les directives que nous avons placées dans le document doivent être préservées.

Regardons de plus près les directives, les patterns et les slots présents dans le template:

<span nevow: data = "currentMonth" jamais: render = "month">

    <h1> <nevow: slot name = "label"> L'étiquette va ici </ nevow: slot> </ h1>

    <table height = "50%" width = "50%" border = "1">

        <tr>

            <td> dimanche </ td>

            ...

            <td> samedi </ td>

        </ tr>

        <tr nevow: pattern = "calendarWeek" nevow: render = "remove">

            <td nevow: pattern = "calendarDay" align = "center"> </ td>

            ...

        </ tr>

        <nevow: slot name = "calendarBody" />

    ...

Dans ce cas, nous avons un noeud factice <span> autour de la partie intéressante du modèle. Ce noeud d'intervalle n'affectera pas la présentation du document et constitue simplement un transporteur pour certaines directives qui affectera certains nœuds à l'intérieur de l'étendue. Sur ce nœud, nous voyons deux directives: nevow: data = "currentMonth" et nevow: render = "month". Lorsque nevow commence à rendre ce nœud span, il appelle d'abord une méthode appelée data_currentMonth, puis transmet les données obtenues à une méthode nommée render_month. La valeur de retour de la méthode render_month remplacera la plage entière dans le DOM de rendu et un traitement ultérieur aura lieu sur celle-ci.



À l'intérieur du noeud span, il y a deux emplacements: <nevow: nom de l'emplacement = "label"> et <nevow: nom de l'emplacement = "calendarBody" />. render_currentMonth s'assurera de fournir des valeurs pour combler ces espaces avant de retourner.

Enfin, à l'intérieur du noeud span, il y a deux modèles: nevow: pattern = "calendarWeek" et nevow: pattern = "calendarDay". La méthode render_currentMonth créera des clones de ces nœuds de modèle lors du rendu du calendrier.

Une dernière remarque: le nœud de modèle <tr nevow: pattern = "calendarWeek"> a une directive nevow: render = "remove". Actuellement, Nevow ne supprime pas automatiquement les nœuds de modèle du modèle. Par conséquent, pour éviter que les données factices ne se retrouvent dans la sortie, nous utilisons la méthode render_remove. render_remove est défini sur la classe Page et renvoie simplement ''.

méthodes de données / rendu

Lorsque nevow localise une directive de données dans un modèle, il appelle la méthode data_ * associée sur la classe Page. Dans notre exemple, la méthode data nommée data_currentMonth est appelée. La valeur renvoyée par la méthode data est mémorisée à l'aide de l'objet contextuel actuel et transmise en tant que paramètre 'data' lors du rendu de ce noeud.

De même, une directive de rendu dans un modèle invoquera une méthode de rendu nommée de manière appropriée. Dans l'exemple, la méthode 'render_month' sera invoquée. Les données seront localisées en regardant dans l'objet de contexte actuel.

Pour lier notre modèle HTML à nos implémentations de nos méthodes data_ * et render_ *, nous sous-classons la classe Page. L'implémentation du squelette ressemble à ceci:

classe ScheduleRoot (rend.Page):

    docFactory = rend.htmlfile ('Month.html')

    def data_currentMonth (self, contexte, data):

        ...

    def render_month (auto, contexte, données):

        ...

La signature d'une méthode data_ * ou render_ * est toujours (self, contexte, data). Self est l'instance de page elle-même, context est l'instance de contexte actuellement au-dessus de la pile de contexte et data est la dernière donnée placée dans la pile de contexte.

Dans ce cas, notre méthode data_currentMonth va produire des données à utiliser pendant le processus de rendu par notre méthode render_month. Par défaut, data_currentMonth renverra un tuple de l'année, du mois et une liste de listes de semaines et de jours de ce mois. Cependant, nous allons également paramétrer la méthode data afin que le mois et l'année à renvoyer puissent être spécifiés en tant qu'arguments dans l'URL:

def data_currentMonth (self, contexte, data):

    curtime = time.localtime ()

    # Nous obtenons soit l'année de la demande, soit s'il n'y a pas

    # argument de l'année dans la demande, utilisez l'année en cours

    année = int (context.arg ('année', heure actuelle [0]))

    # Nous obtenons le mois de la demande ou le mois en cours

    month = int (context.arg ('month', curtime [1]))

    

    # Retourne un 3 tuple de l'année, le mois et la liste des listes

    Nombre de semaines et de jours

    année de retour, mois, calendrier.monthcalendaire (année, mois)

Notre méthode render_month utilisera les données générées par notre méthode data, ainsi que les API disponibles à partir de l'objet context, pour modifier le contexte de rendu. Il crée des copies des nœuds de modèle qu'il nomme dans le modèle HTML, nomme ces données, et insère la construction DOM finale dans la page finale à l'aide de la méthode context.fillSlots:

def render_month (auto, contexte, données):

    # Déballer nos 3 tuple

    année, mois, semaines et jours = données

    weekPattern = context.patternGenerator ('calendarWeek')

    dayPattern = context.with (weekPattern ()). patternGenerator ('calendarDay')

    calendarBody = []

    pour semaine en semaines et jours:

        currentWeek = weekPattern (). clear ()

        calendarBody.append (currentWeek)

        pour jour en semaine:

            currentDay = dayPattern (). clear ()

            si jour! = 0:

                currentDay.children.append (str (jour))

            currentWeek.children.append (currentDay)

    context.fillSlots ('label', "% s% s"% (calendar.name_nom_mot [mois], année))

    context.fillSlots ('calendarBody', calendarBody)

    retourne context.tag

Notez que cette méthode, qui génère des vues assez compliquées, est facile à lire car elle est purement python et ne contient aucune information sur la disposition ou le format du modèle HTML, car elle utilise des modèles et des emplacements nommés pour le manipuler.



Nous avons maintenant terminé la première application Exemple1. Accédez au répertoire Example1 et démarrez l'application:

twistd -noy sched.tac

Visitez l'application sur l'URL:

http: // localhost: 8080 /

Vous verrez un rendu précis du calendrier du mois en cours. L'application contient également une vue qui donne plusieurs années de liens sur lesquels vous pouvez cliquer pour voir le mois correspondant.

Intégration à une source de données externe

Nevow a été conçu pour vous permettre de fournir facilement une interface Web pour un morceau de code tiers sans modifier le code d'origine. Nevow utilise beaucoup d'adaptateurs et d'interfaces pour fournir une architecture à base de composants dans laquelle les classes peuvent implémenter des aspects des fonctionnalités d'une autre classe.

Cependant, il n'est pas nécessaire de comprendre les composants pour pouvoir utiliser Nevow efficacement. Dans notre exemple, nous allons montrer un exemple plus explicite d'encapsuler une source de données externe et de l'exposer au Web.

Afin de prendre en charge notre exemple de planification, j'ai effectué une recherche sur le Web pour trouver un module Python capable d'analyser le format iCalendar standard du marché et de présenter quelques objets Python simples. J'ai repéré un module spécialement conçu pour analyser les fichiers de données utilisés par l'application iCal d'Apple. Avec quelques petites modifications, je l’ai généralisé pour qu’il soit plus multi-plateforme. Le module original peut être trouvé ici:

... ...

Le module modifié, ainsi qu'un exemple de fichier .ics, se trouvent dans le répertoire Example2. Pour commencer l'intégration avec cette source de données externe, nous substituons la méthode __init__ sur notre classe ScheduleRoot:

def __init __ (self, calendarEntries):

    self.calendarEntries = calendarEntries

    super (ScheduleRoot, self) .__ init __ ()

Ensuite, nous modifions le fichier de configuration, qui crée notre instance ScheduleRoot et démarre un serveur Web, en créant une instance ICalReader et en le transmettant à ScheduleRoot:

importer iCal, calendrier

de nevow import appserver

du service d'importation twisted.application, Internet

application = service.Application ('Schedule')

webservice = internet.TCPServer (

    8080,

    appserver.NevowSite (schedule.ScheduleRoot (iCal.ICalReader ()))

)

webservice.setServiceParent (application)

Ce fichier de configuration, sched.tac, est un fichier de configuration d'application tordu standard. Lorsqu'il est exécuté à l'aide de 'twistd -y', l'instance d'application affectée à la variable 'application' sera démarrée et écoutera tous les ports configurés.

Enfin, nous modifions notre méthode 'render_month' pour prendre en compte cette source de données supplémentaire lors du rendu de la page:

calendarBody = []

pour semaine en semaines et jours:

    currentWeek = weekPattern (). clear ()

    calendarBody.append (currentWeek)

    pour jour en semaine:

        si jour! = 0:

            events = self.calendarEntries.eventsFor (date (année, mois, jour))

        autre:

            événements = []

        currentDay = dayPattern (

            render = self.render_day, data = (année, mois, jour, événements))

        currentWeek.children.append (currentDay)

Dans cet exemple, nous appelons l'api 'eventsFor' sur notre instance ICalReader pour déterminer s'il existe des événements pour le jour que nous sommes sur le point de restituer:

events = self.calendarEntries.eventsFor (date (année, mois, jour))

Ensuite, nous déléguons le rendu du fragment journalier réel à la méthode render_day en lui transmettant un tuple de (année, mois, jour, événements) sous forme de données:

currentDay = dayPattern (

    render = self.render_day, data = (année, mois, jour, événements))

La définition du rendu et des données sur un nœud à l'aide de code Python est similaire à celle qui se produit lorsque Nevow rencontre une directive de rendu ou une directive de données dans un modèle HTML, sauf que nous pouvons passer des références Python plus directement. Lorsque le contrôle revient de la méthode render_month et que Nevow continue à restituer le DOM, il rencontrera ces nœuds avec des directives de traitement supplémentaires et les restituera en conséquence.



22