Thu, 06 Feb 2014 19:29:47 +0100
Completed template tags(except 'if').
# -*- coding: utf-8 -*- # Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing the Django tags menu handler. """ import os from PyQt4.QtCore import QObject from PyQt4.QtGui import QMenu, QInputDialog from E5Gui.E5Application import e5App from E5Gui import E5FileDialog from .DjangoTagInputDialog import DjangoTagInputDialog class DjangoTagsMenuHandler(QObject): """ Class implementing the Django tags menu handler. """ def __init__(self, ui, parent=None): """ Constructor @param ui reference to the user interface object (UI.UserInterface) @param parent reference to the parent object (QObject) """ super(DjangoTagsMenuHandler, self).__init__(parent) self.__ui = ui self.__findDialog = None def closeAllWindows(self): """ Public method to close all dialogs managed by the handler. """ if self.__findDialog: self.__findDialog.close() def initMenus(self, mainMenu): """ Public method to initialize the various menus. @param mainMenu reference to the main tags menu (QMenu) """ mainMenu.addAction(self.tr("Django Template Tags Locator"), self.__findTemplateTag) mainMenu.addSeparator() mainMenu.addMenu(self.__initTagsMenu()) def __initTagsMenu(self): """ Private method to initialize the tags menu. @return generated menu (QMenu) """ menu = QMenu(self.tr("Tags")) menu.addAction( self.tr("autoescape - Auto Escape Characters"), lambda: self.__applyTemplate("autoescape")) menu.addSeparator() menu.addAction( self.tr("block - Named Block"), lambda: self.__applyTemplate("block")) menu.addSeparator() menu.addAction( self.tr("comment - Multiline Comment"), lambda: self.__applyTemplate("comment")) menu.addAction( self.tr("csrf_token - Cross Site Request Forgery Token"), lambda: self.__applyTemplate("csrf_token")) menu.addAction( self.tr("cycle - Cycle variables each time used"), lambda: self.__applyTemplate("cycle")) menu.addSeparator() menu.addAction( self.tr("debug - Output Debug Information"), lambda: self.__applyTemplate("debug")) menu.addSeparator() menu.addAction( self.tr("extends - Extend a template with variable contents"), lambda: self.__applyTemplate("extendsvariable")) menu.addAction( self.tr("extends - Extend a template with file"), lambda: self.__applyTemplate("extendsfile")) menu.addSeparator() menu.addAction( self.tr("filter - Filtered Block for one or more filters"), lambda: self.__applyTemplate("filter")) menu.addAction( self.tr("firstof - Outputs first argument variable that is True"), lambda: self.__applyTemplate("firstof")) menu.addAction( self.tr("for - For Loop"), lambda: self.__applyTemplate("for")) menu.addAction( self.tr("for...empty - For Loop with fallback for empty loop"), lambda: self.__applyTemplate("for...empty")) menu.addSeparator() # TODO: add 'if...' templates here menu.addAction( self.tr("include - Render template given by variable"), lambda: self.__applyTemplate("includevariable")) menu.addAction( self.tr("include - Render template given by file name"), lambda: self.__applyTemplate("includefile")) menu.addSeparator() menu.addAction( self.tr("load - Load a custom template tag set"), lambda: self.__applyTemplate("load")) menu.addSeparator() menu.addAction( self.tr("now - Display current date and time"), lambda: self.__applyTemplate("now")) menu.addSeparator() menu.addAction( self.tr("regroup - Regroup list of alike objects by a common" " attribute"), lambda: self.__applyTemplate("regroup")) menu.addSeparator() menu.addAction( self.tr("spaceless - Remove whitespace between HTML tags"), lambda: self.__applyTemplate("spaceless")) menu.addAction( self.tr("ssi - Output contents of a given file into the page"), lambda: self.__applyTemplate("ssi")) menu.addAction( self.tr("ssi - Output contents of a given file into the page" " (dialog selection)"), lambda: self.__applyTemplate("ssifile")) menu.addSeparator() menu.addAction( self.tr("templatetag - Output syntax characters used for" " template"), lambda: self.__applyTemplate("templatetag")) menu.addSeparator() menu.addAction( self.tr("url - Return an absolute path reference"), lambda: self.__applyTemplate("url")) menu.addAction( self.tr("url...as - Return an absolute path reference"), lambda: self.__applyTemplate("urlas")) menu.addSeparator() menu.addAction( self.tr("verbatim - Output block contents without rendering"), lambda: self.__applyTemplate("verbatim")) menu.addSeparator() menu.addAction( self.tr("widthratio - Calculate width ratio"), lambda: self.__applyTemplate("verbatim")) menu.addAction( self.tr("with - Cache a complex variable under a simpler name"), lambda: self.__applyTemplate("verbatim")) self.__tagsMenu = menu return menu def __findTemplateTag(self): """ Private slot to find a template tag and insert its text. """ if self.__findDialog is None: from .FindTemplateTagDialog import FindTemplateTagDialog self.__findDialog = FindTemplateTagDialog() self.__findDialog.tag.connect(self.__applyTemplate) self.__findDialog.show() self.__findDialog.raise_() self.__findDialog.activateWindow() def __applyTemplate(self, tag): """ Private slot to generate and insert the template text. @param tag name of the tag to insert (string) """ editor = e5App().getObject("ViewManager").activeWindow() if editor is None: return templateText, replace = self.__generateTemplateText( tag, editor.selectedText()) if templateText: editor.beginUndoAction() if replace: editor.replaceSelectedText(templateText) else: editor.insert(templateText) editor.endUndoAction() def __generateTemplateText(self, tag, selectedText): """ Private slot to generate the template text. @param tag name of the tag to insert (string) @param selectedText selected text of the current editor (string) @return tuple of generated template text (string), a flag indicating to perform a replace operation (boolean) """ # TODO: complete the tag generation logic replace = False # safe value ok = True templateText = "" #################################################### ## Template Tags ## #################################################### if tag == "autoescape": templateText = ( "{{% autoescape on %}} {0} {{% endautoescape %}}".format( selectedText)) replace = True elif tag == "block": data, ok = DjangoTagInputDialog.getText( None, self.tr("Named Block"), [self.tr("Enter block name:")], ["block_name"]) if ok: templateText = "{{% block {0} %}} {1} {{% endblock %}}".format( data[0], selectedText) replace = True elif tag == "comment": templateText = "{{% comment %}} {0} {{% endcomment %}}".format( selectedText) replace = True elif tag == "csrf_token": templateText = "{% csrf_token %}" elif tag == "cycle": data, ok = DjangoTagInputDialog.getText( None, self.tr("Cycle Variables"), [self.tr("Enter items to cycle, space separated")], ["item1 item2 item3"]) if ok: templateText = "{{% cycle {0} %}}".format(data[0]) elif tag == "debug": templateText = "{% debug %}" elif tag == "extendsvariable": data, ok = DjangoTagInputDialog.getText( None, self.tr("Extends"), [self.tr("Enter variable name:")], ["variable"]) if ok: templateText = "{{% extends {0} %}}".format(data[0]) elif tag == "extendsfile": data, ok = DjangoTagInputDialog.getText( None, self.tr("Extends"), [self.tr("Enter parent file name:")], ["base.html"]) if ok: templateText = '{{% extends "{0}" %}}'.format(data[0]) elif tag == "filter": data, ok = DjangoTagInputDialog.getText( None, self.tr("Tag Filters"), [self.tr("Multiple filters with arguments, pipes separated:")], ["lower|safe"]) if ok: templateText = ( "{{% filter {0} %}} {1} {{% endfilter %}}".format( data[0], selectedText)) replace = True elif tag == "firstof": data, ok = DjangoTagInputDialog.getText( None, self.tr("First Of"), [self.tr("Enter multiple variables, space separated:"), self.tr("Enter fallback value:")], ["var1 var2", "fallback_value"]) if ok: templateText = ( '{{% filter force_escape %}}{{% firstof {0} "{1}" %}}' ' {2} {{% endfilter %}}'.format( data[0], data[1], selectedText)) replace = True elif tag == "for": data, ok = DjangoTagInputDialog.getText( None, self.tr("For Loop"), [self.tr("Enter variable to use for iteration:"), self.tr("Enter sequence to iterate over:")], ["item", "values"]) if ok: templateText = ( "{{% for {0} in {1} %}} {2} {{% endfor %}}".format( data[0], data[1], selectedText)) replace = True elif tag == "for...empty": data, ok = DjangoTagInputDialog.getText( None, self.tr("For Loop"), [self.tr("Enter variable to use for iteration:"), self.tr("Enter sequence to iterate over:"), self.tr("Enter output to use if loop is empty:")], ["item", "values", '"Nothing."']) if ok: templateText = ( "{{% for {0} in {1} %}} {2} {{% empty %}} {3}" " {{% endfor %}}".format( data[0], data[1], selectedText, data[2])) replace = True elif tag == "includevariable": data, ok = DjangoTagInputDialog.getText( None, self.tr("Include"), [self.tr("Enter variable name:")], ["variable"]) if ok: templateText = '{{% include {0} %}}'.format(data[0]) elif tag == "includefile": data, ok = DjangoTagInputDialog.getText( None, self.tr("Include"), [self.tr("Enter file name:")], ["other.html"]) if ok: templateText = '{{% include "{0}" %}}'.format(data[0]) elif tag == "load": data, ok = DjangoTagInputDialog.getText( None, self.tr("Load"), [self.tr("Enter template tag set to load:")], ["foo bar"]) if ok: templateText = '{{% load "{0}" %}}'.format(data[0]) elif tag == "now": dateformat, ok = QInputDialog.getItem( None, self.tr("Now"), self.tr("Current date time format:"), ["DATETIME_FORMAT", "SHORT_DATETIME_FORMAT", "SHORT_DATE_FORMAT", "DATE_FORMAT"], 0, False) if ok: templateText = '{{% now "{0}" %}}'.format(dateformat) elif tag == "regroup": data, ok = DjangoTagInputDialog.getText( None, self.tr("Regroup List"), [self.tr("List Variable:"), self.tr("Common Attribute:"), self.tr("Name of resulting list:")], ["cities", "country", "country_list"]) if ok: templateText = '{{% regroup {0} by {1} as {2} %}}'.format( data[0], data[1], data[2]) elif tag == "spaceless": templateText = "{{% spaceless %}} {0} {{% endspaceless %}}".format( selectedText) replace = True elif tag == "ssi": data, ok = DjangoTagInputDialog.getText( None, self.tr("SSI"), [self.tr("Full path to template:")], ["/tmp/ssi_template.html"]) if ok: templateText = '{{% ssi "{0}" parsed %}}'.format(data[0]) elif tag == "ssifile": ssi = E5FileDialog.getOpenFileName( None, self.tr("SSI"), os.path.expanduser("~"), self.tr("All Files (*)")) if ssi: templateText = '{{% ssi "{0}" parsed %}}'.format(ssi) elif tag == "templatetag": templatetag, ok = QInputDialog.getItem( None, self.tr("Template Tag"), self.tr("Argument:"), ["block", "variable", "brace", "comment"], 0, False) if ok: templateText = ( '{{% templatetag open{0} %}} {1} {{% templatetag' ' close{0} %}}'.format(templatetag, selectedText)) replace = True elif tag == "url": data, ok = DjangoTagInputDialog.getText( None, self.tr("URL"), [self.tr("View method name:"), self.tr("Optional arguments (space separated):")], ["path.to.some_view", "var1 var2"]) if ok: if data[1]: data[1] = ' ' + data[1] templateText = '{{% url "{0}"{1} %}}'.format( data[0], data[1]) elif tag == "urlas": data, ok = DjangoTagInputDialog.getText( None, self.tr("URL...as"), [self.tr("View method name:"), self.tr("Optional arguments (space separated):"), self.tr("URL name:")], ["path.to.some_view", "var1 var2", "url_name"]) if ok: if data[1]: data[1] = ' ' + data[1] templateText = '{{% url "{0}"{1} as {2} %}}'.format( data[0], data[1], data[2]) elif tag == "verbatim": templateText = "{{% verbatim %}} {0} {{% endverbatim %}}".format( selectedText) replace = True elif tag == "widthratio": data, ok = DjangoTagInputDialog.getText( None, self.tr("Width Ratio"), [self.tr("Variable:"), self.tr("Maximum Value:"), self.tr("Maximum Width:")], ["variable", "max_value", "max_width"]) if ok: templateText = "{{% widthratio {0} {1} {2} %}}".format( data[0], data[1], data[2]) elif tag == "with": data, ok = DjangoTagInputDialog.getText( None, self.tr("Cache Variables"), [self.tr("Variables to cache as key=value (space separated):") ], ["variable1=foo.bar variable2=bar.baz"]) if ok: templateText = '{{% with {0} %}} {1} {{% endwith %}}'.format( data[0], selectedText) #################################################### ## Fallback: return just the tag name ## #################################################### else: templateText = tag return templateText, replace