--- 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 ## ####################################################