-
Notifications
You must be signed in to change notification settings - Fork 598
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
Automatically provide cursor filter methods for all schema fields; also provide clean AJAX solution for pieces pages #766
Conversation
…upport for browseFilters option for apostrophe-pieces-pages; 2x speedup of typical index pages even when this is not even being used
…efore I decided that 'and' is a separate filter for easier use of 'build'
…g 'none', or arrays. For joinByArray you can also call '_catsAnd' rather than '_cats' to get an query rather than an query.
…freshes of forms without accidentally clobbering text input in progress
* `browseFilters` is now `piecesFilters`, which addresses both Alex's concern about imposing a UI and my concern about potential conflict with other meanings of the term `filters` that could apply to `apostrophe-pieces-pages` in its role as a manager of its own page type
* Made the schema filters safeFor: 'manage' by default, added `safeFilters()` convenience method to cursors, called it from `apostrophe-pieces-pages` when `piecesFilters` are in play because there's no other reason to call `indexCursor` * The option to apostrophe-pieces-pages to declare some of the filters public and load choices for them for browsing purposes is officially and finally named `piecesFilters`, I will fight you (long story)
…grated to a HOWTO but we also need to think about whether we want to kill here() macros and built all this off old-school forms that have a little bit of progressive enhancement when desired instead, because they solve certain problems better
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.
One thing to look at. Looks good otherwise!
@@ -78,6 +89,7 @@ module.exports = { | |||
|
|||
self.indexCursor = function(req) { | |||
return self.pieces.find(req, {}) | |||
.safeFilters(_.pluck(self.piecesFilters, 'name')) |
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.
FYI - looks like _.pluck()
was removed from lodash in 4.x: https://github.com/lodash/lodash/wiki/Changelog#v400
Maybe use _.map()
instead?
We use lodash 3.x. lodash 4.x is not backwards compatible.
…On Thu, Dec 1, 2016 at 9:35 AM, Brian Gantick ***@***.***> wrote:
***@***.**** commented on this pull request.
One thing to look at. Looks good otherwise!
------------------------------
In lib/modules/apostrophe-pieces-pages/index.js
<#766 (review)>
:
> @@ -78,6 +89,7 @@ module.exports = {
self.indexCursor = function(req) {
return self.pieces.find(req, {})
+ .safeFilters(_.pluck(self.piecesFilters, 'name'))
FYI - looks like _.pluck() was removed from lodash in 4.x:
https://github.com/lodash/lodash/wiki/Changelog#v400
Maybe use _.map() instead?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#766 (review)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAB9fXVkokShH2KMMZZf37-2kWlmgSEdks5rDttKgaJpZM4LAv2w>
.
--
*THOMAS BOUTELL, *SUPPORT LEAD
P'UNK AVENUE | (215) 755-1330 | punkave.com
|
_.pluck is all over a2, but if _.map actually works this way in 3.x it
wouldn't hurt to start moving in that direction.
Thanks for reviewing!
…On Thu, Dec 1, 2016 at 10:41 AM, Tom Boutell ***@***.***> wrote:
We use lodash 3.x. lodash 4.x is not backwards compatible.
On Thu, Dec 1, 2016 at 9:35 AM, Brian Gantick ***@***.***>
wrote:
> ***@***.**** commented on this pull request.
>
> One thing to look at. Looks good otherwise!
> ------------------------------
>
> In lib/modules/apostrophe-pieces-pages/index.js
> <#766 (review)>
> :
>
> > @@ -78,6 +89,7 @@ module.exports = {
>
> self.indexCursor = function(req) {
> return self.pieces.find(req, {})
> + .safeFilters(_.pluck(self.piecesFilters, 'name'))
>
> FYI - looks like _.pluck() was removed from lodash in 4.x:
> https://github.com/lodash/lodash/wiki/Changelog#v400
>
> Maybe use _.map() instead?
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <#766 (review)>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AAB9fXVkokShH2KMMZZf37-2kWlmgSEdks5rDttKgaJpZM4LAv2w>
> .
>
--
*THOMAS BOUTELL, *SUPPORT LEAD
P'UNK AVENUE | (215) 755-1330 | punkave.com
--
*THOMAS BOUTELL, *SUPPORT LEAD
P'UNK AVENUE | (215) 755-1330 | punkave.com
|
…markable/shareable URLs and correct browser history behavior. Add a `data-apos-ajax-context="name"` attribute to the outer div that should be refreshed when any link or form submission inside it takes place and has a URL that points back to the same page. Boom that's it. The `name` must be unique on the page, which is always the case for pieces index pages, but this provision is made as a starting point toward allowing multiple AJAX environments on the page for widget filters. Doing so would require considerable thought toward using nonconflicting query parameters and passing others on. It may never turn out to be a wise idea, we just don't want to slam the door on it. * Text fields and textareas in the AJAX context are *not* replaced, so that submitting the form on keyboard events does not result in broken input behavior. Their ancestors are also not replaced. * Implemented new slug-based join filters. The slug-based versions do *not* take the leading `_` in their names, which is perfect because they are seen by the public in query strings. Programmers will expect the versions with the `_` and pass ids to them and get what they expect. Nerdvana. * Unit tests for the slug-based join filters. * Fixed a bug in the `refinalize` feature of cursors. state.criteria is now cloned before finalize and restored after it. Otherwise many criteria are added twice after refinalize which causes a fatal error with a few, like text search in mongodb. * Refactored and cleaned up my code for generating join filter choices to be clearer and less redundant.
Whoah. |
I had a very productive holiday.
…On Thu, Dec 1, 2016 at 4:42 PM, Alex Gilbert ***@***.***> wrote:
Whoah.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#766 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAB9fdX9jLOUIFXJl7v3MO5Uk3x0B-1pks5rDz9jgaJpZM4LAv2w>
.
--
*THOMAS BOUTELL, *SUPPORT LEAD
P'UNK AVENUE | (215) 755-1330 | punkave.com
|
All tests passing. * Two major new features in this release: built-in filters for most schema fields, and built-in AJAX support for `apostrophe-pieces-pages`. These combine to eliminate the need for custom code in a wide array of situations where you wish to allow users to browse and filter blog posts, events, etc. In most cases there is no longer any need to write your own `cursor.js` or your own AJAX implementation. The provided AJAX implementation handles browser history operations, bookmarking and sharing properly and is SEO-friendly. [See the official summary of the pull request for details and examples of usage.](#766) * We also fixed a bug in the `refinalize` feature of cursors. state.criteria is now cloned before finalize and restored after it. Otherwise many criteria are added twice after refinalize which causes a fatal error with a few, like text search in mongodb. In addition, we merged a contribution from Fotis Paraskevopoulos that allows a `bodyParser` option with `json` and `urlencoded` properties to be passed to the `apostrophe-express` module. Those properties are passed on to configure those two body parser middleware functions.
FILTERS
Most schema field types now automatically get cursor filter methods by the same name. This allows you to write, for instance:
... To retrieve only people who are joined with departments (such a join must exist in the schema for people).
For joins you actually get several filters:
departments
: expects slugs. Singular, or an array. Notice the lack of an_
makes this suitable for the public to see in a query string, and it also expects a slug which is what you expect in a query string (hostile URLs aren't cool)._departments
: expects ids. Singular, or an array. Notice the_
is what our devs already expect with a join and it takes ids, which are what devs usually prefer to pass (they never change).departmentsAnd
: likedepartments
, but if you pass an array of slugs, they ALL must appear. With regulardepartments
, if you pass an array, it's good enough if ANY appear. (The latter is the more common case and usually better UX, so it gets the default name.)_departmentsAnd
: likedepartmentsAnd
, but taking IDs.All of these filters have a
launder
method but are by default markedsafeFor: "manage"
because it's not cool to assume it's safe to let people discover stuff about your data. However there is a newsafeFilters
method of cursors which can be used to conveniently mark an array of filter names assafeFor: "public"
.On the front end,
apostrophe-pieces-pages
now leverages this to implement the newpiecesFilters
option. An example from a client project:This automatically populates
req.data.piecesFilters.system
with an array of choices to select a biological system (via a joinByOne),req.data.piecesFilters.year
with an array of choices for years, etc.Note that the join field in the schema is actually named
_system
; as mentioned above, the filter without the underscore expects slugs, and provides slugs as values for choices.The choices are objects in our standard "label and value properties" format.
The choices are case-insensitively sorted.
This eliminates the need for any custom code for pieces and pieces-pages in many common cases.
This is all unit tested.
PRESENT LIMITATIONS:
More capabilities are coming such as specifying that you want autocomplete rather than an array of choices, which could in some cases be too much of a performance hit. The configuration format is designed to accommodate more properties to cover this.
There is no support for filtering on reverse joins yet. There are significant issues there, but we should dig into it.
AJAX
Implemented a general-purpose, extremely easy solution for AJAX filtering with bookmarkable/shareable URLs and correct browser history behavior. Add a
data-apos-ajax-context="name"
attribute to the outer div that should be refreshed when any link or form submission inside it takes place and has a URL that points back to the same page. Boom that's it. Combine this with the filters features above and you can do remarkable things with zero code.(The
name
of the context must be unique on the page, which is always the case for pieces index pages. We're not committing to implementing support for multiple filterable widgets on one page with bookmarkable URLs across all of them, but we're not slamming the door either.)OTHER
refinalize
feature of cursors. state.criteria is now cloned before finalize and restored after it. Otherwise many criteria are added twice after refinalize which causes a fatal error with a few, like text search in mongodb. This was needed to get the slug filters working right.