Closed bminer closed 11 years ago
Thanks for creating the issue. I'm so glad you're working on it!
Great work! :)
@VanCoding - has this been fixed? Can you confirm? Thanks!
Can someone please confirm that this bug has been fixed? Thanks!
This issue has been fixed. Included templates inherit their parent's locals and view helpers, but they can be overwritten. Issue #141 discusses the possibility of preventing included views from inheriting their parent's locals by default.
I'm having the following issue:
Within the file parent.blade, there is the following dynamic include:
include dynamicTemplateVaraible exposing someDataVariable
Here, someVariable is not available within the template we assigned to dynamicTemplateVaraible. Instead, dynamicTemplateVaraible has the same locals as parent.blade.
-=-=-=-==-
However, in non-dynamic includes things behave as expected, as in:
include "nonDynamic.blade" exposing someDataVariable
Here, someDataVariable is available to the included template, and the parent locals are not available to the child.
======= UPDATE
I found a pretty clean workaround.
Create a dynamicInclude.blade file. That file should contain only this: include dynamicIncludeName
Then when you want to use a dynamic include in a parent template, write it like this: -var dynamicIncludeName = variableDerivedFromLocalOrWhatever; include 'dynamicInclude' exposing dynamicIncludeName, whateverOtherVariable, anotherVariableEtc
What happens is dynamicInclude.blade will receive the exposed variables and use them as locals, as in this part, it is a static include and static includes do fine with receiving exposed variables. dynamicInclude.blade uses the variable dynamicIncludeName to dynamically include the desired dynamic template. Because this is a dynamic include, exposing variables doesn't work, and it receives the local variables of its parent, and those local variables (whateverOtherVariable,anotherVariableEtc) are the ones we intended to reach the desired dynamic template.
That's some weird behavior... I'll have to track down the issue as time permits. Thanks for the bug report!
Looks like my workaround doesn't work in Safari. I'm getting a nasty error:
TypeError: setting a property that has only a getter at /Users/username/meteortest/groop3/views/characterList.blade:2:1
1 | -var dynamicIncludeName = nestedViewItem.includeName + 'Panel'; 2 > include dynamicIncludeName
Could you post the full stack trace, please?
@defualt - I cannot replicate your bug. I believe that this issue is now closed. Try upgrading to the latest version of Blade and Meteor 0.6.2.
I've updated and after updating, I've created new meteor/mrt/blade projects to be sure I'm working with the most up to date and the error persists. I think my particular exception is a result of workarounds for some bugs in meteor or blade, but I think the root of the issue is that dynamic includes are not exposing specified variables.
I made this repository to demonstrate the bug. You will find instructions for adding and removing commenting to show meaningful errors if you mrt it. https://github.com/defualt/bladebug
And this is the project I am working on where you can see the exception in Safari. https://github.com/defualt/Peanuts
Here is the stack trace from my Peanuts project in safari:
(anonymous function)() at characterListPanel.js:52 (anonymous function)() at deftemplate.js:138 (anonymous function)() at spark.js:846 (anonymous function)() at deps.js:129 (anonymous function)() at deps.js:64 (anonymous function)() at deps.js:255 (anonymous function)() at spark.js:844 (anonymous function)() at deftemplate.js:135 (anonymous function)() at spark.js:1183 (anonymous function)() at deftemplate.js:116 (anonymous function)() at spark.js:1114 (anonymous function)() at deftemplate.js:115 (anonymous function)() at runtime-meteor.js:45 (anonymous function)() at spark.js:1114 (anonymous function)() at runtime-meteor.js:44 anonymous() at characterList.js:15 (anonymous function)() at characterList.js:25 (anonymous function)() at deftemplate.js:138 (anonymous function)() at spark.js:846 (anonymous function)() at deps.js:129 (anonymous function)() at deps.js:64 (anonymous function)() at deps.js:255 (anonymous function)() at spark.js:844 (anonymous function)() at deftemplate.js:135 (anonymous function)() at spark.js:1183 (anonymous function)() at deftemplate.js:116 (anonymous function)() at spark.js:1114 (anonymous function)() at deftemplate.js:115 (anonymous function)() at runtime-meteor.js:45 (anonymous function)() at spark.js:1114 (anonymous function)() at runtime-meteor.js:44 anonymous() at dynamicInclude.js:15 (anonymous function)() at dynamicInclude.js:25 (anonymous function)() at deftemplate.js:138 (anonymous function)() at spark.js:846 (anonymous function)() at deps.js:129 (anonymous function)() at deps.js:64 (anonymous function)() at deps.js:255 (anonymous function)() at spark.js:844 (anonymous function)() at deftemplate.js:135 (anonymous function)() at spark.js:1183 (anonymous function)() at deftemplate.js:116 (anonymous function)() at spark.js:1114 (anonymous function)() at deftemplate.js:115 (anonymous function)() at runtime-meteor.js:45 (anonymous function)() at spark.js:1114 (anonymous function)() at runtime-meteor.js:44 (anonymous function)() at rootView.js:39 (anonymous function)() at runtime.js:512 wrapper() at runtime.js:462isolateWrapper() at runtime.js:467 (anonymous function)() at runtime.js:510 (anonymous function)() at spark.js:1114 itemFuncWrapper() at runtime.js:509 (anonymous function)() at runtime.js:533 anonymous() at rootView.js:31 (anonymous function)() at rootView.js:57 (anonymous function)() at deftemplate.js:138 (anonymous function)() at spark.js:846 (anonymous function)() at deps.js:129 (anonymous function)() at deps.js:64 (anonymous function)() at deps.js:255 (anonymous function)() at spark.js:844 (anonymous function)() at deftemplate.js:135 (anonymous function)() at spark.js:1183 (anonymous function)() at deftemplate.js:116 (anonymous function)() at spark.js:1114 (anonymous function)() at deftemplate.js:115 (anonymous function)() at peanuts.js:17 (anonymous function)() at spark.js:846 (anonymous function)() at deps.js:129 (anonymous function)() at deps.js:64 (anonymous function)() at deps.js:255 (anonymous function)() at spark.js:844 (anonymous function)() at convenience.js:3 (anonymous function)() at spark.js:39 (anonymous function)() at spark.js:211 (anonymous function)() at spark.js:411 (anonymous function)() at convenience.js:2 (anonymous function)() at peanuts.js:14 (anonymous function)() at bladestest.js:230 (anonymous function)() at bladestest.js:229 (anonymous function)() at startup_client.js:8
Finally, the Blade documentation about includes is somewhat misleading. Notice that you are expressing a global variable , which you are then exposing to a child template.
- header = "Header: 1, 2, 3"
- text = "This is some text: 1, 2, 3"
- for(var i = 0; i < 10; i++) include "foobar" exposing i, text
"text" is available in the included template and everywhere else because it's global. In this example, you are including "foobar.blade" non-dynamically. If you were to include it dynamically, and if you expressed "text" with a "var" keyword, then "text" would not be available to the child. This tripped me up while trying to figure out this bug because I used this as an example and it appeared that my dynamic include/exposing was working, but this was only because the global variable was making it into my child template due to it's being global, not due its being exposed.
Thanks for your work on this.
@defualt - I can now duplicate your bug, and you are correct. I will correct this shortly.
Since updating, variables will only be passed into an included template if you use "exposing". If you omit "exposing [variables]" then no local variables get passed into the included template.
This behavior does not match the documentation. "By default, Blade will pass the parent's local variables to the included template; however, when using the exposing keyword, you can specify exactly which variables are to be exposed to the included template."
I've updated https://github.com/defualt/bladebug to demonstrate the issue.
Also, I can confirm that exposing variables in a dynamic include effectively passes those variables into the included template. So now dynamic and non-dynamic includes that use "exposing" function as expected.
Sorry, @defualt - I should clarify the documentation. Blade will pass view locals to included (child) templates. It will not automatically pass local variables declared using the var
keyword. It only passes the properties of the locals
Object.
@defualt - Thank you very much for your help. I believe that the documentation and the implementation should now be consistent with one another. If not, please feel free to post back here.
Thanks again!
When you include a template using
include "foo.blade"
the subtemplate uses the data context of the current template.