Jump to content

Investor area, best way to layout permission-only pages


onjegolders
 Share

Recommended Posts

Just trying to get my head around this one and was wondering how you would play it on your sites?

I have a property portfolio page with different properties as children. This should be visible to all visitors (no problem here)

There also needs to be property-specific extras for people who are logged in as "investors" (role already created)

I'm just trying to think hierarchically the best way to go about this. I currently see two options but I'm hoping there are more, or that I'm missing something.

Option 1:

Create an Investors page and repeat the portfolio children underneath -

The downside of this I suppose is that the staff would had to add a property twice and repeat all the content?

Option 2:

Use same "Portfolio" and "Portfolio-entry" templates and then add permission-only content to these templates such as:

<?php if ($user->hasRole("investor") == 1) { ?>
// some code here...
<?php } ?>

This could be a better option but I'm wondering how cluttered the templates may get.

Would just be interested in your thoughts on how you may go about this?

Thanks!

Link to comment
Share on other sites

It depends on the scope of the content. But it sounds to me like Option 2 is your best bet. This is the route I usually take.

If it's content that you can include all on your portfolio-entry pages, then I would do that... no need to split it on multiple public vs. investor pages unless it's a whole lot of stuff, or it makes more sense with the site structure. Your portfolio-entry template will contain the fields of content that are public as well as investor-specific. But you will only display the investor-specific content if the user has the 'investor' role. Your template code might look like this:

echo "<h1>{$page->title}</h1>";
echo $page->body; 

if($user->hasRole('investor')) {
   echo "<h2>Investor Data</h2>";
   echo $page->investor_data; 
}

That's basically repeating what you already included in your code, so I think you already arrived at a good solution.

Link to comment
Share on other sites

Thanks Ryan.

I think this is definitely the best way to go. If I had a whole page (or template) of specific information for an existing (public) property could I then go one level deeper?

Something like:

site.com/properties/property-1/investor-view

?

I just think it may arise that the client wants a whole bunch of information for a particular investor. I guess then there would need to be a role per property?

Link to comment
Share on other sites

You could certainly take it a level deeper and then just display the links to it if they had access. On the deeper levels, you'd either want to limit view access to the 'investor' role (from the template access settings). Or if the template is being used for public stuff too, then perform the check in your template code like in the examples above. If you are performing your own check, you may want to redirect them to the login page when they don't have access, or say something like "Become an investor to get access", or just: throw Wire404Exception();

Link to comment
Share on other sites

No need to use a role for that. I would just use a page reference to relate them, or you could even do it by page name. You'd perform the check in your template code, but you could get exactly what you want that way.

Link to comment
Share on other sites

No need to use a role for that. I would just use a page reference to relate them, or you could even do it by page name. You'd perform the check in your template code, but you could get exactly what you want that way.

Sorry Ryan you've lost me there! Could you give me a quick example?

Link to comment
Share on other sites

I think Ryan means, you can add a page reference field to the user template. Then select the properties you want the user to view. Using that reference you check in the template if the user has the property in the page reference selected and show something or not.

Link to comment
Share on other sites

You can put a page field in the properties template and select the page "users" as the parent of selectable pages.

Then, you call the user for each property, from the property page, like this:

foreach($page->pagefield as $myuser){
  echo $myuser->name;
}

and to all properties from a user:

$theuser = $pages->get("user selector");
$properties = $pages->find("template=property, pagefield=$theuser");

(both not tested)

edit:

where investors are $users with role of "investor"

I didn't take this in consideration in my answer, but there must be a way of constraining the selectable pages to this.

edit2:

Ok, besides limiting the field by parent, you can place on the field's "Custom PHP code to find selectable pages", this snippet of code:

$investor = $pages->get("name=investor");
return $pages->find("roles=$investor");

This will limit the selection to users with the role "investor"

edit: I changed the variable $user to $myuser where I was using it, so it won't override the existing $user from the API

  • Like 1
Link to comment
Share on other sites

Sorry, I'm picking this up again and trying to look at it from a front-end point of view as well.

If on my portfolio-entry page I want to have a link to the investment details for this property I need to send the link to an actual page don't I?

Because I had merrily gone about creating a new template called investment_details.php which called it's parent, got the data from there and displayed it in a different way. But I'm now realizing that for this "page" to exist at all front end then there needs to be an actual page generated back-end, by the client underneath the particular property.

Am I getting this right? If so is there any other way of displaying a different template for the same page? (So that there doesn't need to be 20 sub-pages for 20 property investment details)?

Thanks again and sorry for dragging this out (I think my brain has gone back into EE mode)

Link to comment
Share on other sites

You can use a URL segments. I don't have much time now, but maybe you can understand what I mean from this small code:

$detail = $input->urlSegment1;
echo "The content of {$detail} is: {$page->$detail}.";
Link to comment
Share on other sites

You can use a URL segments. I don't have much time now, but maybe you can understand what I mean from this small code:

$detail = $input->urlSegment1;
echo "The content of {$detail} is: {$page->$detail}.";

Thanks Diogo but I don't quite understand where you would put that code?

Would this be a way of reusing a pages content in a different template?

Link to comment
Share on other sites

I think what Diogo is saying is that with a URL segment you can take a different path depending on what the URL segment is. For instance:

if($input->urlSegment1 == 'photos') {
   // output photo gallery

} else if($input->urlSegment1 == 'rates') {
   // output rates table

} else if($input->urlSegment1) {
   // unknown URL segment, send a 404
   throw new Wire404Exception();

} else {
   // output default 
}

So you don't need to have a separate page for the segments you are looking for like 'photos' and 'rates' and any others. This can be a worthwhile technique in some instances and it sounds like yours would be one of them.

Link to comment
Share on other sites

I think what Diogo is saying is that with a URL segment you can take a different path depending on what the URL segment is. For instance:

if($input->urlSegment1 == 'photos') {
// output photo gallery

} else if($input->urlSegment1 == 'rates') {
// output rates table

} else if($input->urlSegment1) {
// unknown URL segment, send a 404
throw new Wire404Exception();

} else {
// output default
}

So you don't need to have a separate page for the segments you are looking for like 'photos' and 'rates' and any others. This can be a worthwhile technique in some instances and it sounds like yours would be one of them.

Thanks Ryan, but correct me if I'm wrong, if we wanted say the 'rates' for 'Property 1' in the properties section, then the page properties/property_1/rates would still need to be created in the backend? So essentially each property would end up with a child, all called rates?

These could then be referenced with urlSegment but I'm presuming you couldn't just give an href to a non-existent page and then create it on the fly?

Sorry for being so slow here :)

Link to comment
Share on other sites

You can create such a page on the fly - just include some code like this in your template

<?php
if($pages->get('properties/property_1/rates ') instanceof NullPage){
 $newpage = new Page();
 $newpage->template = 'rates';
 $newpage->parent = $pages->get('template=property,name=property_1');
 $newpage->title = $title;
 $newpage->save();
}
?>

You might need to use a couple of variables to make this cover the possible eventualities, but it works.

Link to comment
Share on other sites

You can create such a page on the fly - just include some code like this in your template

<?php
if($pages->get('properties/property_1/rates ') instanceof NullPage){
 $newpage = new Page();
 $newpage->template = 'rates';
 $newpage->parent = $pages->get('template=property,name=property_1');
 $newpage->title = $title;
 $newpage->save();
}
?>

You might need to use a couple of variables to make this cover the possible eventualities, but it works.

Thanks Dave, was just re-reading Ryan's last post with a fresher pair of eyes, I think he means that if someone puts in or is linked to /rates then you CAN output a template without there actually being a page.

My preference would be for there to not be a new page, just a new view of the same content. That way the client could put all the property info on one page in the backend. Then in the portfolio_entry template I could check if they had certain permissions and if so link them to /rates for example and then they'd be shown a template with investor-specific information on it.

Sorry if this is making no sense at all! I think the best way may be that I just give it a go and see where it ends up.

Link to comment
Share on other sites

I think he means that if someone puts in or is linked to /rates then you CAN output a template without there actually being a page

You can output a completely different page only by checking the url segment :)

edit: if it confuses you to have all the code on one file you can do it with includes:

if($input->urlSegment1 == 'photos') {
   include 'photos.inc';
} else if($input->urlSegment1 == 'rates') {
   include 'rates.inc';
} else if($input->urlSegment1) {
   // unknown URL segment, send a 404
   throw new Wire404Exception();
} else {
   // output default
}
  • Like 1
Link to comment
Share on other sites

Thanks Ryan, but correct me if I'm wrong, if we wanted say the 'rates' for 'Property 1' in the properties section, then the page properties/property_1/rates would still need to be created in the backend? So essentially each property would end up with a child, all called rates?

When you enable the URL segments option for a given template (Templates > Edit Template > URLs > URL Segments) then PW will accept non-existant URLs, so long as they start with one that does exist. So lets say that you have a page called /products/widget/. If URL segments are enabled, then you could access any URL below that and it would be sent to /products/widget/. So accessing /products/widget/photos/ (a page that doesn't exist) would still get sent to /products/widget/. (If URL segments are not enabled, then of course accessing /products/widget/photos/ would generate a 404 instead.)

Using the /products/widget/photos/ URL, the 'photos' portion would be considered URL segment 1. You can check the value of URL segment 1 in your template file with $input->urlSegment1. If there were another segment on there too, like, /products/widget/photos/cats/ then 'cats' would be URL segment 2 ($input->urlSegment2), and so on.

The advantage of URL segments is that you can have just 1 page handling many URLs. The portion of those URLs that are translated to URL segments are not pages in PW. In fact, if you actually created a page in PW named /products/widget/photos/, then your 'widget' page would no longer receive the 'photos' URL segment, as the new photos page would then have control over it.

  • Like 2
Link to comment
Share on other sites

When you enable the URL segments option for a given template (Templates > Edit Template > URLs > URL Segments) then PW will accept non-existant URLs, so long as they start with one that does exist. So lets say that you have a page called /products/widget/. If URL segments are enabled, then you could access any URL below that and it would be sent to /products/widget/. So accessing /products/widget/photos/ (a page that doesn't exist) would still get sent to /products/widget/. (If URL segments are not enabled, then of course accessing /products/widget/photos/ would generate a 404 instead.)

Using the /products/widget/photos/ URL, the 'photos' portion would be considered URL segment 1. You can check the value of URL segment 1 in your template file with $input->urlSegment1. If there were another segment on there too, like, /products/widget/photos/cats/ then 'cats' would be URL segment 2 ($input->urlSegment2), and so on.

The advantage of URL segments is that you can have just 1 page handling many URLs. The portion of those URLs that are translated to URL segments are not pages in PW. In fact, if you actually created a page in PW named /products/widget/photos/, then your 'widget' page would no longer receive the 'photos' URL segment, as the new photos page would then have control over it.

Thanks Ryan that sounds exactly what I was looking for. So in theory I could put an include within an if urlSemgent test and output a whole new template. This would basically allow me to replicate EE's templating system somewhat?

Link to comment
Share on other sites

Just wanted to say thanks to all of you for helping me out with this, it works perfectly as expected, if a user has the credentials I can send him off to another template with private information and if they don't they'll just see the normal page. The client can add all the necessary information under one entry so this is very powerful and easy at the same time!

  • Like 1
Link to comment
Share on other sites

  • 6 months later...

Sorry, just running into another issue with urlSegments. I have enabled urlSegments on my "students" template so that

/students/geography includes a geography_students.inc file.

My problem is that underneath /students/ is the "student" template so

/students/joe-bloggs displays using the "student" template but I want to add a link to "edit profile" from this particular student page and I'm trying to include an "edit_profile.inc" file but I don't know whether this would be a urlSegment2 of the "students" template or a urlSegment1 of the "student" template.

I have tried both, but neither seem to work, any ideas on how to implement this?

Thanks gang!

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