{"action":"created","issue":{"url":"https://api.github.com/repos/jadejs/jade/issues/2055","labels_url":"https://api.github.com/repos/jadejs/jade/issues/2055/labels{/name}","comments_url":"https://api.github.com/repos/jadejs/jade/issues/2055/comments","events_url":"https://api.github.com/repos/jadejs/jade/issues/2055/events","html_url":"https://github.com/jadejs/jade/issues/2055","id":102399161,"number":2055,"title":"Re-imagining how blocks work","user":{"login":"ForbesLindesay","id":1260646,"avatar_url":"https://avatars.githubusercontent.com/u/1260646?v=3","gravatar_id":"","url":"https://api.github.com/users/ForbesLindesay","html_url":"https://github.com/ForbesLindesay","followers_url":"https://api.github.com/users/ForbesLindesay/followers","following_url":"https://api.github.com/users/ForbesLindesay/following{/other_user}","gists_url":"https://api.github.com/users/ForbesLindesay/gists{/gist_id}","starred_url":"https://api.github.com/users/ForbesLindesay/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ForbesLindesay/subscriptions","organizations_url":"https://api.github.com/users/ForbesLindesay/orgs","repos_url":"https://api.github.com/users/ForbesLindesay/repos","events_url":"https://api.github.com/users/ForbesLindesay/events{/privacy}","received_events_url":"https://api.github.com/users/ForbesLindesay/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/jadejs/jade/labels/blocks%20&%20extends","name":"blocks & extends","color":"FF8F00"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/jadejs/jade/milestones/2","html_url":"https://github.com/jadejs/jade/milestones/2.0.0","labels_url":"https://api.github.com/repos/jadejs/jade/milestones/2/labels","id":558592,"number":2,"title":"2.0.0","description":null,"creator":{"login":"ForbesLindesay","id":1260646,"avatar_url":"https://avatars.githubusercontent.com/u/1260646?v=3","gravatar_id":"","url":"https://api.github.com/users/ForbesLindesay","html_url":"https://github.com/ForbesLindesay","followers_url":"https://api.github.com/users/ForbesLindesay/followers","following_url":"https://api.github.com/users/ForbesLindesay/following{/other_user}","gists_url":"https://api.github.com/users/ForbesLindesay/gists{/gist_id}","starred_url":"https://api.github.com/users/ForbesLindesay/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ForbesLindesay/subscriptions","organizations_url":"https://api.github.com/users/ForbesLindesay/orgs","repos_url":"https://api.github.com/users/ForbesLindesay/repos","events_url":"https://api.github.com/users/ForbesLindesay/events{/privacy}","received_events_url":"https://api.github.com/users/ForbesLindesay/received_events","type":"User","site_admin":false},"open_issues":18,"closed_issues":32,"state":"open","created_at":"2014-02-04T15:26:30Z","updated_at":"2015-08-21T15:02:09Z","due_on":null,"closed_at":null},"comments":3,"created_at":"2015-08-21T15:02:09Z","updated_at":"2015-08-22T12:09:53Z","closed_at":null,"body":"I've been doing some thinking about how to simplify blocks in jade 2.0.0.  I'd love to get people's thoughts.\r\n\r\n# jade 1.x.x\r\n\r\n- `yield` declares a block to be overridden when the template is included\r\n- `block` declares a block to be overridden when the mixin is called\r\n- `block <name>` declares or overrides a block by name\r\n- `block (append|prepend) <name>` append or prepend onto a block\r\n- `extends ./path-to-file.jade` Load file, use blocks in this file to override blocks in the file being extended\r\n- `include ./path-to-file.jade` Load file, use body as value for `yield` keyword then munge content of `include` with current file.\r\n\r\nThis is messy:\r\n - The behaviour gets extremely hard to define around what happens when include and extends interact\r\n - There is no way to pass multiple named blocks to an include or a mixin\r\n - There is no clean way to specify a \"default\" block for extends, leading to a mess of `content`/`body`/`default` etc.\r\n - There is no uniform way to get the text of a block as a value (e.g. to use in an attribute)\r\n\r\n# jade 2.x.x\r\n\r\n - removed: `yield` and `block <name>`\r\n - `block` is a short hand for `block declare DEFAULT`, works in mixins, included files and extended files\r\n - `block <name>` overrides a block by name (note that it does not \"declare\" a block any more)\r\n - `block declare <NAME>` declares a block by name to be overriden\r\n - `include ./filename.jade` and `+mixin_call` both accept a body.  anything in the body that is not inside a block is automatically put inside a single `block DEFAULT`\r\n - `extends ./filename.jade` is equivalent to `include ./filename.jade` followed by an indent.  It is only allowed as the first thing in a file.\r\n - `block (append|prepend) <name>` append or prepend onto a block\r\n - A new keyword is added to JavaScript inside jade called `block` that must be immediately followed by a block name.  e.g. `input(value=(block value))`\r\n\r\nThis means that `+mixin_call`, `include ./filename.jade` and `extend ./filename.jade` all do essentially the same thing.  They create a \"Block Context\".\r\n\r\n# Examples\r\n\r\nlayout.jade\r\n```jade\r\ndoctype html\r\nhtml\r\n  head\r\n    title My Layout\r\n  body\r\n    block\r\n    script(src=\"/jquery.js\")\r\n    block scripts\r\n```\r\n\r\nTo use this layout template, you can use `extend`:\r\n\r\nchild.jade\r\n```jade\r\nextend ./layout.jade\r\n\r\nh1 My Child Page\r\n```\r\n\r\nCould also have been written as:\r\n\r\n```jade\r\ninclude ./layout.jade\r\n  h1 My Child Page\r\n```\r\n\r\nWhich is, itself a short hand for:\r\n\r\n```jade\r\ninclude ./layout.jade\r\n  block DEFAULT\r\n    h1 My Child Page\r\n```\r\n\r\nEither way the output would be:\r\n\r\n```html\r\n<!DOCTYPE html>\r\n<html>\r\n  <head>\r\n    <title>My Layout</title>\r\n  </head>\r\n  <body>\r\n    <h1>My Child Page</h1>\r\n    <script src=\"/jquery.js\"></script>\r\n  </body>\r\n</html>\r\n```\r\n\r\nThis lets you write a neatly encapsulated component like:\r\n\r\ndialog-component.jade\r\n\r\n```jade\r\nblock append scripts\r\n  script(src='/dialog.js')\r\n\r\ndiv.dialog(data-dialog)\r\n  div.dialog-heading\r\n    block declare heading\r\n  div.dialog-body\r\n    block\r\n```\r\n\r\nwhich is equivalent to:\r\n\r\n```jade\r\nblock append scripts\r\n  script(src='/dialog.js')\r\n\r\ndiv.dialog(data-dialog)\r\n  div.dialog-heading\r\n    block declare heading\r\n  div.dialog-body\r\n    block declare DEFAULT\r\n```\r\n\r\nIt can be used as:\r\n\r\nchild-2.jade\r\n```jade\r\nextend ./layout.jade\r\n  h1 My Child Page\r\n  include ./component.jade\r\n    block heading\r\n      h2 My Dialog Heading\r\n    p My Content\r\n```\r\n\r\nchild-2.jade\r\n```jade\r\nextend ./layout.jade\r\n  h1 My Child Page\r\n  include ./component.jade\r\n    block heading\r\n      h2 My Dialog Heading\r\n    block DEFAULT\r\n      p My Content\r\n```\r\n\r\n```html\r\n<!DOCTYPE html>\r\n<html>\r\n  <head>\r\n    <title>My Layout</title>\r\n  </head>\r\n  <body>\r\n    <h1>My Child Page</h1>\r\n    <div data-dialog class=\"dialog\">\r\n      <div class=\"dialog-heading\">\r\n        <h2>My Dialog Heading</h2>\r\n      </div>\r\n      <div class=\"dialog-body\">\r\n        <p>My Content</p>\r\n      </div>\r\n    </div>\r\n    <script src=\"/jquery.js\"></script>\r\n    <script src=\"/dialog.js\"></script>\r\n  </body>\r\n</html>\r\n```"},"comment":{"url":"https://api.github.com/repos/jadejs/jade/issues/comments/133684319","html_url":"https://github.com/jadejs/jade/issues/2055#issuecomment-133684319","issue_url":"https://api.github.com/repos/jadejs/jade/issues/2055","id":133684319,"user":{"login":"alubbe","id":2028065,"avatar_url":"https://avatars.githubusercontent.com/u/2028065?v=3","gravatar_id":"","url":"https://api.github.com/users/alubbe","html_url":"https://github.com/alubbe","followers_url":"https://api.github.com/users/alubbe/followers","following_url":"https://api.github.com/users/alubbe/following{/other_user}","gists_url":"https://api.github.com/users/alubbe/gists{/gist_id}","starred_url":"https://api.github.com/users/alubbe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alubbe/subscriptions","organizations_url":"https://api.github.com/users/alubbe/orgs","repos_url":"https://api.github.com/users/alubbe/repos","events_url":"https://api.github.com/users/alubbe/events{/privacy}","received_events_url":"https://api.github.com/users/alubbe/received_events","type":"User","site_admin":false},"created_at":"2015-08-22T12:09:53Z","updated_at":"2015-08-22T12:09:53Z","body":"Sounds like a great way to consolidate mixins, includes and extends.\r\nWhen you say \"Block Context\", how does that interact with local JS variables?"}}