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
Feature: Make it possible to configure if admin bar loads on page load #1449
Feature: Make it possible to configure if admin bar loads on page load #1449
Conversation
Add new configuration to control if admin bar opens on page load.
After a bit of sleep I'm considering to rename |
Hey @houmark this is awesome work. The Apostrophe team had enhancement to this feature in mind and it is slightly more than what you have here, maybe you'd be willing to work it into this branch? in addition to a binary open/close state, we had planned to implement a 'only open on the homepage' mode that would be open by default and close with a timeout. I think this would fit on top of your implementation, double checking another flag and comparing it to What do you think about adding this? |
Thanks for your feedback @stuartromanek. I would, but I am not sure checking Do you have an opinion on the infinite open which would also overrule this new home page setting? |
Didn't think pathname was sufficient either.. will dig around a bit more to see if there is a better way to know you're on the homepage from the front-end. As for infinite open, it is not a core want right now but since we're going down this road I'd like to have it. It would make a lot of sense to use if a dev unfloats the admin bar and puts it back in flow as an element. |
Would applying some data attribute if the page had no ancestors work? |
@abea Yes. There's no way to pass on the current page "meta data" from the admin-bar module as it doesn't run on page load, but only on app start, so it's JavaScript only, which means some other part of Apostrophe would need to add some kind of boolean for the user.js JavaScript to look for inside the DOM. I do have a |
Add `openOnHomepage` option which defaults to true and will keep the admin bar open on the front page using the `closeDelay` (default 3000ms) value (needs improvement, see comments in PR). Renamed `stayOpenTimeout` to `closeDelay` as I think it's a better name.
I'm thinking that in |
@abea I'll take a look. @stuartromanek would it be accepted to put a data attribute on the |
This will keep the admin bar option infinitely.
adding |
I was considering to use the internal existing Adding the |
Please see latest commit. I decided to use the body class for now. I think the place I am hooking into the core is pretty much okay, but I am curious to hear feedback from @boutell on that. Open for changing this concept, but not sure how to add the block and write to it from where I am detecting level 0 in the api of Awaiting feedback, but considering this feature complete for now. |
Updated code to use "house practice". (would be great with some core guidelines and best practices documentation page when contributing — but I'm sure that's on the todo list) |
I feel like the flow should be
Not sure if the case of @Runyx @grdunn @abea can you weigh in defaults and this API? |
@@ -19,8 +19,14 @@ apos.define('apostrophe-admin-bar', { | |||
|
|||
self.enhance = function() { | |||
var $bar = $('[data-apos-admin-bar]'); | |||
var isHomepage = $('[data-apos-home]'); |
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.
prefix this var with $
to denote jQuery object
I'd also write `var isHomepage = $('[data-apos-home']).length`, so it can
actually be treated as the boolean flag its name implies.
…On Wed, Jun 27, 2018 at 10:45 AM, Stuart Romanek ***@***.***> wrote:
***@***.**** requested changes on this pull request.
------------------------------
In lib/modules/apostrophe-admin-bar/public/js/user.js
<#1449 (comment)>
:
> @@ -19,8 +19,14 @@ apos.define('apostrophe-admin-bar', {
self.enhance = function() {
var $bar = $('[data-apos-admin-bar]');
+ var isHomepage = $('[data-apos-home]');
prefix this var with $ to denote jQuery object
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1449 (review)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAB9fSuUxeF_hSMM8sg_qMXCvTlHq215ks5uA5qngaJpZM4U3iZU>
.
--
*THOMAS BOUTELL, CHIEF SOFTWARE ARCHITECT*
P'UNK AVENUE | (215) 755-1330 | punkave.com
|
Regarding defaults, are we not worried about a behavior BC break? If not, I think what @stuartromanek wrote looks good. I'm not sure I see a problem with If so, we could do:
Not as neat, but would resolve a break. It also wouldn't establish opening only on the homepage as the default. In the case |
@boutell Thanks for the hint on the templates API function. I agree on introducing a more generic core API to add this as it can be used by anything else also. I can add this API, but would you accept it as a part of this PR, or should it be its own PR? This PR would rely on the other one being added, so it would complicate testing more. |
@abea Your latest comment on default behavior is, unless I missed a detail, how it currently works and I did it like that to ensure backwards compatibility. To sum up: If you don't add anything to app.js, then it will continue to work exactly as before. But the new option So to completely disable auto opening, you add both In any case, I can make Again, if you don't change anything when upgrading Apostrophe, things will continue to work as now; admin bar opens on all pages with a delay of 3000ms before they close. I personally like it as it is right now, because it gives you the most flexibility in configuration. You can keep it closed on all subpages, but still open it on the front page, which helps new editors to understand "what this icon is all about". I even considered mixing this with user/group based settings for the logged in user, but decided to keep v1 simple (this would allow for the admin group keeping it always closed, but a normal user group always opened etc.). |
I would make it `openOnHomepageLoad` for consistency.
Like the general approach fine.
@houmark it would be fine to include the addition of that API in the PR.
Look at the addBodyClass one to see the pattern.
…On Wed, Jun 27, 2018 at 12:33 PM, houmark ***@***.***> wrote:
@abea <https://github.com/abea> Your latest comment on default behavior
is, unless I missed a detail, how it currently works and I did it like that
to ensure backwards compatibility.
*To sum up:* If you don't add anything to app.js, then it will continue
to work exactly as before. But the new option openOnHomepage is default
to true and that overwrites the behavior for the homepage only, which means
it will still open with the default 3000ms timeout, if you don't add any
setting.
So to completely disable auto opening, you add both onOnLoad: false; and openOnHomepage:
false;. This was how I understood the added homepage feature from
@stuartromanek <https://github.com/stuartromanek> but I may have gotten
his idea wrong.
In any case, I can make openOnLoad become the superseding configuration
here which means you would only need to set openOnLoad: false; to fully
disable the auto load on any page including the homepage.
Again, if you don't change anything when upgrading Apostrophe, things will
continue to work as now; admin bar opens on all pages with a delay of
3000ms before they close.
I personally like it as it is right now, because it gives you the most
flexibility in configuration. You can keep it closed on all subpages, but
still open it on the front page, which helps new editors to understand
"what this icon is all about". I even considered mixing this with
user/group based settings for the logged in user, but decided to keep v1
simple (this would allow for the admin group keeping it always closed, but
a normal user group always opened etc.).
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1449 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAB9fdll6nBuX9N2eoHcvZPrexJHGac1ks5uA7PFgaJpZM4U3iZU>
.
--
*THOMAS BOUTELL, CHIEF SOFTWARE ARCHITECT*
P'UNK AVENUE | (215) 755-1330 | punkave.com
|
Thanks @boutell, got it. This should be ready very soon. One more question. For people to be able to rely on the |
How about `data-apos-level` and it's the value of the `level` property?
That has many uses.
…On Wed, Jun 27, 2018 at 1:12 PM, houmark ***@***.***> wrote:
Thanks @boutell <https://github.com/boutell>, got it. This should be
ready very soon.
One more question. For people to be able to rely on the apos-homepage I
was considering to add a default apos-subpage which will be on all
subpages also, now that I'm at it? Would just be the else on the level
=== 0. Should I?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1449 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAB9feVod5_5S-xDTXi_b4o5_3lETfPlks5uA7z8gaJpZM4U3iZU>
.
--
*THOMAS BOUTELL, CHIEF SOFTWARE ARCHITECT*
P'UNK AVENUE | (215) 755-1330 | punkave.com
|
It could, but since this is attribute and value only, I don't see the need for an object as there's no apparent use case for adding more key/values to the object? |
Only if you also make it possible to wrap the object in an array, so that you can pass multiple attributes at once. But this makes it a bit more complex and this API function can be called multiple times if you need multiple attributes added (with my latest edition, that I am about to push). And sorry, I missed your "array of objects" here in my first read which led to my weird comments. |
This means it can only receive one attribute per call but it can be called multiple times of course.
req.data.aposBodyDataAttributes = (req.data.aposBodyDataAttributes ? (req.data.aposBodyDataAttributes + ' ') : ' ') + | ||
('data-' + _.trim(bodyAttribute)).split(' ').join(' data-'); | ||
'data-' + (!_.isUndefined(value) ? (name + '=' + value + '') : 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.
I need to also check for name
not being undefined / empty. Will push another commit for that, which will just return.
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.
Question goes. I wanted the value to be wrapped in "
(double quotes) but it's being escaped in the body tag. How do I "bless" this internally to prevent that @boutell?
Also trim to avoid rendering a broken attribute
I've done the changes requested, added some inline comments here, awaiting feedback. |
…rameter Passing an object in our first use case.
I went all in on this one and made it possible to pass an object, an array or a string (string for backwards compatibility haha, not). I hope you like that approach. |
// is attached to `req.data`, where `req.data.aposBodyDataAttributes` is built up | ||
// using `name` as the attribute name which is automatically prepended with "data-" | ||
// and the optional `value` argument | ||
// Also receives a single object or an array of objects with name and value key pairs |
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.
I think a better use for an object syntax would be an object like:
{
foo: 'value',
bar: 'other value'
}
That feels natural for adding attributes. In fact I think the array syntax could be omitted in favor of this.
return; | ||
} | ||
req.data.aposBodyDataAttributes = (req.data.aposBodyDataAttributes ? (req.data.aposBodyDataAttributes + ' ') : ' ') + | ||
'data-' + (!_.isUndefined(attribute.value) && attribute.value.toString().length > 0 ? (attribute.name + ('="' + attribute.value + '"')) : attribute.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.
Since we're using "safe" here, we need to make sure these values are actually safe. The attribute name and value should be passed through apos.utils.escapeHtml
.
Okay, so remove the array option, and key/value objects which also can be multiple and thus you can add multiple attributes in one call to the API function? Should I keep the string option to make it possible to just call the function with 3 arguments; I will also do |
@boutell forgot to mention you, please let me know so I can try to get this one right the next time :) |
Will still accept a string value for attribute name and value. Array no longer supported, but the object can be multiple key / value pairs.
I have now updated the code to accept an object of key / value based pairs. It will still accept 2 arguments (after I'm once more back to be pending on reviews. |
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.
Thank you for this PR - we are close!
@@ -19,8 +19,14 @@ apos.define('apostrophe-admin-bar', { | |||
|
|||
self.enhance = function() { | |||
var $bar = $('[data-apos-admin-bar]'); | |||
var $isHomepage = $('[data-apos-level="0"]').length; |
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.
Now that this is a simple boolean and not a jquery object anymore... which is great... the $
is no longer appropriate. Sorry for the hassle. I have a lot of PRs to look at today or I'd slip this change in myself!
// is attached to `req.data`, where `req.data.aposBodyDataAttributes` is built up | ||
// using `name` as the attribute name which is automatically prepended with "data-" | ||
// and the optional `value` argument | ||
// Also receives a single object or an array of objects with name and value key pairs |
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.
No longer quite accurate, we removed the array syntax but you're still talking about it in the doc comment.
|
||
self.addBodyDataAttribute = function(req, name, value = '') { | ||
var values = {}; | ||
if (_.isObject(name) && !_.isArray(name) && !_.isFunction(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.
You can drop all checks here other than _.isObject(name)
as the only allowed syntaxes now are the "name, value" syntax and the object syntax. Ditto the other places _.isArray()
is still around, shouldn't need to do that.
I think with my latest changes we should be good. I also merged master back into this branch and there should be no issues. |
Branch is now up to date with master. Ready to merge :) |
Thanks! |
This PR introduces two new configuration options in app.js:
Features:
openOnLoad
to false, making the admin bar stay closed on page loads. If not set defaults to true, opening the admin bar on every page load.openOnLoad
istrue
orundefined
/ not set.closeDelay
configures the time in milliseconds before the admin bar closes. If not set or set to 0, it will default back to 3000.openOnHomepage
, but still keep it closed on subpages of the site.Thoughts:
I thought about making it possible to set
closeDelay
to 0 and make it stay open infinite or until the user clicks the Apostrophe logo, but decided to not complicate the code further unless there's a want from core devs for this. In that case, let me know and I will update this PR.This needs a bit of documentation, but I am not sure how that works, I hope the above text helps adding it for whoever has access/knowledge.