Jump to content

Setting the page status 'unpublished' at runtime


Dani
 Share

Recommended Posts

Hi all,

I'm trying to unpublish a page at runtime, depending on the value of a page field. I tried to do it like this in the file ready.php:

if ($this->page->hasField("showPageIn") && $this->page->showPageIn->has("title=Dev")) {
    $this->page->addStatus(Page::statusUnpublished);
}

However, it doesn't quite have the intended effect. When I render the page in the frontend, I get an error:

Exception: Page '[my url]' is not currently viewable. (in /home/me/public_html/wire/modules/PageRender.module line 388)"

I'd like the page to behave like a page whose "published" flag in the settings is unchecked. Any help/solution is highly appreciated. Thanks!

 

Link to comment
Share on other sites

38 minutes ago, Dani said:

I'm trying to unpublish a page at runtime, depending on the value of a page field.

What's the intention? Your 'title=Dev' suggests to me that you do not want the page to be viewable by non Devs? non-superusers? Why not just leave the page unpublished then? You (the superuser) will be able to view it, others won't. Alternatively, you can use permissions and/or roles. If the current user doesn't have the permission, PW won't allow them to see the page.

Link to comment
Share on other sites

Hi kongondo

Thanks for replying. The intention is the following. Apart from my production site (www.mysite.com), I have set up a development (dev) site to try out new things. I have a copy of the site/templates folder (site/templates-dev), where I change templates (layouts, CSS etc.) and which I access through a subdomain (dev.mysite.com) by changing the corresponding variables in the config file.

I would now like to also create new pages that do not yet show in my production site, but do show and behave in my dev site like all other pages. In particular, these dev pages should also show up in the site menu. My idea is to have a page field, which determines if the page shows in the production and/or in the dev site. To show in the menu, e.g., such a dev page must be published - but nevertheless should not show in the production site.

I hope I made myself understood. There might be other approaches that do the trick. I'm happy to hear ^_^

Link to comment
Share on other sites

42 minutes ago, Dani said:

I would now like to also create new pages that do not yet show in my production site,

I assume you mean do not show in the frontend (via search or in menus) but do show in the backend pages tree, right?

If my assumption above is correct, then keeping them unpublished in the live/production site should do the trick without the need for the page field check. This supposes that in the production site, no other user apart from you the supersuser has the permission to publish those pages.

Menu in the production site (www.mysite.com):

$items = $pages->find('template=some-template');// this will not return unpublished pages
// generate menu
foreach($items as $item) {
// simple menu here
}

Menu in the dev site (dev.mysite.com):

$items = $pages->find('template=some-template, include=all');// this will return unpublished and hidden pages
// generate menu
foreach($items as $item) {
// simple menu here
}

You can of course add other checks, e.g. if your new pages share a template or parent, you can exclude them from your menus by checking if the current user is you (superuser), etc.

Wouldn't the above work or I'm still missing the point?

Edit:

Yes, there are other techniques to viewing different templates/styles depending on whose viewing the site. I can't find the relevant threads in the forums at the moment.

Edited by kongondo
Link to comment
Share on other sites

1 hour ago, kongondo said:

I forgot to ask, is this your personal requirement?

Yes, personal in the sense that I am webmaster and want to see the effects of new developments (changes in the layouts, new pages etc.). It's not the requirement of a customer.

Regarding your question

Quote

I assume you mean do not show in the frontend (via search or in menus) but do show in the backend pages tree, right?

Yes. The idea is that on dev.mysite.com anyone (i.e., also guests) can see the changes. One doesn't have to be logged in to see the changes. I know it's kind of a "risk" because such a dev site would be more or less public (if one knows the subdomain - security by obscurity if you like).

By "menu" I meant the front-end menu, which I generate automatically by Soma's Markup Simple Navigation module, i.e., I don't assembly it "manually" on my own. That's one of the reasons I want those dev pages to behave like normal pages on the dev site.

Link to comment
Share on other sites

1 hour ago, Dani said:

Markup Simple Navigation module, i.e., I don't assembly it "manually" on my own. That's one of the reasons I want those dev pages to behave like normal pages on the dev site.

I see. FWIW, MSN can take a PageArray and build a menu off of that. However, they will be first level entries only. 

I am out of ideas, sorry :-).

Link to comment
Share on other sites

8 hours ago, theo said:

I think the easiest would be to change the way the navigation is created, so that you can filter out the pages with a "dev" tag for the production site.

Well, in my opinion, this would just be a workaround for my original requirement. As I said initially, my ideal solution would be to set the status of a page at runtime (e.g., in the ready.php file or with a hook at the right place) and that the page thereafter behaves as if it had had that status from the beginning of the request.

But maybe this idea contradicts some general principles of ProcessWire. Maybe the status of a page is supposed to be persistent in the DB and shouldn't be changed at runtime. But then, why do we have methods like 

$page->addStatus(Page::statusUnpublished);

at all? Maybe someone can clarify the purpose of such methods. I am happy to learn ^_^

Link to comment
Share on other sites

34 minutes ago, Dani said:

But then, why do we have methods like 


$page->addStatus(Page::statusUnpublished);

at all? Maybe someone can clarify the purpose of such methods. I am happy to learn ^_^

How else would we change the status of a page via the API then :)? We use these methods and save the page to commit to the database.

Link to comment
Share on other sites

Just had a thought. What is the use of the new pages in the live/production site if they are not meant to be seen until they are ready? Are editors updating them with content? If they are not getting updated on the production site, maybe you can just create them on the dev site then when you are ready for them to go live, use the API of either multi-instance or page export/import to re-create and pre-populate (basically mirror) these pages in the production site?

Just a thought...

Link to comment
Share on other sites

First of all, I greatly appreciate your help. Thx!

Note that I am running a multi-site setup (using Soma's / Apeisa's Multisite module), not a multi-instance setup. There are two sites (dev and production). So all pages live in the same PW instance. For that reason I intend to flag certain pages as "dev only" to see how they would look like in the context of the rest (i.e., on the dev site together with all the pages in production) while they are not quite ready yet. Such pages might not be ready yet because the still need some content to be worked out, or I try out new layouts, styles etc.

Link to comment
Share on other sites

Aah, I see. I don't know how that module works so I can't comment further. Hopefully others will chime in. I'm still curious though whether Page status can be made to work in runtime context only. Please let us know if you come up with a solution :).

Link to comment
Share on other sites

If it were me I would be hesitant to do any significant development on a live website. Better I think to copy the site locally or to a separate testing account.

But I think it should be possible to achieve what you want. As I understand it you have two objectives:

1. Prevent certain pages appearing a menu generated by MarkupSimpleNavigation.
2. Prevent certain pages from being viewed.

For MSN you can conditionally set the selector according to whether the dev site is being viewed. Not sure what test you are using for that, but for MSN you would do something like this:

$selector = ''; // Whatever your default selector is for the menu
// Set $is_dev according to your test
if(!$is_dev) $selector .= ", !showPageIn.title='Dev'";
// Now use $selector in your MSN options array

Then to prevent viewing of dev pages (in case a visitor stumbled upon the URL of a dev page), in /site/ready.php:

$wire->addHookBefore('Page::render', function(HookEvent $event) {
    $page = $event->object;
    // Set $is_dev according to your test
    if(!$is_dev && $page->showPageIn->has("title=Dev")) throw new Wire404Exception();
});

 

  • Like 2
Link to comment
Share on other sites

Hi Robin S

Thanks for joining in ^_^ This sounds like a promising approach, although it still looks to me like a work-around - I'd really like to have a solution where at a single point in my code I hook in and unpublish a page at runtime. But I'll definitely try your suggestion out.

Maybe I'm just too optimistic and/or don't understand some PW principles which would prove my idea absurd...

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...