Implemented template tags 'f' to 'i' (except 'if').

Wed, 05 Feb 2014 19:13:12 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 05 Feb 2014 19:13:12 +0100
changeset 4
ba04ed0b14a1
parent 3
6d10c1249cb8
child 5
e2b08694e945

Implemented template tags 'f' to 'i' (except 'if').

PluginDjangoTagsMenu.e4p file | annotate | diff | comparison | revisions
ProjectDjangoTagsMenu/DjangoTagInputDialog.py file | annotate | diff | comparison | revisions
ProjectDjangoTagsMenu/DjangoTagsMenuHandler.py file | annotate | diff | comparison | revisions
ProjectDjangoTagsMenu/FindTemplateTagDialog.py file | annotate | diff | comparison | revisions
--- a/PluginDjangoTagsMenu.e4p	Mon Feb 03 19:54:07 2014 +0100
+++ b/PluginDjangoTagsMenu.e4p	Wed Feb 05 19:13:12 2014 +0100
@@ -18,6 +18,7 @@
     <Source>ProjectDjangoTagsMenu/__init__.py</Source>
     <Source>ProjectDjangoTagsMenu/DjangoTagsMenuHandler.py</Source>
     <Source>ProjectDjangoTagsMenu/FindTemplateTagDialog.py</Source>
+    <Source>ProjectDjangoTagsMenu/DjangoTagInputDialog.py</Source>
   </Sources>
   <Forms>
     <Form>ProjectDjangoTagsMenu/FindTemplateTagDialog.ui</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ProjectDjangoTagsMenu/DjangoTagInputDialog.py	Wed Feb 05 19:13:12 2014 +0100
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to enter data for the creation of a tag.
+"""
+
+from PyQt4.QtCore import Qt
+from PyQt4.QtGui import QDialog, QDialogButtonBox, QVBoxLayout, QLabel
+
+from E5Gui.E5LineEdit import E5ClearableLineEdit
+
+
+class DjangoTagInputDialog(QDialog):
+    """
+    Class implementing a dialog to enter data for the creation of a tag.
+    """
+    def __init__(self, labels, defaults=None, parent=None):
+        super(DjangoTagInputDialog, self).__init__(parent)
+        
+        assert 0 < len(labels) < 6      # max 5 entries allowed
+        self.__inputs = []
+        
+        self.__topLayout = QVBoxLayout(self)
+        index = 0
+        for label in labels:
+            self.__topLayout.addWidget(QLabel(label, self))
+            entry = E5ClearableLineEdit(self)
+            if defaults and index < len(defaults):
+                entry.setText(defaults[index])
+            self.__inputs.append(entry)
+            self.__topLayout.addWidget(entry)
+            index += 1
+        self.__buttonBox = QDialogButtonBox(
+            QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
+            Qt.Horizontal, self)
+        self.__topLayout.addWidget(self.__buttonBox)
+        
+        self.resize(400, self.minimumSizeHint().height())
+        self.setSizeGripEnabled(True)
+        
+        self.__buttonBox.accepted.connect(self.accept)
+        self.__buttonBox.rejected.connect(self.reject)
+        
+        self.__inputs[0].selectAll()
+        self.__inputs[0].setFocus()
+    
+    def getData(self):
+        """
+        Public method to retrieve the entered data.
+        
+        @return tuple containing the text of all entries (tuple of string)
+        """
+        data = [input.text().strip() for input in self.__inputs]
+        return tuple(data)
+    
+    @staticmethod
+    def getText(parent, title, labels, defaults=[]):
+        """
+        Static method to create the dialog and return the entered data.
+        
+        @return tuple of a tuple containing the text of all entries
+            (tuple of string) and a flag indicating the acceptance
+            state (boolean)
+        """
+        dlg = DjangoTagInputDialog(labels, defaults, parent)
+        dlg.setWindowTitle(title)
+        if dlg.exec_() == QDialog.Accepted:
+            return dlg.getData(), True
+        else:
+            return tuple(), False
--- a/ProjectDjangoTagsMenu/DjangoTagsMenuHandler.py	Mon Feb 03 19:54:07 2014 +0100
+++ b/ProjectDjangoTagsMenu/DjangoTagsMenuHandler.py	Wed Feb 05 19:13:12 2014 +0100
@@ -8,10 +8,12 @@
 """
 
 from PyQt4.QtCore import QObject
-from PyQt4.QtGui import QMenu, QInputDialog, QLineEdit
+from PyQt4.QtGui import QMenu
 
 from E5Gui.E5Application import e5App
 
+from .DjangoTagInputDialog import DjangoTagInputDialog
+
 
 class DjangoTagsMenuHandler(QObject):
     """
@@ -54,22 +56,27 @@
         @return generated menu (QMenu)
         """
         menu = QMenu(self.tr("Tags"))
-        menu.addAction(self.tr("autoescape - Auto Escape Characters"),
-                       lambda: self.__applyTemplate("autoescape"))
+        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.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("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.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.addAction(
+            self.tr("debug - Output Debug Information"),
+            lambda: self.__applyTemplate("debug"))
         menu.addSeparator()
         menu.addAction(
             self.tr("extends - Extend a template with variable contents"),
@@ -77,6 +84,27 @@
         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"))
         
         self.__tagsMenu = menu
         return menu
@@ -106,12 +134,13 @@
         templateText, replace = self.__generateTemplateText(
             tag, editor.selectedText())
         
-        editor.beginUndoAction()
-        if replace:
-            editor.replaceSelectedText(templateText)
-        else:
-            editor.insert(templateText)
-        editor.endUndoAction()
+        if templateText:
+            editor.beginUndoAction()
+            if replace:
+                editor.replaceSelectedText(templateText)
+            else:
+                editor.insert(templateText)
+            editor.endUndoAction()
     
     def __generateTemplateText(self, tag, selectedText):
         """
@@ -119,67 +148,130 @@
         
         @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) and a flag indicating
+        @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 %} " +
-                            selectedText +
-                            " {% endautoescape %}")
+            templateText = (
+                "{% autoescape on %} " + selectedText + " {% endautoescape %}")
             replace = True
         elif tag == "block":
-            blockName, ok = QInputDialog.getText(
+            data, ok = DjangoTagInputDialog.getText(
                 None,
                 self.tr("Named Block"),
-                self.tr("Enter block name:"),
-                QLineEdit.Normal,
-                "block_name")
-            templateText = ("{% block " +
-                            blockName.strip() +
-                            " %} " +
-                            selectedText +
-                            " {% endblock %}")
-            replace = True
+                [self.tr("Enter block name:")],
+                ["block_name"])
+            if ok:
+                templateText = (
+                    "{% block " + data[0] + " %} " + selectedText +
+                    " {% endblock %}")
+                replace = True
         elif tag == "comment":
-            templateText = ("{% comment %} " +
-                            selectedText +
-                            " {% endcomment %}")
+            templateText = (
+                "{% comment %} " + selectedText + " {% endcomment %}")
             replace = True
         elif tag == "csrf_token":
-            templateText = "{% csrf_token %}"
+            templateText = ("{% csrf_token %}")
         elif tag == "cycle":
-            cycleItems, ok = QInputDialog.getText(
+            data, ok = DjangoTagInputDialog.getText(
                 None,
                 self.tr("Cycle Variables"),
-                self.tr("Enter items to cycle separated by space"),
-                QLineEdit.Normal,
-                "item1 item2 item3")
-            templateText = ("{% cycle " + cycleItems.strip() + " %} ")
+                [self.tr("Enter items to cycle, space separated")],
+                ["item1 item2 item3"])
+            if ok:
+                templateText = ("{% cycle " + data[0] + " %} ")
         elif tag == "debug":
-            templateText = "{% debug %}"
+            templateText = ("{% debug %}")
         elif tag == "extendsvariable":
-            extends, ok = QInputDialog.getText(
+            data, ok = DjangoTagInputDialog.getText(
+                None,
+                self.tr("Extends"),
+                [self.tr("Enter variable name:")],
+                ["variable"])
+            if ok:
+                templateText = ('{% extends ' + 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 "' + 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 " + data[0] + " %} " + selectedText +
+                    " {% endfilter %}")
+                replace = True
+        elif tag == "firstof":
+            data, ok = DjangoTagInputDialog.getText(
                 None,
-                self.tr("Extends Variable"),
-                self.tr("Enter variable name:"),
-                QLineEdit.Normal,
-                "variable")
-            templateText = '{% extends ' + extends.strip() + ' %} '
-        elif tag == "extendsfile":
-            extends, ok = QInputDialog.getText(
+                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 " + data[0] +
+                    ' "' + data[1] + '" %} ' + selectedText +
+                    " {% endfilter %}")
+                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 " + data[0] + " in " + data[1] +
+                    " %} " + selectedText + " {% endfor %}")
+                replace = True
+        elif tag == "for...empty":
+            data, ok = DjangoTagInputDialog.getText(
                 None,
-                self.tr("Extends Parent"),
-                self.tr("Enter parent file name:"),
-                QLineEdit.Normal,
-                "base.html")
-            templateText = '{% extends "' + extends.strip() + '" %} '
+                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 " + data[0] + " in " + data[1] + " %} " +
+                    selectedText + " {% empty %} " + data[2] + " {% endfor %}")
+                replace = True
+        elif tag == "includevariable":
+            data, ok = DjangoTagInputDialog.getText(
+                None,
+                self.tr("Include"),
+                [self.tr("Enter variable name:")],
+                ["variable"])
+            if ok:
+                templateText = ('{% include ' + data[0] + ' %} ')
+        elif tag == "includefile":
+            data, ok = DjangoTagInputDialog.getText(
+                None,
+                self.tr("Include"),
+                [self.tr("Enter file name:")],
+                ["other.html"])
+            if ok:
+                templateText = ('{% include "' + data[0] + '" %} ')
         
         ####################################################
         ## Fallback: return just the tag name             ##
@@ -187,4 +279,5 @@
         
         else:
             templateText = tag
+        
         return templateText, replace
--- a/ProjectDjangoTagsMenu/FindTemplateTagDialog.py	Mon Feb 03 19:54:07 2014 +0100
+++ b/ProjectDjangoTagsMenu/FindTemplateTagDialog.py	Wed Feb 05 19:13:12 2014 +0100
@@ -28,6 +28,7 @@
         super(FindTemplateTagDialog, self).__init__(parent)
         self.setupUi(self)
         
+        # TODO: check tags against handler
         self.__completer = QCompleter((
             'autoescape', 'block', 'comment', 'csrf_token', 'cycle', 'debug',
             'extends', 'filter', 'firstof', 'for', 'for...empty', 'if',

eric ide

mercurial