zurb / front-router

Generate AngularJS states from Front Matter in state templates. Used by Foundation for Apps.
MIT License
8 stars 3 forks source link

Adding custom data to front router #1

Open Dillie-O opened 9 years ago

Dillie-O commented 9 years ago

When Z4A was using front-matter, I was able to achieve a nifty effect of dynamically updating my page titles in a shared header section. Here's how it worked:

In my page templates, I had the following front-matter definition:


---
name: AddPrayer
url: /prayers/add
controller: PrayersController
data:
    title: Add Prayer

---

Armed with this data, I used a route changing trick in the run function to pull this data and update things accordingly:

function run($rootScope) {
    FastClick.attach(document.body);

$rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
    $rootScope.title = current.$$route.data.vars.data.title;
});

$rootScope.$on('$stateChangeStart',
    function (event, toState, toParams, fromState, fromParams) {
        $rootScope.title = toState.data.vars.data.title;
});
}

This was made possible due to what front-matter provided. You probably know more about angular than I do, but we have to register both of those events (routeChange and stateChage) so that you can track either when a view is directly loaded (page link or refresh) vs an action through the app. Granted rootScope has it's own concerns, but hey, it was cool. I was also using this to update metadata stuff in the head of the page.

It would be nice if we could add something like this to front-router I'm sure there is additional use cases for custom data, and this doesn't seem too hard to work with, at least in my mind.

Let me know your thoughts.

Thanks for all you hard work!

Dillie-O commented 9 years ago

I was looking into this a bit more, and I think my original issue was buggy.

I was digging through some routing issues, pulled up the debugger, and noticed that custom data was available. It was just the reference point that is different now. In the above events, you can access the data accordingly:

$routeChangeSuccess - $$route.data.title

$stateChangeStart - toState.data.title

I'm not sure if this was an angular routing update or what, but now you can access the custom data without having to dig down into "data.vars.data" they are now first class citizens.

It might be worth adding that to documentation. Sorry for the hassle.

gakimball commented 9 years ago

Yeah, we had some functionality for adding custom data through the Yaml, but we didn't document it because we weren't sure if people would find it useful.

Actually, any data you add in that Front Matter block can be accessed through the state's parameters. We do this in our documentation, adding a title to each page:

url: /modal
name: modal
title: Modal

And then binding it to the <title> element:

<title ng-bind="$state.current.data.vars.title"></title>

Is updating a page title your main use case for it, or do you have other things you think it would be useful? And would you use it more when prototyping, or in production also?

Dillie-O commented 9 years ago

For myself I can see it in production as well. Now this could be a classic case of "you're doing it wrong" but when I built out my mobile layout, I have the view title in the main bar of the page to assist the user (the title in the actual view screen will be getting phased out)

https://www.evernote.com/l/ACI57hwVi-RNpZxasLyXODc4FkBO4mBcj5o https://www.evernote.com/l/ACLoXo0nzEBEc7R2z5wGpS0pSPF5gekoAn0

Since that area is part of the main index template, I needed some "root scope" level data needed to be pushed. Since I already have an event firing when the view changes, I wanted to link things in to that code, and store it in a place where I didn't have to think about when to call a method to update the title in the controller, so I put it in the front matter. I also thought this might help fix the issue of trying to share my views on G+ / FB / Twitter where they scrape the page, but that isn't working and I'll have to look into some of the more traditional means to make that happen.

Does that help at all?

gakimball commented 9 years ago

Yeah, it seems like page-level metadata is a totally sensible use of custom YML attributes. I think when we originally put this idea together, we assumed people would just be stuffing big arrays of data in the YML to prototype list views and so on. But it also works really well for simple things, like setting the title of the page.

So to get back to the original issue, we can definitely add documentation for this. But is there anything we can do to make the feature easier to use?

Dillie-O commented 9 years ago

I can see two options...

1 - Just let the YAML read anything and treat things that aren't reserved words as custom variable names. That means that they easily show up in $state.current.data.XXX

2 - Have an extra field called "custom" or something like that which will be the array for the custom data we want to put there. That might be a little nicer since it conforms to existing front-matter layouts, and I don't mind having to go "one level" deeper to access my custom data.

I think that would make it simple to access and work with. Thoughts?