{"action":"created","issue":{"url":"https://api.github.com/repos/expressjs/express/issues/2924","repository_url":"https://api.github.com/repos/expressjs/express","labels_url":"https://api.github.com/repos/expressjs/express/issues/2924/labels{/name}","comments_url":"https://api.github.com/repos/expressjs/express/issues/2924/comments","events_url":"https://api.github.com/repos/expressjs/express/issues/2924/events","html_url":"https://github.com/expressjs/express/pull/2924","id":138074732,"number":2924,"title":"Exposing session variables to template.","user":{"login":"gfoust","id":1664161,"avatar_url":"https://avatars.githubusercontent.com/u/1664161?v=3","gravatar_id":"","url":"https://api.github.com/users/gfoust","html_url":"https://github.com/gfoust","followers_url":"https://api.github.com/users/gfoust/followers","following_url":"https://api.github.com/users/gfoust/following{/other_user}","gists_url":"https://api.github.com/users/gfoust/gists{/gist_id}","starred_url":"https://api.github.com/users/gfoust/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gfoust/subscriptions","organizations_url":"https://api.github.com/users/gfoust/orgs","repos_url":"https://api.github.com/users/gfoust/repos","events_url":"https://api.github.com/users/gfoust/events{/privacy}","received_events_url":"https://api.github.com/users/gfoust/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/expressjs/express/labels/5.x","name":"5.x","color":"ededed"},{"url":"https://api.github.com/repos/expressjs/express/labels/ideas","name":"ideas","color":"d7e102"},{"url":"https://api.github.com/repos/expressjs/express/labels/pr","name":"pr","color":"006b75"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2016-03-03T04:48:59Z","updated_at":"2016-03-03T05:51:42Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/expressjs/express/pulls/2924","html_url":"https://github.com/expressjs/express/pull/2924","diff_url":"https://github.com/expressjs/express/pull/2924.diff","patch_url":"https://github.com/expressjs/express/pull/2924.patch"},"body":"This is a request for a change I'd like to see in Express.  It exposes session variables to the template engine.\r\n\r\nCurrently the template engine is passed a map of variables obtained by combining the variables of `app.locals`, `res.locals`, and those passed directly to `res.render`.  In the case of conflicts, variables of `res.locals` override `app.locals`, and variables passed to `res.render` override both.  The template cannot reference session variables directly; they must be explicitly copied into `res.locals` or into the map passed to `res.render`.\r\n\r\nThis change adds the properties of the `req.session` object to the variables map passed to the template engine so that they may be referenced directly by the template.  In the case of conflicts, variables of `req.session` override those of `app.locals`, but variables of `res.locals` and those passed to `res.render` override those of `app.session`.  FYI:  this is consistent with the behavior of JSP.  The idea is that `app.locals` holds global variables, `req.session` holds variables specific to the user, `res.locals` holds variables specific to the request, and variables specific to the template are passed to `res.render`.\r\n\r\nFurthermore, all four variable maps are exposed through variables `_application` for `app.locals`, `_session` for `req.session`, `_request` for `res.locals`, and `_template` for variables passed to `res.render`.  This allows explicit name-conflict resolution (and, again, follows the behavior of JSP).\r\n\r\nThis change does not require `req.session` to exist; in the case where it doesn't, no session variables will be added to the map.  Note that all enumerable properties of the session are exposed.  In the case of express-session, this would include object methods such as `save`, `reload`, and `destroy`.  I have submitted a separate pull request to express-session that would make all such methods non-enumerable.\r\n\r\nThis change does have the potential to break existing applications in rare cases where there is a conflict between a session variable and a variable in `app.locals`.  Prior to the change the variable name would result in the value from `app.locals`, after the change it will result in the value from `req.session`.  This can be fixed in the template by explicitly referencing the desired scope (e.g., `_application.x` instead of just `x`).  However, if this is a concern, a configuration option could be used to determine whether or not session variables are exposed to the template engine.\r\n\r\nThis change uses `res.req` to access the request object via the response object in order to access the session object.  This property is not listed in the official API documentation.  If there are plans to remove that property, an alternative approach to accessing the session would be required.\r\n\r\nThanks."},"comment":{"url":"https://api.github.com/repos/expressjs/express/issues/comments/191593839","html_url":"https://github.com/expressjs/express/pull/2924#issuecomment-191593839","issue_url":"https://api.github.com/repos/expressjs/express/issues/2924","id":191593839,"user":{"login":"gfoust","id":1664161,"avatar_url":"https://avatars.githubusercontent.com/u/1664161?v=3","gravatar_id":"","url":"https://api.github.com/users/gfoust","html_url":"https://github.com/gfoust","followers_url":"https://api.github.com/users/gfoust/followers","following_url":"https://api.github.com/users/gfoust/following{/other_user}","gists_url":"https://api.github.com/users/gfoust/gists{/gist_id}","starred_url":"https://api.github.com/users/gfoust/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gfoust/subscriptions","organizations_url":"https://api.github.com/users/gfoust/orgs","repos_url":"https://api.github.com/users/gfoust/repos","events_url":"https://api.github.com/users/gfoust/events{/privacy}","received_events_url":"https://api.github.com/users/gfoust/received_events","type":"User","site_admin":false},"created_at":"2016-03-03T05:51:42Z","updated_at":"2016-03-03T05:51:42Z","body":"I don't mind splitting it into two requests, but I'm a little unsure as how to proceed since one of those pull requests will have to be based on the other.  Can I make a pull request that depends on another pending pull request?  (Sorry, I'm new at this.)\r\n\r\nTo continue the discussion on configuration:  suppose each request had some sort of \"variables stack\"---an array of variable maps.  At the beginning of the request the stack might contain just `app.locals`; calling `res.render` might result in pushing first `res.locals`, then the variables passed to `res.render`.  Then the stack gets flattened into a single variable map---with maps higher-up in the stack overriding maps lower-down---and passed to the template engine.\r\n\r\nSo, ultimately every variable stack would begin with `apps.locals` and end with `res.locals` and the variables passed to `res.render`.  In between, other middleware could add variable maps to the stack.  So, e.g., when the express-session middleware is triggered, it could first create `req.session`, then push it onto the variables stack.  Other middleware could likewise push variables onto the stack; the order of execution for the middleware would affect which variables get overridden."}}