Jump to content

How to override 404 for unpublished pages


alexcapes
 Share

Recommended Posts

Hi,

I have a custom built module that auto-generates a number of pages (translations) on creation of a master page (English version) and saves them as subpages of their respective languages.

Home

- Articles (English)

-- Article title

- French

-- Articles

--- Article title (unpublished)

- German

-- Articles

--- Article title (unpublished)

etc

The pages that are created are unpublished and I'd like if possible to be able to pull content for the English version until a translated version is published. Sometimes no translated version will be available so the English content is seen as a 'fallback' here.

Currently to a logged out user trying to view an unpublished translation page will see a 404.

Could there be a a way to override this behaviour? I'd only want it to be limited to the translations, so template or parent specific.

Extra info...

  • Every translated version has a pagefield storing the master English version, so that info is available for pulling out into a template or module.
  • Each article and it's translations have the same name but is / a country code, such as /fr/ or /de/ etc

Any help much appreciated!

  • Like 1
Link to comment
Share on other sites

Something like this 

// in modules init()
$this->addHookBefore('ProcessPageView::pageNotFound', $this, 'redirectToEnglish');

public function redirectToEnglish($event){
  if($this->page instanceof Page && $this->page->is("template.name^=article_")){
    $this->session->redirect($this->page->pageField->url);
  }
}
  • Like 1
Link to comment
Share on other sites

Something like this 

// in modules init()
$this->addHookBefore('ProcessPageView::pageNotFound', $this, 'redirectToEnglish');

public function redirectToEnglish($event){
  if($this->page instanceof Page && $this->page->is("template.name^=article_")){
    $this->session->redirect($page->pageField->url);
  }
}

Rather than a redirect, ideally I'd be able to render the page using the English content. So for example the template file would have checks in whether it was unpublished and if so, grab title, body etc from $page->related_language_page->title, $page->related_language_page->body etc.

A return return $Page->render();  would do I guess unless you want a redirect of cause.

More info: https://github.com/ryancramerdesign/ProcessWire/blob/dev/wire/modules/Process/ProcessPageView.module#L582

Would you mind explaining this a little further? Ideally not wanting to do a plain redirect to the English page but just be able to render the page and maybe just do conditionals in the template file.

Link to comment
Share on other sites

A return return $aPage->render();  would do I guess unless you want a redirect of cause.

More info: https://github.com/ryancramerdesign/ProcessWire/blob/dev/wire/modules/Process/ProcessPageView.module#L582

$this->addHookBefore('ProcessPageView::pageNotFound', $this, 'overrideError');	

public function overrideError($event){

	  if($this->page instanceof Page && $this->page->is("template.name*=article")){
			return $this->$page->render();
	  }
	}

This ^ is what I have so far but doesn't seem to be changing anything and is still throwing a 404 unpublished pages.

Link to comment
Share on other sites

I'm trying here, but so far no luck. (Returns empty page)

Sorry...

Only LostKobrakai's redirect seems to work. 

Yeah same here too. This is the redirect code that works...

		public function init() {
		$this->addHookBefore('ProcessPageView::pageNotFound', $this, 'overrideError');
	}

public function overrideError($event){
		$page = $event->arguments[0];

		if($page instanceof Page && $page->is("template.name^=article_")){
		$this->session->redirect($page->related_page_language->url);
	}
	}

This is workable I reckon but the ideal solution would be to able to render the contents of the English version within the page.

Going to keep plugging away to see if I can come up with something that works.

.

Link to comment
Share on other sites

	public function init() {
		$this->addHookBefore('ProcessPageView::pageNotFound', $this, 'overrideError');

	}

	public function overrideError($event){
		$page = $event->arguments[0];

		if($page instanceof Page && $page->is("template.name^=article_")){
			return $page->render();
		}
	}

This gives me an error: Fatal error: Exception: Page '...' is not currently viewable.

Which I can see why, it's trying to render a page that unpublished, so it correctly spits out the error.

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.

  • Similar Content

    • By jploch
      Hey folks,
      currently Iam working on a website for one of my clients and I need some advice on how to approach this in PW.
      The website is for a company, that offers holiday houses in two locations. 

      The client wants the homepage to show the first location. Normally I just have a home template for the first page, but here the URL should reflect that you are in Location 1. So when you visit the URL casamani.com it should redirect to casamani.com/location-1. Not sure if this makes sense at all.

      Whould it be bad for SEO and performance reasons to redirect home to the Location-1 page?
      Another approach would be to render the Location-1 template on the home template or do an include like discussed here.
      Here is how the tree looks:
      – Home
      – Location 1 (Homepage)
           – Creation
           – Adventure
           – Sustainability
      – Location 2 
           – Creation
           – Adventure
           – Sustainability

      Thanks for looking into this!
    • By theoretic
      Hi guys and ladies! And thanks for Processwire!
      It appears i've got an interesting issue concerning the template-settings-based PW redirects dealing with access control. Any PW template has some access control options i.e. "Login redirect URL or page ID to render". If this option is used for a page having a template with this option filled, a redirect will occur if user is not logged in and/or has insufficient access rights.
      I like to hook PW events. In one of my current projects i decided to write an addHookBefore('Session::redirect', ...) which should store the page we are being redirected from. With "regular" redirects like $session->redirect('/somewhere/') this hook works like a charm. But it was strange to see that it doesn't work with the template-settings-based redirect.
      I'm too dumb to dive deep inside PW and to examine the whole PW session mechanism. But it could be rather logical if ANY redirect ( no matter template-settings-based or using $session->redirect() ) could be hooked in the same manner.
      Okay okay i can forget about template-settings-based redirect and write my own. Just a couple of lines of code, and it works. But it's less elegant than hooking the template-settings-based redirects.
      So am i missing something? It this behavior a bug, or is it intended by PW team? Thanks in advance for any comment!
    • By JeevanisM
      HI,
      The scenario is,  I manage a magazine website, I have an article to publish, but before making it public available, I have to show the preview to my Editor and get approval. What I have done is, I created the page, filled the contents then put it as a Unpublished status. I as admin can see the preview of the page but when I send this page link to the editor ( he has no admin access, he should not because the person may vary with each articles ) , the editor cannot view the preview of Unpublished page. Is there any workaround on this ?  Is it possible to make this preview page watchable with a direct link ?


      thanks
    • By snck
      Hey there,
      for a client website I need to implement a "reviewer" role. "Reviewers" should be able to review new (unpublished) articles to give feedback to editors, but not have the permission to change them. 
      I built a new "reviewer" role that only has page-view permissions for the respective templates, but this permission does not include viewing unpublished pages. How can I grant them access to the unpublished articles without giving them page-edit permission?
      Cheers,
      Flo
    • By jonatan
      Hi! 😄
      SITE SETUP / DESCRIPTION:
      What? Online art magazine with an "All featured works" and also an "All featured artists" index page, and also individual "Work" and "Artists" pages, and data relations between the different artists and their artworks.
      So, I have two different page reference fields, connected by @Robin S's awesome Connect Page Fields module (though that has nothing to do with the issue in fact, Robin's plugin works great! and the issue is the same with or without it).
      The two Page Reference type fields are called "works" and "artists". They are meant to simply connect different artists to different artworks.
      Fx:
      Work 1  (page)  –> artists (Page Reference field) : Artist A (page)           --->>> (automatically connected)         Artist A (page)  –> works (Page Reference field) : Work 1 (page)
      Work 2  (page) –> artists (Page Reference field) : Artist B  (page)           --->>> (automatically connected)         Artist B (page)  –> works (Page Reference field) : Work 2 (page)
      ISSUE:
      On both Page Reference fields, both on "artists" and on "works" this option "Allow unpublished pages" is activated:

      As it says in the option description, supposedly, unpublished pages should be selectable in the page reference field, but they should not be visible, they shouldn't appear, on the front-end...
      Frontend:
      To show all works related to the artist on the artist individual page I'm doing this:
      <?php foreach($page->works as $item) { echo "<img src='{$item->image->first->width(200)->url}' class='pr-2'><a class='pr-4' href='$item->url'>$item->title</a>"; } The problem is now, unexpectedly, if some work is set to "Unpublished", it shows up anyways!
      WORKAROUND:
      So to get around this I figured out that I can do this:
      <?php foreach($page->works as $item) { if($item->is(Page::statusUnpublished)) { return; }; echo "<img src='{$item->image->first->width(200)->url}' class='pr-2'><a class='pr-4' href='$item->url'>$item->title</a>"; } But ofc this is a rather inelegant "solution" which shouldn't really be necessary, right? 
      I might be missing something basic here, but really can't figure out what it is... I hope one of you awesome guys can help me out 😊
      Thanks a lot in advance!
      All the best,
      Jonatan
×
×
  • Create New...