<
From version < 6.1 >
edited by Marius Dumitru Florea
on 2011/01/21
To version < 6.2 >
edited by Sergiu Dumitriu
on 2011/01/21
>
Change comment: There is no comment for this version

Summary

Details

Page properties
Author
... ... @@ -1,1 +1,1 @@
1 -XWiki.mflorea
1 +XWiki.Sergiu
Content
... ... @@ -65,11 +65,114 @@
65 65  
66 66  = Backward Compatibility and Migration Notes =
67 67  
68 +== The Velocity engine was updated to version 1.7, which is slightly backwwards icompatible with previous versions ==
69 +
68 68  {{warning}}
69 -We upgraded Velocity to version 1.7 which brings a lot of changes that are not backwards compatible. We had to fix the following problems on the velocity code bundled with XWiki Enteprise:
70 -* Escape quotes in interpolated strings (both ' and ") by doubling them ('' and "") (See [[VELOCITY-555>>https://issues.apache.org/jira/browse/VELOCITY-555]])
71 +We upgraded Velocity to version 1.7 which brings several changes that are not backwards compatible.
71 71  {{/warning}}
72 72  
74 +We had to fix the following problems on the velocity code bundled with XWiki Enteprise:
75 +
76 +* Escape quotes in interpolated strings (both ' and ") by doubling them ('' and "") (See [[VELOCITY-555>>https://issues.apache.org/jira/browse/VELOCITY-555]])
77 +
78 +=== Macro evaluation strategy ===
79 +
80 +The main change is that Velocity 1.7 changed the way macro evaluations work. While before it was more flexible with many possible outcomes depending on what parameters were passed, and how they were used inside the macro, the current version simplified a lot the internal logic of variable assignments inside macros, which resulted in a critical regression for us. The same change was introduced between 1.6.0 and 1.6.1, but was reverted in 1.6.2 when we notified them of the regression, with the decision to go further with the change in 1.7.
81 +
82 +To better understand the kind of code that doesn't work, take this example:
83 +
84 +{{code language="none}}
85 +#macro(callBySharing $x)
86 + #set($x = 'a')
87 +#end
88 +#set($y = 'y')
89 +#callBySharing($y)
90 +
91 +$y -> 'y' in 1.7
92 +$y -> 'a' in 1.6.2, 1.6.0 and before)
93 +{{/code}}
94 +
95 +But:
96 +
97 +{{code language="none"}}
98 +#set($x = 'x')
99 +#callBySharing($x)
100 +
101 +$x -> 'a' in all versions
102 +{{/code}}
103 +
104 +This means that only macros that are supposed to assign and return a value in one of its formal parameters will stop working, and only when the formal and actual parameters have different names. Macros with signatures like:
105 +
106 +{{code language="none"}}
107 +#macro(computeSomething $fromValue1 $fromValue2 $putResultHere)
108 +{{/code}}
109 +
110 +The only macro in the global ##macros.vm## that was broken by this change was ###setVariableFromRequest##, which is already fixed in the released version.
111 +
112 +Now there's also a generic ###setVariable ("variableName" $value)## macro which can be used to emulate the call by sharing behavior in custom macros. How to use it:
113 +
114 +Suppose you had a macro like this:
115 +
116 +
117 +{{code language="none"}}
118 +#macro(isBlogGlobal $blogDoc $isGlobal)
119 + #set($isGlobal = false)
120 + #getBlogProperty($blogDoc 'blogType' '' $discard)
121 + #if($discard == 'global')
122 + #set($isGlobal = true)
123 + #end
124 +#end
125 +{{/code}}
126 +
127 +Here ##$isGlobal## is the output variable which now doesn't always work. The updated version of the macro can be written as:
128 +
129 +{{code language="none"}}
130 +#macro(isBlogGlobal $blogDoc $isGlobal)
131 + #set ($result = false)
132 + #getBlogProperty($blogDoc 'blogType' '' $discard)
133 + #if($discard == 'global')
134 + #set($result = true)
135 + #end
136 + #set ($isGlobal = $util.null)
137 + #setVariable ("$isGlobal" $result)
138 +#end
139 +{{/code}}
140 +
141 +Pay attention to the last two lines in the macro.
142 +
143 +In Velocity, when rendering ##$variable##, where ##$variable## is ##undefined## or ##null##, will cause the variable name to be printed instead. As it happens, when inside a macro, what gets printed is the name of the actual parameter (the one passed in the macro call), and not the formal one (the one declared in the macro definition). So, whenever ##$isGlobal## is rendered as a string, the name of the actual parameter is obtained.
144 +
145 +###set ($isGlobal = $util.null)## will make sure that no matter what the previous value of the variable was, ##$isGlobal## will be ##null## from this point forward, and ##"$isGlobal"## will output the name of the actual parameter.
146 +
147 +When calling ###setVariable ("$isGlobal" $result)##, the first parameter will contain the name of the actual parameter used when calling ###isBlogGlobal##.
148 +
149 +Inside the ###setVariable## macro, the wanted variable is assigned using ###evaluate##.
150 +
151 +=== Quotes and apostrophes inside strings ===
152 +
153 +The second change is the escape syntax used inside strings for quotes and apostrophes. While before this used to work:
154 +
155 +{{code language="none"}}
156 +{{velocity}}
157 +#set ($a = "He said \"maybe\"")
158 +$a => He said \"maybe\"
159 +{{/velocity}}
160 +{{/code}}
161 +
162 +now this snippet would throw an exception. Trying to escape an apostrophe inside an apostrophe-delimited string would have failed even before.
163 +
164 +In Velocity 1.7 it is possible to place both single and double quotes inside a string, by doubling that character. For example:
165 +
166 +{{code language="none"}}
167 +{{velocity}}
168 +#set ($a = "He said ""maybe""")
169 +$a => He said "maybe"
170 +
171 +#set ($b = 'that''s funny')
172 +$b => that's funny
173 +{{/velocity}}
174 +{{/code}}
175 +
73 73  == General Notes ==
74 74  
75 75  {{warning}}

Get Connected