Sat, 08 Feb 2014 18:58:33 +0100
Finished the filter tags and implemented the 'humanize', 'web design' and 'static' tags and the various 'if' tags.
--- a/PluginDjangoTagsMenu.e4p Fri Feb 07 18:21:09 2014 +0100 +++ b/PluginDjangoTagsMenu.e4p Sat Feb 08 18:58:33 2014 +0100 @@ -19,9 +19,13 @@ <Source>ProjectDjangoTagsMenu/DjangoTagsMenuHandler.py</Source> <Source>ProjectDjangoTagsMenu/FindTemplateTagDialog.py</Source> <Source>ProjectDjangoTagsMenu/DjangoTagInputDialog.py</Source> + <Source>ProjectDjangoTagsMenu/LoremTagInputDialog.py</Source> + <Source>ProjectDjangoTagsMenu/IfTagInputDialog.py</Source> </Sources> <Forms> <Form>ProjectDjangoTagsMenu/FindTemplateTagDialog.ui</Form> + <Form>ProjectDjangoTagsMenu/LoremTagInputDialog.ui</Form> + <Form>ProjectDjangoTagsMenu/IfTagInputDialog.ui</Form> </Forms> <Translations/> <Resources/>
--- a/ProjectDjangoTagsMenu/DjangoTagsMenuHandler.py Fri Feb 07 18:21:09 2014 +0100 +++ b/ProjectDjangoTagsMenu/DjangoTagsMenuHandler.py Sat Feb 08 18:58:33 2014 +0100 @@ -10,7 +10,7 @@ import os from PyQt4.QtCore import QObject -from PyQt4.QtGui import QMenu, QInputDialog +from PyQt4.QtGui import QMenu, QInputDialog, QDialog from E5Gui.E5Application import e5App from E5Gui import E5FileDialog @@ -52,6 +52,9 @@ mainMenu.addSeparator() mainMenu.addMenu(self.__initTagsMenu()) mainMenu.addMenu(self.__initFiltersMenu()) + mainMenu.addMenu(self.__initHumanizeMenu()) + mainMenu.addMenu(self.__initWebDesignMenu()) + mainMenu.addMenu(self.__initStaticMenu()) def __initTagsMenu(self): """ @@ -102,7 +105,18 @@ 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("if - if...elif...else... clauses"), + lambda: self.__applyTemplate("if")) + menu.addAction( + self.tr("ifchanged - Check if a value has changed"), + lambda: self.__applyTemplate("ifchanged")) + menu.addAction( + self.tr("ifequal - Output block if variables are equal"), + lambda: self.__applyTemplate("ifequal")) + menu.addAction( + self.tr("ifnotequal - Output block if variables are not equal"), + lambda: self.__applyTemplate("ifnotequal")) menu.addAction( self.tr("include - Render template given by variable"), lambda: self.__applyTemplate("includevariable")) @@ -226,10 +240,221 @@ self.tr("force_escape - Escape as HTML immediately"), lambda: self.__applyTemplate("force_escape")) menu.addSeparator() + menu.addAction( + self.tr("get_digit - Extract rightmost digit"), + lambda: self.__applyTemplate("get_digit")) + menu.addSeparator() + menu.addAction( + self.tr("iriencode - Convert IRI to string"), + lambda: self.__applyTemplate("iriencode")) + menu.addSeparator() + menu.addAction( + self.tr("join - Join list"), + lambda: self.__applyTemplate("join")) + menu.addSeparator() + menu.addAction( + self.tr("last - Return last item in list"), + lambda: self.__applyTemplate("last")) + menu.addAction( + self.tr("length - Return length of the value"), + lambda: self.__applyTemplate("length")) + menu.addAction( + self.tr("length_is - Check length"), + lambda: self.__applyTemplate("length_is")) + menu.addAction( + self.tr("linebreaks - Replace line breaks with HTML"), + lambda: self.__applyTemplate("linebreaks")) + menu.addAction( + self.tr("linebreaksbr - Replace line breaks with <br/>"), + lambda: self.__applyTemplate("linebreaksbr")) + menu.addAction( + self.tr("linenumbers - Display text with line numbers"), + lambda: self.__applyTemplate("linenumbers")) + menu.addAction( + self.tr("ljust - Left-align value"), + lambda: self.__applyTemplate("ljust")) + menu.addAction( + self.tr("lower - Convert to lowercase"), + lambda: self.__applyTemplate("lower")) + menu.addSeparator() + menu.addAction( + self.tr("make_list - Turn value into a list"), + lambda: self.__applyTemplate("make_list")) + menu.addSeparator() + menu.addAction( + self.tr("phone2numeric - Convert phone number into numeric"), + lambda: self.__applyTemplate("phone2numeric")) + menu.addAction( + self.tr("pluralize - Return plural suffix"), + lambda: self.__applyTemplate("pluralize")) + menu.addAction( + self.tr("pprint - Pretty Print"), + lambda: self.__applyTemplate("pprint")) + menu.addSeparator() + menu.addAction( + self.tr("random - Return random item from list"), + lambda: self.__applyTemplate("random")) + menu.addAction( + self.tr("removetags - Remove HTML tags"), + lambda: self.__applyTemplate("removetags")) + menu.addAction( + self.tr("rjust - Right-align value"), + lambda: self.__applyTemplate("rjust")) + menu.addSeparator() + menu.addAction( + self.tr("safe - Mark as not requiring HTML escaping "), + lambda: self.__applyTemplate("safe")) + menu.addAction( + self.tr("safeseq - Mark as a safe sequence"), + lambda: self.__applyTemplate("safeseq")) + menu.addAction( + self.tr("slice - Return a slice of a list"), + lambda: self.__applyTemplate("slice")) + menu.addAction( + self.tr("slugify - Return value slugified"), + lambda: self.__applyTemplate("slugify")) + menu.addAction( + self.tr("stringformat - Format variable"), + lambda: self.__applyTemplate("stringformat")) + menu.addAction( + self.tr("striptags - Strip all HTML tags"), + lambda: self.__applyTemplate("striptags")) + menu.addSeparator() + menu.addAction( + self.tr("time - Format time"), + lambda: self.__applyTemplate("time")) + menu.addAction( + self.tr("timesince - Format as time since"), + lambda: self.__applyTemplate("timesince")) + menu.addAction( + self.tr("timeuntil - Format as time until"), + lambda: self.__applyTemplate("timeuntil")) + menu.addAction( + self.tr("title - Convert to titlecase"), + lambda: self.__applyTemplate("title")) + menu.addAction( + self.tr("truncatechars - Truncate after a number of characters"), + lambda: self.__applyTemplate("truncatechars")) + menu.addAction( + self.tr("truncatewords - Truncate after a number of words"), + lambda: self.__applyTemplate("truncatewords")) + menu.addAction( + self.tr("truncatewords_html - Truncate after a number of words" + " (HTML aware)"), + lambda: self.__applyTemplate("truncatewords_html")) + menu.addSeparator() + menu.addAction( + self.tr("unordered_list - Return HTML unordered list"), + lambda: self.__applyTemplate("unordered_list")) + menu.addAction( + self.tr("upper - Convert to uppercase"), + lambda: self.__applyTemplate("upper")) + menu.addAction( + self.tr("urlencode - Escape as URL"), + lambda: self.__applyTemplate("urlencode")) + menu.addAction( + self.tr("urlize - Convert URLs as clickable links"), + lambda: self.__applyTemplate("urlize")) + menu.addAction( + self.tr("urlizetrunc - Convert URLs as clickable links and" + " truncate"), + lambda: self.__applyTemplate("urlizetrunc")) + menu.addSeparator() + menu.addAction( + self.tr("wordcount - Return number of word"), + lambda: self.__applyTemplate("wordcount")) + menu.addAction( + self.tr("wordwrap - Wrap words"), + lambda: self.__applyTemplate("wordwrap")) + menu.addSeparator() + menu.addAction( + self.tr("yesno - Map True, False and None"), + lambda: self.__applyTemplate("yesno")) self.__filtersMenu = menu return menu + def __initHumanizeMenu(self): + """ + Private method to initialize the humanize menu. + + @return generated menu (QMenu) + """ + menu = QMenu(self.tr("Humanize")) + menu.addAction( + self.tr("Load Package"), + lambda: self.__applyTemplate("loadhumanize")) + menu.addSeparator() + menu.addAction( + self.tr("apnumber - Format integer the Associated Press style"), + lambda: self.__applyTemplate("apnumber")) + menu.addSeparator() + menu.addAction( + self.tr("intcomma - Format integer with commas"), + lambda: self.__applyTemplate("intcomma")) + menu.addAction( + self.tr("intword - Convert integer to word"), + lambda: self.__applyTemplate("intword")) + menu.addSeparator() + menu.addAction( + self.tr("naturalday - Format date naturally"), + lambda: self.__applyTemplate("naturalday")) + menu.addAction( + self.tr("naturaltime - Format time naturally"), + lambda: self.__applyTemplate("naturaltime")) + menu.addSeparator() + menu.addAction( + self.tr("ordinal - Convert integer to ordinal"), + lambda: self.__applyTemplate("ordinal")) + + self.__humanizeMenu = menu + return menu + + def __initWebDesignMenu(self): + """ + Private method to initialize the web design menu. + + @return generated menu (QMenu) + """ + menu = QMenu(self.tr("Web Design")) + menu.addAction( + self.tr("Load Package"), + lambda: self.__applyTemplate("loadweb")) + menu.addSeparator() + menu.addAction( + self.tr("lorem - Builtin Lorem Impsum Generator"), + lambda: self.__applyTemplate("lorem")) + + self.__webMenu = menu + return menu + + def __initStaticMenu(self): + """ + Private method to initialize the static menu. + + @return generated menu (QMenu) + """ + menu = QMenu(self.tr("Static")) + menu.addAction( + self.tr("Load Package"), + lambda: self.__applyTemplate("loadstatic")) + menu.addSeparator() + menu.addAction( + self.tr("static - Link to static file"), + lambda: self.__applyTemplate("staticfile")) + menu.addAction( + self.tr("static - Link to static file (via variable)"), + lambda: self.__applyTemplate("staticvariable")) + menu.addAction( + self.tr("get_static_prefix - Insert static URL"), + lambda: self.__applyTemplate("get_static_prefix")) + menu.addAction( + self.tr("get_media_prefix - Insert media URL"), + lambda: self.__applyTemplate("get_media_prefix")) + + self.__staticMenu = menu + return menu + def __findTemplateTag(self): """ Private slot to find a template tag and insert its text. @@ -272,7 +497,6 @@ @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 = "" @@ -378,6 +602,46 @@ " {{% endfor %}}".format( data[0], data[1], selectedText, data[2])) replace = True + elif tag == "if": + from .IfTagInputDialog import IfTagInputDialog + dlg = IfTagInputDialog() + if dlg.exec_() == QDialog.Accepted: + templateText = dlg.getTag() + elif tag == "ifchanged": + data, ok = DjangoTagInputDialog.getText( + None, + self.tr("Check Variables for Changes"), + [self.tr("Enter variables to check (space separated):")], + ["variable1 variable2"]) + if ok: + templateText = ( + '{{% ifchanged {0} %}}{1}{{% endifchanged %}}' + .format(data[0], selectedText)) + replace = True + elif tag == "ifequal": + data, ok = DjangoTagInputDialog.getText( + None, + self.tr("Check If Equal"), + [self.tr("Enter first variable or string to check:"), + self.tr("Enter second variable or string to check:")], + ["user.username", '"adrian"']) + if ok: + templateText = ( + '{{% ifequal {0} {1} %}}{2}{{% endifequal %}}' + .format(data[0], data[1], selectedText)) + replace = True + elif tag == "ifnotequal": + data, ok = DjangoTagInputDialog.getText( + None, + self.tr("Check If Not Equal"), + [self.tr("Enter first variable or string to check:"), + self.tr("Enter second variable or string to check:")], + ["user.username", '"adrian"']) + if ok: + templateText = ( + '{{% ifnotequal {0} {1} %}}{2}{{% endifnotequal %}}' + .format(data[0], data[1], selectedText)) + replace = True elif tag == "includevariable": data, ok = DjangoTagInputDialog.getText( None, @@ -506,22 +770,21 @@ data[0], selectedText) #################################################### - ## Template Filters ## + ## Template Filters ## #################################################### elif tag == "add": data, ok = DjangoTagInputDialog.getText( None, self.tr("Add Variable or String"), - [self.tr("Variables or String to add:") - ], + [self.tr("Variables or String to add:")], ["variable"]) if ok: templateText = "|add:{0}".format(data[0]) elif tag == "addslashes": - templateText = "|addslashes " + templateText = "|addslashes" elif tag == "capfirst": - templateText = "|capfirst " + templateText = "|capfirst" elif tag == "center": width, ok = QInputDialog.getInt( None, @@ -534,8 +797,7 @@ data, ok = DjangoTagInputDialog.getText( None, self.tr("Cut Characters"), - [self.tr("Characters to cut:") - ], + [self.tr("Characters to cut:")], [" "]) if ok: templateText = '|cut:"{0}"'.format(data[0]) @@ -548,43 +810,42 @@ "SHORT_DATE_FORMAT", "DATE_FORMAT"], 0, True) if ok: - templateText = '|date:"{0}" '.format(date) + if date: + templateText = '|date:"{0}"'.format(date) + else: + templateText = '|date' elif tag == "default": data, ok = DjangoTagInputDialog.getText( None, self.tr("Default Value if False"), - [self.tr("Enter default value if result is False:") - ], + [self.tr("Enter default value if result is False:")], ["nothing"]) if ok: - templateText = '|default:"{0}" '.format(data[0]) + templateText = '|default:"{0}"'.format(data[0]) elif tag == "default_if_none": data, ok = DjangoTagInputDialog.getText( None, self.tr("Default Value if None"), - [self.tr("Enter default value if result is None:") - ], + [self.tr("Enter default value if result is None:")], ["nothing"]) if ok: - templateText = '|default:"{0}" '.format(data[0]) + templateText = '|default:"{0}"'.format(data[0]) elif tag == "dictsort": data, ok = DjangoTagInputDialog.getText( None, self.tr("Sort Dictionaries"), - [self.tr("Enter key to sort on:") - ], + [self.tr("Enter key to sort on:")], ["key"]) if ok: - templateText = '|dictsort:"{0}" '.format(data[0]) + templateText = '|dictsort:"{0}"'.format(data[0]) elif tag == "dictsortreversed": data, ok = DjangoTagInputDialog.getText( None, self.tr("Sort Dictionaries reversed"), - [self.tr("Enter key to sort on:") - ], + [self.tr("Enter key to sort on:")], ["key"]) if ok: - templateText = '|dictsortreversed:"{0}" '.format(data[0]) + templateText = '|dictsortreversed:"{0}"'.format(data[0]) elif tag == "divisibleby": divisor, ok = QInputDialog.getInt( None, @@ -592,17 +853,17 @@ self.tr("Enter divisor value:"), 2, 1, 99, 1) if ok: - templateText = '|divisibleby:"{0}" '.format(divisor) + templateText = '|divisibleby:"{0}"'.format(divisor) elif tag == "escape": - templateText = '|escape ' + templateText = '|escape' elif tag == "escapejs": - templateText = '|escapejs ' + templateText = '|escapejs' elif tag == "filesizeformat": - templateText = '|filesizeformat ' + templateText = '|filesizeformat' elif tag == "first": - templateText = '|first ' + templateText = '|first' elif tag == "fix_ampersands": - templateText = '|fix_ampersands ' + templateText = '|fix_ampersands' elif tag == "floatformat": decimals, ok = QInputDialog.getInt( None, @@ -610,11 +871,274 @@ self.tr("Enter number of decimal places:"), 2, -20, 20, 1) if ok: - templateText = '|floatformat:"{0}" '.format(decimals) + templateText = '|floatformat:"{0}"'.format(decimals) elif tag == "force_escape": - templateText = '|force_escape ' + templateText = '|force_escape' + elif tag == "get_digit": + digit, ok = QInputDialog.getInt( + None, + self.tr("Get Rightmost Digit"), + self.tr("Enter index of digit:"), + 1, 1, 99, 1) + if ok: + templateText = '|get_digit:"{0}"'.format(digit) + elif tag == "iriencode": + templateText = '|iriencode' + elif tag == "join": + data, ok = DjangoTagInputDialog.getText( + None, + self.tr("Join List"), + [self.tr("Enter string to join by:")], + ["//"]) + if ok: + templateText = '|join:"{0}"'.format(data[0]) + elif tag == "last": + templateText = '|last' + elif tag == "length": + templateText = '|length' + elif tag == "length_is": + length, ok = QInputDialog.getInt( + None, + self.tr("Check Length"), + self.tr("Enter desired length:"), + 10, 1, 99, 1) + if ok: + templateText = '|length_is:"{0}"'.format(length) + elif tag == "linebreaks": + templateText = '|linebreaks' + elif tag == "linebreaksbr": + templateText = '|linebreaksbr' + elif tag == "linenumbers": + templateText = '|linenumbers' + elif tag == "ljust": + width, ok = QInputDialog.getInt( + None, + self.tr("Left-align Value"), + self.tr("Enter width of the output:"), + 10, 1, 99, 1) + if ok: + templateText = '|ljust:"{0}"'.format(width) + elif tag == "lower": + templateText = '|lower' + elif tag == "make_list": + templateText = '|make_list' + elif tag == "phone2numeric": + templateText = '|phone2numeric' + elif tag == "pluralize": + data, ok = DjangoTagInputDialog.getText( + None, + self.tr("Plural Suffix"), + [self.tr("Enter plural suffix (nothing for default):")], + [""]) + if ok: + if data[0]: + templateText = '|pluralize:"{0}"'.format(data[0]) + else: + templateText = '|pluralize' + elif tag == "pprint": + templateText = '|pprint' + elif tag == "random": + templateText = '|random' + elif tag == "removetags": + data, ok = DjangoTagInputDialog.getText( + None, + self.tr("Remove HTML Tags"), + [self.tr("Enter HTML tags to remove (space separated):")], + ["b span"]) + if ok: + templateText = '|removetags:"{0}"'.format(data[0]) + elif tag == "rjust": + width, ok = QInputDialog.getInt( + None, + self.tr("Right-align Value"), + self.tr("Enter width of the output:"), + 10, 1, 99, 1) + if ok: + templateText = '|rjust:"{0}"'.format(width) + elif tag == "safe": + templateText = '|safe' + elif tag == "safeseq": + templateText = '|safeseq' + elif tag == "slice": + data, ok = DjangoTagInputDialog.getText( + None, + self.tr("Extract slice of a list"), + [self.tr("Enter Python like slice expression:")], + ["1:5"]) + if ok: + templateText = '|slice:"{0}"'.format(data[0]) + elif tag == "slugify": + templateText = '|slugify' + elif tag == "stringformat": + data, ok = DjangoTagInputDialog.getText( + None, + self.tr("Perform String Formatting"), + [self.tr("Enter Python like string format:")], + [""]) + if ok: + templateText = '|stringformat:"{0}"'.format(data[0]) + elif tag == "striptags": + templateText = '|striptags' + elif tag == "time": + time, ok = QInputDialog.getItem( + None, + self.tr("Format Date"), + self.tr("Enter date format:"), + ["TIME_FORMAT"], + 0, True) + if ok: + if time: + templateText = '|time:"{0}"'.format(time) + else: + templateText = '|time' + elif tag == "timesince": + data[0], ok = DjangoTagInputDialog.getText( + None, + self.tr("Time Since"), + [self.tr("Enter variable containing time reference:")], + ["comment_date"]) + if ok: + if data[0]: + templateText = '|timesince:{0}'.format(data[0]) + else: + templateText = '|timesince' + elif tag == "timeuntil": + data[0], ok = DjangoTagInputDialog.getText( + None, + self.tr("Time Until"), + [self.tr("Enter variable containing time reference:")], + ["from_date"]) + if ok: + if data[0]: + templateText = '|timeuntil:{0}'.format(data[0]) + else: + templateText = '|timeuntil' + elif tag == "title": + templateText = '|title' + elif tag == "truncatechars": + characters, ok = QInputDialog.getInt( + None, + self.tr("Truncate String"), + self.tr("Enter number of characters:"), + 10, 1, 99, 1) + if ok: + templateText = '|truncatechars:{0}'.format(characters) + elif tag == "truncatewords": + words, ok = QInputDialog.getInt( + None, + self.tr("Truncate String"), + self.tr("Enter number of words:"), + 10, 1, 99, 1) + if ok: + templateText = '|truncatewords:{0}'.format(words) + elif tag == "truncatewords_html": + words, ok = QInputDialog.getInt( + None, + self.tr("Truncate String"), + self.tr("Enter number of words:"), + 10, 1, 99, 1) + if ok: + templateText = '|truncatewords_html:{0}'.format(words) + elif tag == "unordered_list": + templateText = '|unordered_list' + elif tag == "upper": + templateText = '|upper' + elif tag == "urlencode": + templateText = '|urlencode' + elif tag == "urlize": + templateText = '|urlize' + elif tag == "urlizetrunc": + characters, ok = QInputDialog.getInt( + None, + self.tr("Convert URLs as clickable links and truncate"), + self.tr("Enter number of characters:"), + 10, 1, 199, 1) + if ok: + templateText = '|urlizetrunc:{0}'.format(characters) + elif tag == "wordcount": + templateText = '|wordcount' + elif tag == "wordwrap": + characters, ok = QInputDialog.getInt( + None, + self.tr("Wrap words"), + self.tr("Enter number of characters:"), + 10, 1, 99, 1) + if ok: + templateText = '|wordwrap:{0}'.format(characters) + elif tag == "yesno": + data, ok = DjangoTagInputDialog.getText( + None, + self.tr("Map True, False and None"), + [self.tr("Enter mapping (comma separated):")], + ["yeah,no,maybe"]) + if ok: + if data[0]: + templateText = '|yesno:"{0}"'.format(data[0]) + else: + templateText = '|yesno' #################################################### + ## Humanize Template Tags ## + #################################################### + + elif tag == "loadhumanize": + templateText = '{% load humanize %}' + elif tag == "apnumber": + templateText = '|apnumber' + elif tag == "intcomma": + templateText = '|intcomma' + elif tag == "intword": + templateText = '|intword' + elif tag == "naturalday": + templateText = '|naturalday' + elif tag == "naturaltime": + templateText = '|naturaltime' + elif tag == "ordinal": + templateText = '|ordinal' + + #################################################### + ## Web Design Template Tags ## + #################################################### + + elif tag == "loadweb": + templateText = '{% load webdesign %}' + elif tag == "lorem": + from .LoremTagInputDialog import LoremTagInputDialog + dlg = LoremTagInputDialog() + if dlg.exec_() == QDialog.Accepted: + templateText = "{{% {0} %}}".format(dlg.getTag()) + + #################################################### + ## Static Template Tags ## + #################################################### + + elif tag == "loadstatic": + templateText = '{% load static %}' + elif tag == "staticfile": + data, ok = DjangoTagInputDialog.getText( + None, + self.tr("Link to static file"), + [self.tr("Enter relative path of static file:")], + ["images/hi.jpg"]) + if ok: + templateText = '{{% static "{0}" %}}'.format(data[0]) + elif tag == "staticvariable": + data, ok = DjangoTagInputDialog.getText( + None, + self.tr("Link to static file"), + [self.tr("Enter variable containing relative path of" + " static file:")], + ["user_stylesheet"]) + if ok: + templateText = '{{% static {0} %}}'.format(data[0]) + elif tag == "get_static_prefix": + templateText = '{% get_static_prefix %}' + elif tag == "get_media_prefix": + templateText = '{% get_media_prefix %}' + + # TODO: add comment functions + # TODO: add internationalization tags + #################################################### ## Fallback: return just the tag name ## ####################################################
--- a/ProjectDjangoTagsMenu/FindTemplateTagDialog.py Fri Feb 07 18:21:09 2014 +0100 +++ b/ProjectDjangoTagsMenu/FindTemplateTagDialog.py Sat Feb 08 18:58:33 2014 +0100 @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- +# Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de> +# + """ Module implementing a dialog to search foe template tags. """ @@ -28,31 +31,48 @@ super(FindTemplateTagDialog, self).__init__(parent) self.setupUi(self) - # TODO: check tags against handler self.__completer = QCompleter(( + # template tags 'autoescape', 'block', 'comment', 'csrf_token', 'cycle', 'debug', - 'extends', 'filter', 'firstof', 'for', 'for...empty', 'if', - 'ifchanged', 'ifequal', 'ifnotequal', 'include', 'load', 'now', - 'regroup', 'spaceless', 'ssi', 'templatetag', 'verbatim', - 'in operator', 'not in operator', 'widthratio', 'with', 'add', - 'addslashes', 'capfirst', 'center', 'cut', 'date', 'default', - 'default_if_none', 'dictsort', 'dictsortreversed', 'divisibleby', - 'escape', 'escapejs', 'filesizeformat', 'first', 'fix_ampersands', - 'floatformat', 'force_escape', 'get_digit', 'iriencode', 'join', - 'last', 'lenght', 'lenght_is', 'linebreaks', 'linebreaksbr', - 'linenumbers', 'ljust', 'lower', 'make_list', 'phone2numeric', - 'pluralize', 'pprint', 'random', 'removetags', 'rjust', 'safe', - 'safeseq', 'slice', 'slugify', 'stringformat', 'striptags', - 'time', 'timesince', 'timeuntil', 'title', 'truncatechars', - 'truncatewords', 'truncatewords_html', 'htmlcomment', + 'extendsvariable', 'extendsfile', 'filter', 'firstof', 'for', + 'for...empty', 'if', 'ifchanged', 'ifequal', 'ifnotequal', + 'includevariable', 'includefile', 'load', 'now', 'regroup', + 'spaceless', 'ssi', 'ssifile', 'templatetag', 'url', 'urlas', + 'verbatim', 'widthratio', 'with', + + # template filters + 'add', 'addslashes', 'capfirst', 'center', 'cut', 'date', + 'default', 'default_if_none', 'dictsort', 'dictsortreversed', + 'divisibleby', 'escape', 'escapejs', 'filesizeformat', 'first', + 'fix_ampersands', 'floatformat', 'force_escape', 'get_digit', + 'iriencode', 'join', 'last', 'lenght', 'lenght_is', 'linebreaks', + 'linebreaksbr', 'linenumbers', 'ljust', 'lower', 'make_list', + 'phone2numeric', 'pluralize', 'pprint', 'random', 'removetags', + 'rjust', 'safe', 'safeseq', 'slice', 'slugify', 'stringformat', + 'striptags', 'time', 'timesince', 'timeuntil', 'title', + 'truncatechars', 'truncatewords', 'truncatewords_html', 'unordered_list', 'upper', 'urlencode', 'urlize', 'urlizetrunc', - 'wordcount', 'wordwrap', 'yesno', 'apnumber', 'intcomma', - 'intword', 'naturalday', 'naturaltime', 'ordinal', 'lorem', - 'static', 'iecomment', 'get_static_prefix', 'get_media_prefix', + 'wordcount', 'wordwrap', 'yesno', + + # humanize tags + 'loadhumanize', 'apnumber', 'intcomma', 'intword', 'naturalday', + 'naturaltime', 'ordinal', + + # web design tags + 'loadweb', 'lorem', + + # static tags + 'loadstatic', 'staticfile', 'staticvariable', 'get_static_prefix', + 'get_media_prefix', + + # comments + # TODO: check tags against handler + 'htmlcomment', 'iecomment', 'singlelinecomment', 'multilinecomment', 'singlelinecommentpopup', 'multilinecommentpopup', 'singlelinecommentclipboard', 'multilinecommentclipboard', 'multilinecommentfile', - 'singlelinecommentdatetime'), self) + 'singlelinecommentdatetime'), + self) self.__completer.setCompletionMode(QCompleter.PopupCompletion) self.__completer.setCaseSensitivity(False) self.tagEdit.setCompleter(self.__completer)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProjectDjangoTagsMenu/IfTagInputDialog.py Sat Feb 08 18:58:33 2014 +0100 @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to enter the parameters for the if tag. +""" + +from PyQt4.QtCore import pyqtSlot +from PyQt4.QtGui import QDialog, QDialogButtonBox + +from .Ui_IfTagInputDialog import Ui_IfTagInputDialog + + +class IfTagInputDialog(QDialog, Ui_IfTagInputDialog): + """ + Class implementing a dialog to enter the parameters for the if tag. + """ + def __init__(self, parent=None): + """ + Constructor + + @param parent reference to the parent widget (QWidget) + """ + super().__init__(parent) + self.setupUi(self) + + self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) + + @pyqtSlot(str) + def on_ifEdit_textChanged(self, txt): + """ + Private slot to handle changes of the 'if' expression. + """ + self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(bool(txt)) + + def getTag(self): + """ + Public method to retrieve the tag. + + @return tag (string) + """ + tag = '{{% if {0} %}}\n'.format(self.ifEdit.text()) + elifText = self.elifEdit.toPlainText() + if elifText: + for expression in elifText.splitlines(): + if expression.strip(): + tag += '{{% elif {0} %}}\n'.format(expression.strip()) + if self.elseCheckBox.isChecked(): + tag += '{% else %}\n' + tag += '{% endif %}' + + return tag
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProjectDjangoTagsMenu/IfTagInputDialog.ui Sat Feb 08 18:58:33 2014 +0100 @@ -0,0 +1,118 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>IfTagInputDialog</class> + <widget class="QDialog" name="IfTagInputDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>500</width> + <height>400</height> + </rect> + </property> + <property name="windowTitle"> + <string>If Tag Template</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>'if' expression:</string> + </property> + </widget> + </item> + <item> + <widget class="E5ClearableLineEdit" name="ifEdit"> + <property name="statusTip"> + <string>Enter the 'if' expression</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>'elif' expressions (one per line):</string> + </property> + </widget> + </item> + <item> + <widget class="QPlainTextEdit" name="elifEdit"> + <property name="toolTip"> + <string>Enter 'elif' expressions one per line</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="elseCheckBox"> + <property name="toolTip"> + <string>Select to include an 'else' part</string> + </property> + <property name="text"> + <string>Include 'else'</string> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>E5ClearableLineEdit</class> + <extends>QLineEdit</extends> + <header>E5Gui/E5LineEdit.h</header> + </customwidget> + </customwidgets> + <tabstops> + <tabstop>ifEdit</tabstop> + <tabstop>elifEdit</tabstop> + <tabstop>elseCheckBox</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>IfTagInputDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>IfTagInputDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProjectDjangoTagsMenu/LoremTagInputDialog.py Sat Feb 08 18:58:33 2014 +0100 @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to enter the parameters for the lorem tag. +""" + +from PyQt4.QtGui import QDialog + +from .Ui_LoremTagInputDialog import Ui_LoremTagInputDialog + + +class LoremTagInputDialog(QDialog, Ui_LoremTagInputDialog): + """ + Class implementing a dialog to enter the parameters for the lorem tag. + """ + def __init__(self, parent=None): + """ + Constructor + + @param parent reference to the parent widget (QWidget) + """ + super(LoremTagInputDialog, self).__init__(parent) + self.setupUi(self) + + def getTag(self): + """ + Public method to get the generated tag string. + + @return tag string (string) + """ + count = "{0}".format(self.countSpinBox.value()) + method = "{0}".format("bpw"[self.methodComboBox.currentIndex()]) + random = "random" if self.randomCheckBox.isChecked() else "" + + if random: + tag = "lorem {0} {1} {2}".format(count, method, random) + elif method != "b": + tag = "lorem {0} {1}".format(count, method) + elif count != "1": + tag = "lorem {0}".format(count) + else: + tag = "lorem" + + return tag
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProjectDjangoTagsMenu/LoremTagInputDialog.ui Sat Feb 08 18:58:33 2014 +0100 @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>LoremTagInputDialog</class> + <widget class="QDialog" name="LoremTagInputDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>137</height> + </rect> + </property> + <property name="windowTitle"> + <string>Lorem Tag Template</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Count:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="countSpinBox"> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>9</number> + </property> + </widget> + </item> + <item row="0" column="2"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>272</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Method:</string> + </property> + </widget> + </item> + <item row="1" column="1" colspan="2"> + <widget class="QComboBox" name="methodComboBox"> + <item> + <property name="text"> + <string>Plain text paragraphs</string> + </property> + </item> + <item> + <property name="text"> + <string>HTML paragraphs</string> + </property> + </item> + <item> + <property name="text"> + <string>Words</string> + </property> + </item> + </widget> + </item> + <item row="2" column="0" colspan="3"> + <widget class="QCheckBox" name="randomCheckBox"> + <property name="text"> + <string>Generate random text</string> + </property> + </widget> + </item> + <item row="3" column="0" colspan="3"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>countSpinBox</tabstop> + <tabstop>methodComboBox</tabstop> + <tabstop>randomCheckBox</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>LoremTagInputDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>LoremTagInputDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui>