-
-
Notifications
You must be signed in to change notification settings - Fork 16.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding additional template variable scopes #2926
Conversation
This is awesome :)! There are a couple nits in there, but my main question, of course, would be how this would work with features of modules like Or, would the idea be that |
lib/response.js
Outdated
* | ||
* @public | ||
*/ | ||
res.addTmplVars = function addTmplVars(options) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll probably want to think of a better method name than addTmplVars
, but I don't have anything on the top of my tongue. Just adding that I don't particularly care for this name, and would love to hear thoughts from other people on it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, no argument here. I just wrote down the first thing that popped into my head.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a place holder, it's good, but yeah, that doesn't track for the long haul.
+1 We'll probably want to think of a better method name than addTmplVars
I personally was expecting that modules would automatically add variable scopes to the response, thereby lessening programmer burden. I have two thoughts regarding the issue you raised. The first is that a module could make it configurable as to whether or not they exposed variables to the template. This would mean a programmer could prevent the default exposure doing something like this: app.use(session({ tmplVars: false })); Then the programmer could manually add variable scopes whenever appropriate---e.g., after regenerating a session. The second thought is that we could allow modules to "tag" their scopes by providing an id (e.g., the module name). This id could be an optional parameter, maybe something like this: res.addTmplVars('myId', scopeObj); If there were two calls using the same id, the later call would replace the earlier call. In this way a session module could automatically update its scope whenever the session was regenerated. As an added bonus, if you ever decided to expose scopes using variable names (as discussed in #2924) you could use the identifiers as the variable names. Thus, I could be sure I was using variable |
I like the idea of naming scopes. Could lead to a nice api like |
I like that idea, @tunniclm. It does create a potential for name clashes, but (I would say) not unreasonably so. It should be easy enough for modules to allow the programmer to modify the scope name used by the module if necessary. Questions that occur to me: Is it required that all scopes have a name? What about For my part, I would suggest that all scopes should be required to have a name, and that you choose and reserve names for |
I have taken @tunniclm's suggestion and renamed the
If no scope with name
If scope with name
If I use properties The scope stack is completely unrelated to both To support the new behavior, I have added another signature for
This has the usual behavior of The other signatures of |
I'm not really sure of your process here, so I wanted to check in on this. Is this being considered for possible inclusion in a future release? If so, is there anything I can do to help it be approved? Thanks. |
Great effort and implementation. However, my opinion is that the functionality should be implemented at the application level; we should keep Express as simple as possible. @expressjs/express-tc |
Alright, this is definitely a stale pull request. Not sure why we didn't close it, but above is our thoughts, ultimately. |
This is a follow up to #2924. It addresses the issue of exposing session variables to template engines using a more general approach. Note that unlike #2924, this request does not involve exposing scopes explicitly using certain names.
Each response (potentially) has a stack of template variable scopes. Each scope is an object whose properties define the variables to be exposed. A method was added to the response object named
addTmplVars
. The parameter to this method is a scope to be pushed on the scope stack. Here is an example:The scope is stored directly on the scope stack. Therefore, any changes made to that scope will be visible to the template engine. For example, the following code listing has the same effect as the previous one.
When a template is rendered, the objects on the scope stack are "flattened" into a single object. This "flattening" does not alter the scopes in any way; it merely copies their properties to a new object. In the case of conflicts, variables from scopes higher up in the stack will replace those from scopes lower in the stack.
Prior to this "flattening", the variables of
app.locals
are effectively added to the bottom of the stack, and variables fromres.locals
are added to the top of the stack, followed by variables passed tores.render
. This augmented stack may be represented as follows:variables passed to
res.render
->res.locals
-> scope stack (high to low) ->app.locals
The arrows here represent precedence: variables from scopes on the left of the arrow will override variables from scopes on the right should a conflict occur.
The idea here is that any middleware can expose a scope to the template engine. For example, when using express-session, it could push the session object onto the scope stack, allowing session variables to be directly accessed by the template. Should multiple middlewares push scopes to the stack, the order in which they execute will define precedence.
I used the
tmplVars
property of the response object to hold the scope stack. I would expect this to be considered a private variable. The property is not created until the first timeaddTmplVars
is called.