Jump to content

Status Unpublished and $pages->get()


Gazley
 Share

Recommended Posts

Hi there,

I really want the status of the album-category page to be 'unpublished' but if I do that, the following doesn't work:

$pages->get('/album-category/')->children

Is this the expected behaviour?

Thanks.

Link to comment
Share on other sites

Hmm.. I don't actually know whether get should "get" the unpublished page or not. I guess not, since that is not published - so it doesn't exist. I have never had that kind of need myself. Why you need it unpublished? If it is purely "metadata" then just keep it hidden and don't create template file - then it throws 404 if accessed directly.

Link to comment
Share on other sites

If you want it show up in get() / find() operations then you want it to be published. Unpublished is not suitable then - it means something that is not ready yet, work in progress, draft... PW 2.0 didn't even have unpublished status, so you can go without easily and it's more for content adding phase for editors than for site building.

I think what you want is just hidden for the parent page, something like this:

/category/ (hidden)

/topic/

/another_topic/

Link to comment
Share on other sites

WEll it was when I coudn't help to make page sunpublished already on running site that needed approval before going live. Could have done it differently but I just tried intuitively and it just worked... with a little smile.

  • Like 1
Link to comment
Share on other sites

Thanks guys - "hidden" is exactly what I want!?

I took the following statement literally - "

Hidden: Excluded from lists and searches"

It most certainly shows up in queries which I took for "searches". In that case, I wonder what kind of lists and searches are not based on queries?

Link to comment
Share on other sites

Hidden pages are excluded from all queries that return multiple pages. Things like find(), children() etc.. But since get() returns only single page it is assumed that you really want what you are looking for. So hidden pages are returned in get(), but not in finds (unless you explicitly say include=hidden).

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Hello, I have an odd behaviour going on with unpublished pages on the backend admin :

Let's consider a page (PageA) whose template has a Page field (FieldA).

PageA status is published.

FieldA input field type is "PageListSelect".

The backend interface allows to add an unpublished page (PageB) to FieldA, then save PageA.

However, once this is done, after refresh, FieldA is still displayed as empty, without the newly assigned PageB.

Moreover, if this field is set as "required", then PW refuses to update-resave the page.

As soon as you publish PageB, then it reappears in FieldA, and PageA can be updated-resaved.

Note that if FieldA input field type is set to "Select" instead of ""PageListSelect", then the unpublished PageB is no more available for being assigned to FieldA.

There is something non consistent going on.

I suppose the expected behavior is to allow the addition of unpublished pages, then display them once added even though they are unpublished, and not complaining about missing required field ?

Link to comment
Share on other sites

Page references aren't designed to contain unpublished pages. Granted, you can trick them into doing it, because the referencing page doesn't necessarily have control over the state of the page being referenced… a published page can become unpublished, among other situations. Likewise you saw that an unpublished page reference can be stored (if the input will let you select it), but unpublished pages get ignored when a field is loaded/presented. The only reason you can add unpublished pages at all is purely for the API. But now I'm wondering if that's more confusion than utility. Maybe I should just prevent unpublished pages from being stored at all--will have to think about this more.

When using a PageListSelect input and you see a page with a line through it like this that means it's unpublished and you shouldn't select it. As far as I know, this is the only input that will let you select an unpublished page. It's only selectable so that you can access children, should it have any. I may be able to find a way to enforce this further, but PageList has to do a lot of things so I'm a little shy about going beyond visual indicators for this one. I'm more inclined to modify the behavior of Page references to just refuse unpublished pages completely. Thanks for your feedback--I'll experiment a bit more here.

  • Like 1
Link to comment
Share on other sites

Thanks for your explanation.

From a backend workflow usage perspective, my objective is to keep new pages unpublished while I work on them, then publish everything at once by lazy-cron, based on a "publish_date" Date field. This includes unpublished pages which are PageFields of other unpublished pages.

My lazy-cron code is working fine for this.

But given what you describe, such a workflow should not be used, because I shouldn't be able to have unpublished PageFields within (unpublished) Pages.

What shoud I do ? Use "hidden" status instead of unpublished ? (I didn't look "hidden" status in depth so far)

Link to comment
Share on other sites

I think in your case the best bet probably is to use the 'hidden' status, or to add your own checkbox field specific to this need. Ultimately we don't allow unpublished pages in page references because: unless you are superuser, you aren't going to see unpublished pages that you don't have access to edit. So it would violate the security model a bit if users could see or add unpublished pages. If only superusers could do it, then another editor (non-superuser) could potentially break the selection simply by saving the page. While I think there are some potential nice things about being able to add unpublished pages to page references, in the big picture, I think we're better off avoiding it.

Link to comment
Share on other sites

So far I didn’t look into the roles security model, my security model is more basic, with myself as the superuser on one side, and Internet end-users on the other side :)

By the way, with current version 2.2.9, even tough I’m superuser, I can assign an unpublished page to a PageField, but then it is not displayed as being assigned.

Logically, I was presuming that on the backend side (ie. roles > guest), a status of published vs unpublished would have no impact in terms of who has the permission to do what -> ok it seems I was wrong.

Notwithstanding backend issues, one of the main purposes of the unpublished status is that pages are… unpublished, so they can’t be accessed at their URL by the “anonymous” end-users, nor with pages->find, $pages->get, ...

This is something the hidden status doesn’t provide : you mentioned it in previous posts, and I just verified, that a hidden page can still be accessed by its URL, and by $pages->get. So using hidden instead of unpublished doesn’t sound good to me, for obvious security/disclosure reasons. Same goes for using a checkbox : ok, but is there a solution for preventing end-users access to these pages, equivalent to unpublished ? Maybe performing a test (eg. if($page->viewable()) ) everywhere in the code before displaying anything? I don’t know why I’m not a big fan of this approach… which would mean reimplementing “unpublished” feature by hand.

Well, in my case I can cope with a workflow where I first publish the pages (which happen to be less sensitive) which are going to be referenced inside unpublished pages (which are more sensitive), so I’ll do this way.

But I think it’s a worthwhile discussion :)

Ok, I add to my TODO list “learn more about Processwire RBAC model” :)

Update : I’ve just read the RBAC model API introduction, and I think I have another option :

The Work-In-Progress stuff could take place in a /WIP directory tree, which would have no guest access.

From my lazy-cron, when publish_date field is met for pages in /WIP, then move the relevant pages from /WIP to the relevant locations in /Live-Content, which is the main tree with guest access.

In order to be automated inside a lazon-cron, it's more complex and more rigid than just switching a status flag, but I suppose it should work.

Still, it would be great if “unpublished” status behaviour could be made more convenient and useful, as per my arguments ;)

  • Like 1
Link to comment
Share on other sites

If we could assume just a superuser environment, then we could narrow the scope and make it more convenient for that specific scenario. But since we are a multi-user, multi-access environment, we can't make those assumptions.

Like you correctly noted, using 'hidden' would only be a good idea if you were dealing with non-sensitive stuff. And of course, 'hidden' isn't specifically meant for this purpose in the first place.

Using access control with your WIP tree is a good way to go.

It would also not be much of a stretch to implement your own unpublished feature to work however you want it. You would add a checkbox to your template called something like 'toggle_unpublished'. Then in your head.inc or whatever initial/common template your site uses, you would just check for that first:

if($page->toggle_unpublished && !$page->editable()) throw new Wire404Exception();

Combine that with the hidden status (to keep it out of navigation), and I think you'd have exactly what you need.

If you didn't want to have to bother at all with the hidden status, then you could update your find() or children() selectors to include "toggle_unpublished!=1". Or if you didn't want to even bother with that, you could make a hook function to do it for you (at the top of your head.inc, before output has started):

$pages->addHookBefore('find', null, 'hookPagesFind'); 
hookPagesFind(HookEvent $event) {
 $event->setArgument(0, $event->arguments[0] . ", toggle_unpublished!=1"); 
}

All page get/find/children/siblings/etc. calls get routed through $pages->find, so you wouldn't need more than this 1 hook.

Link to comment
Share on other sites

while I'm not fond of the head.inc + hidden status (because for instance I have a page which does heavy use of find() on potentially unpublished pages, so the display of this page would still get unwanted data),

the last 2 options seem very good and straightforward, with the last one being particularly impressive, thank you very much !

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...