Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implement "iriencode" filter

  • Loading branch information...
commit 9646b5a4e68c3fe8e9ab29d3408b4f8b8d33a4d0 1 parent e26d23f
@evanmiller evanmiller authored
View
6 README.markdown
@@ -1,15 +1,15 @@
ErlyDTL
=======
-ErlyDTL implements most but not all of the Django Template Language.
+ErlyDTL compiles Django Template Language to Erlang bytecode.
*Supported tags*: autoescape, block, comment, cycle, extends, filter, firstof, for, if, ifequal, ifnotequal, include, now, spaceless, ssi, templatetag, trans, widthratio, with
_Unsupported tags_: csrf_token, ifchanged, regroup, url
-*Supported filters*: add, addslashes, capfirst, center, cut, date, default, default_if_none, dictsort, dictsortreversed, divisibleby, escape, escapejs, filesizeformat, first, fix_ampersands, floatformat, force_escape, format_integer, format_number, get_digit, join, last, length, length_is, linebreaks, linebreaksbr, linenumbers, ljust, lower, make_list, phonenumeric, pluralize, pprint, random, random_num, random_range, removetags, rjust, safe, safeseq, slice, slugify, stringformat, striptags, time, timesince, timeuntil, title, truncatewords, truncatewords_html, unordered_list, upper, urlencode, urlize, urlizetrunc, wordcount, wordwrap, yesno
+*Supported filters*: add, addslashes, capfirst, center, cut, date, default, default_if_none, dictsort, dictsortreversed, divisibleby, escape, escapejs, filesizeformat, first, fix_ampersands, floatformat, force_escape, format_integer, format_number, get_digit, iriencode, join, last, length, length_is, linebreaks, linebreaksbr, linenumbers, ljust, lower, make_list, phonenumeric, pluralize, pprint, random, random_num, random_range, removetags, rjust, safe, safeseq, slice, slugify, stringformat, striptags, time, timesince, timeuntil, title, truncatewords, truncatewords_html, unordered_list, upper, urlencode, urlize, urlizetrunc, wordcount, wordwrap, yesno
-_Unsupported filter_: iriencode
+_Unsupported filters_: _none_
Project homepage: <http://code.google.com/p/erlydtl/>
View
2  src/erlydtl_compiler.erl
@@ -852,7 +852,7 @@ auto_escape(Value, _, _) ->
Value.
firstof_ast(Vars, Context, TreeWalker) ->
- body_ast([lists:foldl(fun
+ body_ast([lists:foldr(fun
({L, _, _}=Var, []) when L=:=string_literal;L=:=number_literal ->
Var;
({L, _, _}, _) when L=:=string_literal;L=:=number_literal ->
View
36 src/erlydtl_filters.erl
@@ -67,7 +67,7 @@
format_integer/1,
format_number/1,
get_digit/2,
- %iriencode/1,
+ iriencode/1,
join/2,
last/1,
length/1,
@@ -117,6 +117,27 @@
(C >= $0 andalso C =< $9) orelse
(C =:= $\. orelse C =:= $-
orelse C =:= $~ orelse C =:= $_))).
+
+-define(NO_IRI_ENCODE(C), (?NO_ENCODE(C) orelse (
+ C =:= $/ orelse
+ C =:= $# orelse
+ C =:= $[ orelse
+ C =:= $] orelse
+ C =:= $= orelse
+ C =:= $: orelse
+ C =:= $; orelse
+ C =:= $$ orelse
+ C =:= $& orelse
+ C =:= $( orelse
+ C =:= $) orelse
+ C =:= $+ orelse
+ C =:= $, orelse
+ C =:= $! orelse
+ C =:= $? orelse
+ C =:= $* orelse
+ C =:= $@ orelse
+ C =:= $' orelse
+ C =:= $~))).
-define(KILOBYTE, 1024).
-define(MEGABYTE, (1024 * ?KILOBYTE)).
@@ -308,6 +329,9 @@ get_digit(Input, Digit) when Digit > 0 ->
get_digit(Input, _) ->
Input.
+iriencode(Input) ->
+ iriencode(unicode:characters_to_list(Input), []).
+
%% @doc Joins a list with a given separator.
join(Input, Separator) when is_list(Input) ->
join_io(Input, Separator).
@@ -832,6 +856,16 @@ fix_ampersands("&" ++ Rest, Acc) ->
fix_ampersands([C | Rest], Acc) ->
fix_ampersands(Rest, [C | Acc]).
+iriencode([], Acc) ->
+ lists:reverse(Acc);
+iriencode([C | Rest], Acc) when ?NO_IRI_ENCODE(C) ->
+ iriencode(Rest, [C | Acc]);
+iriencode([$\s | Rest], Acc) ->
+ iriencode(Rest, [$+ | Acc]);
+iriencode([C | Rest], Acc) ->
+ <<Hi:4, Lo:4>> = <<C>>,
+ iriencode(Rest, [hexdigit(Lo), hexdigit(Hi), $\% | Acc]).
+
join_io([], _Sep) -> [];
join_io([_] = X, _Sep) -> X;
join_io([X|T], Sep) -> [X,Sep] ++ join_io(T, Sep).
View
11 src/erlydtl_parser.yrl
@@ -39,6 +39,7 @@ Nonterminals
ValueBraced
Value
+ Values
Variable
Filter
@@ -63,8 +64,6 @@ Nonterminals
NowTag
FirstofTag
- FirstofList
- FirstofValues
FilterBlock
FilterBraced
@@ -218,6 +217,9 @@ Value -> Value '|' Filter : {apply_filter, '$1', '$3'}.
Value -> Variable : '$1'.
Value -> Literal : '$1'.
+Values -> Value : ['$1'].
+Values -> Values Value : '$1' ++ ['$2'].
+
Variable -> identifier : {variable, '$1'}.
Variable -> Variable '.' identifier : {attribute, {'$3', '$1'}}.
@@ -254,10 +256,7 @@ EndFilterBraced -> open_tag endfilter_keyword close_tag.
Filters -> Filter : ['$1'].
Filters -> Filters '|' Filter : '$1' ++ ['$3'].
-FirstofTag -> open_tag firstof_keyword FirstofList close_tag : '$3'.
-FirstofList -> FirstofValues : {firstof, '$1'}.
-FirstofValues -> FirstofValues Value : ['$2'|'$1'].
-FirstofValues -> Value : ['$1'].
+FirstofTag -> open_tag firstof_keyword Values close_tag : {firstof, '$3'}.
ForBlock -> ForBraced Elements EndForBraced : {for, '$1', '$2'}.
ForBlock -> ForBraced Elements EmptyBraced Elements EndForBraced : {for, '$1', '$2', '$4'}.
View
2  src/erlydtl_scanner.erl
@@ -96,7 +96,7 @@ scan([], Scanned, _, in_text) ->
"templatetag", "openblock", "closeblock", "openvariable", "closevariable", "openbrace", "closebrace", "opencomment", "closecomment",
- %TODO "url",
+ % "url", - implemented as custom tag
"widthratio",
View
2  tests/src/erlydtl_unittests.erl
@@ -425,6 +425,8 @@ tests() ->
<<"{{ var1|format_number }}">>, [{var1, fun() -> fun() -> 31 end end}], <<"31">>},
{"|get_digit:\"2\"",
<<"{{ var1|get_digit:\"2\" }}">>, [{var1, 42}], <<"4">>},
+ {"|iriencode",
+ <<"{{ url|iriencode }}">>, [{url, "You #$*@!!"}], <<"You+#$*@!!">>},
{"|join:\", \" (list)",
<<"{{ var1|join:\", \" }}">>, [{var1, ["Liberte", "Egalite", "Fraternite"]}],
<<"Liberte, Egalite, Fraternite">>},
Please sign in to comment.
Something went wrong with that request. Please try again.