Skip to content

Commit

Permalink
docs(middleware): Added missing router methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefan Walther authored and Stefan Walther committed Jun 6, 2016
1 parent 1a096ba commit 48665ac
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions docs/src/content/api/middleware.md
Expand Up @@ -123,14 +123,18 @@ Router methods are similar to the router METHODS in [express][], but instead of
**Summary**

- `onLoad`: Immediately after a view is loaded, as a last step just before adding the view to a collection.
- `onStream`:
- `preRender`: Called before rendering a view.
- `preCompile`: Called before compiling a view.
- `preLayout`: Immediately before the first [layout][] in a [layout-stack][] is applied to a view.
- `postCompile`: Called after compiling a view.
- `postRender`: Called after rendering a view.
- `preWrite`:
- `postWrite`:

- `onLayout`: Called after each [layout][] in a [layout-stack][] is applied.
- `postLayout`: Called after all [layouts][] have been applied to a view.
- `onMerge`: Called directly before [partials][] collections are merged onto the [context][].
- `preCompile`: Called before compiling a view.
- `postCompile`: Called after compiling a view.
- `preRender`: Called before rendering a view.
- `postRender`: Called after rendering a view.


## Methods
Expand Down

13 comments on commit 48665ac

@stefanwalther
Copy link
Contributor

@stefanwalther stefanwalther commented on 48665ac Jun 6, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jonschlinkert: sorry, pushed immediately ... wasn't my intention.
But to my point:

  • I have added some missing events and brought them into the right order
  • While doing that I realized, that some events are currently not working:
    • onLoad
    • onStream
    • onLayout
    • postLayout
    • onMerge

See here for a working test to reproduce: https://github.com/assemble/assemble-recipes/blob/master/recipes/middleware/index.spec.js#L59

@jonschlinkert
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no problem, thanks. I'll take a look.

@jonschlinkert
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stefanwalther, think of a middleware function as being similar to an event listener. Middleware is registered using a router method (like .onLoad) and handled by a corresponding .handler. So, for the .onLoad middleware to be handled, a view must be loaded onto a collection. For the .preRender middleware to be handled, a view must be rendered.

This is because we call the .onLoad handler when a view is loaded onto a collection, and we call the .preRender and .postRender handlers (and others) when a view enters and leaves the render cycle.

Think of it this way. Similar to events, with middleware, instead of calling .emit we call .handle, and instead of listening with .on we use a router method that matches the name of the handler we intend to call (such as .onLoad, preRender, and so on). Assemble does most of this internally for you. But it's completely customizable.

Events vs Middleware

For example, this is what a typical event might look like.

// when the `foo` event is fired...
app.on('foo', function(view) {
  // ...do stuff to view 
});

var view = new app.View('foo', {
  content: 'this is a collection-less view'
})

// we need to fire a `foo` event for the `.on` listener to "hear" something
app.emit('foo', view);

Like events, middleware handlers are completely customizable, so you could create handler called .onFoo if you wanted. Unlike events, when a custom handler is created, a (router) method is actually created on the instance.

Additionally:

  • Event emitters can emit any arguments, and listeners will receieve them. But middleware only takes view and next as arguments
  • Event emitters do not discriminate which listeners will hear what is emitted. When foo is emitted, all foo listeners will hear the event. With routes, we can control which middleware functions will be called by specifying a route path, which is a regex or string that is passed to a router method.

Example

// create a custom middleware handler, which will add 
// an `.onFoo` method to the instance
app.handler('onFoo');

// middleware function
function doStuff(view, next) {
  // do stuff to view
  next();
}

// add middleware with our custom method
app.onFoo(/foo/, doStuff);
app.onFoo(/bar/, doStuff);

// handle all `.onFoo` middleware (like firing an event)
app.handle('onFoo', function(err, view) {
  if (err) return console.log(err);
  // do stuff to view or finish
});

I'll add this to the docs somewhere. let me know if this makes sense or if you have any questions

@stefanwalther
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx, very helpful, but I think/hope not that far away how I understood it ;-)
I really hope you save all these extensive answers for the docs later on ...

Thx!!!

@jonschlinkert
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think/hope not that far away how I understood it ;-)

Great, I was just making sure since you said the events (middleware I think you meant) weren't working, but your tests aren't doing anything to trigger them.

@stefanwalther
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, got that, thx again!

@jonschlinkert
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stefanwalther, @doowb or I will do a pr to the recipes soon with some changes. We'll need to reformat how some of the tests are done to ensure that state is not shared across tests, and to make it more clear configuration is done. It took me a while to figure out that there was configuration outside of the tests that was effecting behavior in the tests. also I'd like to make the formatting more consistent with the format we use for the rest of our examples and docs. In general though, the recipes are awesome, and the documentation itself is impressive.

@stefanwalther
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jonschlinkert, again, I can just state, that I am more than willing to help. Right now there are still a lot of moving pieces or sometimes I don't get the full picture; but I also don't want to disturb you too much; makes more sense if you can concentrate on development work.
I still very much like the idea of having integration tests, so what I have actually tried to achieve a bit in assemble-recipies. It allows you to run the tests against a new version and you can be sure that everything still works fine.

Just tell me, how I can help best ...

@jonschlinkert
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still very much like the idea of having integration tests

agreed, I think what you're doing is great. I don't want you to change the general approach - all we need is some comments or something to let the user know what's happening here.

I also prefer having more detailed descriptions in the it and describe statements, so that others know what you're trying to achieve (and I try to keep in mind that newcomers are looking at the code. fwiw, that's how I learned how to program, by reading clear unit tests and code comments).

@jonschlinkert
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stefanwalther would you like to do a call/screenshare with @doowb and I some time? so we can discuss roadmap and show you what we're working on?

@stefanwalther
Copy link
Contributor

@stefanwalther stefanwalther commented on 48665ac Jun 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that would be great! Where are you located? US? I am based in the Munich area/Germany, so CET, most of the time in the evening it's just fine. Are you using Skype, is so we could arrange a meeting there, my handle: stefanwalther.qliktech

@jonschlinkert
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, I'm in the U.S. EST. how is tomorrow or Thursday? Instead of Skype, have you ever tried screenhero? It will allow me to share my screen and give you control. We can send you an invite before the call.

@stefanwalther
Copy link
Contributor

@stefanwalther stefanwalther commented on 48665ac Jun 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes screenhero or skype, webex or whatever, all fine for me ... any channel like Skype where we can continue this discussion, don't want this to be public ;-)

Please sign in to comment.