Jump to content

Secured content in a public environment, URL


olafgleba
 Share

Recommended Posts

Hi,

i am not the brightest star to arise today, i am afraid...

I have a secure members section as a part of a public website (user/role permissions). For example, logged in members are able to fill a blog  within the members section. They can choose (checkbox) if each of their posts should be available on the public website also (there exists a similiar section).

The problem while looping over those pages (in the public area) is, that the $page->url of course points to the secured members section. Which is - as well of course - not what i want.

// Simplyfied example

// Current: Path to detail page of a blog page
/members/blog/<name-of-the-post>/
  
// Should be: Path to detail page of a blog page
/blog/<name-of-the-post>/

Everywhere dead ends while thinking of how to solve this 😕

Any hints are much appreciated, regards
Olaf

Link to comment
Share on other sites

@olafgleba As I understand it, you've got pages that live at /members/blog/<name> and you want them to be accessible at /blog/<name>. First thing is to make it so that the blog post pages ->url property reflects the URL you want them to use. You can do this with a hook in /site/init.php:

$wire->addHookAfter('Page::path', function($event) {
  $path = $event->return;
  if(strpos($path, '/members/blog/') !== 0) return;
  $event->return = str_replace('/members/', '/', $path); 
}); 

Next, you want to make it so that ProcessWire will deliver those blog post pages at the /blog/<name> URL. You can do this either by enabling and handling URL segments on a /blog/ page, or you can use a URL/path hook, again in /site/init.php. I'm going to assume there is no /blog/ page, so a URL/path hook may be the best bet:

$wire->addHook('/blog/{name}', function($event) {
  $name = $event->arguments('name'); 
  $blog = wire()->pages->get("/members/blog/$name"); 
  return $blog->id && $blog->viewable() ? $blog : false;
}); 

Are those /members/blog/ pages are access protected from public users? If so, the above hook is not going to let them through because of the $blog->viewable() condition at the end. You could remove that, or better yet, replace it with a different condition:

if($blog->isUnpublished()) return false;
return $blog->id && $blog->template->name === 'blog-post' ? $blog : false;

I can't remember at the moment if ProcessWire does another access control check on the returned page ($blog). So if you find it doesn't work returning the $blog page, try having it return $blog->render() instead.

  • Like 9
  • Thanks 1
Link to comment
Share on other sites

On 6/7/2023 at 4:09 PM, ryan said:

@olafgleba As I understand it, you've got pages that live at /members/blog/<name> and you want them to be accessible at /blog/<name>. First thing is to make it so that the blog post pages ->url property reflects the URL you want them to use. You can do this with a hook in /site/init.php: [...]

First, many thanks @ryan for your detailed answer and examples!

While reading my post again afterwards, i am afraid i was not precise enough.

Maybe a more visual description what i aim to achive makes it more clear (hopefully, although meanwhile i guess what i like to achive is simply not possible, s. below). Btw., this description deals only with public available pages/paths (to avoid complexity at this point):

Website (Public)

Tree:

- Homepage (page)

  - About (page)
  
    - Blog (type: page, url: /about/blog/, template: blog)
      - Blog Post(s) (type: page, url: /about/blog/<name-of-blog-post>, template: blog-post) 
    
  - Campus (type: page, url: /campus/, template: campus)
    - Campus Post(s) (type: page, url: /campus/<name-of-blog-post>, template: campus-post)

Now i like to include the content of the blog page on the campus page (`/campus/`). So the blog is available on `/about/blog/` and `/campus/`. This is easy by iterating within the campus page template (template: campus, which is rather a copy of the blog template and has similiar settings. A template: campus-post also is created): 

$posts = $pages->find("template=blog-post, limit=12, sort=-blog_date");

<?php foreach($posts as $post): ?>
	...
<?php endforeach; ?>

But every blog post url points to its origin (e.g. `/about/blog/<name-of-post>`) of course. Where i want (in this context/ on this page) something like `/campus/<name-of-post`...

Again, meanwhile i guess this not possible because there are real templates involved. But would be pleased to get this wrong of course.

Many thanks for reading all this stuff 😉

Regards
Olaf

Maybe this helps, real life example (unfortunately only german language available):

https://vdp-ev.de/der-vdp/aktuell/ (correspond to `Blog`, url: `/about/blog`)
https://vdp-ev.de/der-vdp/aktuell/sybille-hirzel-verstorben/ (correspond to `Blog Post `, url: /about/blog/<name-of-post>`)
https://vdp-ev.de/kulturpolitik-und-foerderprogramme/ (correspond to `Campus`, url: `/campus`)

Link to comment
Share on other sites

Why don't you put all the posts directly under /campus/ instead?
That would result in page/post urls you are looking for.

Or do only appear some of those posts under /campus/ once in a while and only there?
That would be possible with a URL hook as shown by Ryan in the example. Minor changes necessary of course.

Just in case you really want to have some posts under /blog/ AND /campus/ this would result in duplicate content and you would have to fix this with canonical tags.

 

Some more questions just to understand this better:

Why do you want to mix different content types (posts, news, ...)?
I can get that but why would it then be necessary to change the URLs?

Link to comment
Share on other sites

Quote

Why do you want to mix different content types (posts, news, ...)?

Posts and news are no different content types, just different names for the same thing. In this case.

Quote

Or do only appear some of those posts under /campus/ once in a while and only there?

Close but not exactly: There is only one main blog which holds all posts (lives under /about/blog/). It is possible to assign multiple tags/keywords to each post (so the website visitor can narrow down the results).

At project launch the client wanted to have another section (e.g. /campus/) on the website with content that has similar design requirements as the blog area mentioned above. But while some posts are relevant only for the campus section, some appear in both sections (blog +  campus). The request then was to avoid establishing two independent blogs. Just to spare the need to maintain similar content in two different blogs.

So i trained the client to assign dedicated tags/keywords for posts, which are relevant for the display in the campus section. On the campus page i collect all posts with those dedicated tags/keywords.

Quote

Just in case you really want to have some posts under /blog/ AND /campus/ this would result in duplicate content and you would have to fix this with canonical tags.

Yes, right, i am aware of this.

Quote

I can get that but why would it then be necessary to change the URLs?

I find it a bit awkward to click on a post abstract while being on the /campus page and landing on the /about/blog/<name-of-post>. Confusing and a kind of one-way path for visitors.

And that exactly is the reason for my post/question.

  • Like 1
Link to comment
Share on other sites

  • 4 weeks later...

Since it is not possible to get what i like to have, the final solution now is a complete different one.

Referring to the OP: Member blog entries with the option set (e.g Publish to public site additionally?) will be mirrored to a clone of the blog which lives in the public available page tree. To avoid confusion, the public available blog is read only for editors.

This happens:
a. with a page hook while new member blog entries are applied or present entries are edited
b. nightly cronjob to synchronize orphaned or/and deleted entries.

 

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...