Jump to content


Photo

Investor area, best way to layout permission-only pages

roles member area

  • Please log in to reply
25 replies to this topic

#1 onjegolders

onjegolders

    Hero Member

  • Members
  • PipPipPipPipPip
  • 828 posts
  • 217

  • LocationMidlands, UK

Posted 17 April 2012 - 11:14 AM

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!

#2 ryan

ryan

    Hero Member

  • Administrators
  • 5,980 posts
  • 3382

  • LocationAtlanta, GA

Posted 18 April 2012 - 08:45 AM

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.

#3 onjegolders

onjegolders

    Hero Member

  • Members
  • PipPipPipPipPip
  • 828 posts
  • 217

  • LocationMidlands, UK

Posted 18 April 2012 - 09:13 AM

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?

#4 ryan

ryan

    Hero Member

  • Administrators
  • 5,980 posts
  • 3382

  • LocationAtlanta, GA

Posted 18 April 2012 - 10:31 AM

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();

#5 onjegolders

onjegolders

    Hero Member

  • Members
  • PipPipPipPipPip
  • 828 posts
  • 217

  • LocationMidlands, UK

Posted 18 April 2012 - 10:36 AM

Any particular way you could tie a property to a user? I suppose you would need a separate role per property? investor_property1, investor_property_2? Thanks again

#6 ryan

ryan

    Hero Member

  • Administrators
  • 5,980 posts
  • 3382

  • LocationAtlanta, GA

Posted 18 April 2012 - 10:48 AM

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.

#7 onjegolders

onjegolders

    Hero Member

  • Members
  • PipPipPipPipPip
  • 828 posts
  • 217

  • LocationMidlands, UK

Posted 18 April 2012 - 10:55 AM

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?

#8 Soma

Soma

    Hero Member

  • Moderators
  • 3,406 posts
  • 1938

  • LocationSH, Switzerland

Posted 18 April 2012 - 11:07 AM

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.

@somartist | modules created | support me, flattr my work flattr.com


#9 diogo

diogo

    Hero Member

  • Moderators
  • 2,068 posts
  • 1179

  • LocationPorto, Portugal

Posted 18 April 2012 - 11:08 AM

Have you seen the Page FieldType already? This is what Ryan is talking about http://processwire.c...page-fieldtype/

#10 onjegolders

onjegolders

    Hero Member

  • Members
  • PipPipPipPipPip
  • 828 posts
  • 217

  • LocationMidlands, UK

Posted 18 April 2012 - 11:26 AM

Thanks Diogo, I have seen them I'm just not sure how to use them in this case (where investors are $users with role of "investor" and they are only related to certain properties)

#11 diogo

diogo

    Hero Member

  • Moderators
  • 2,068 posts
  • 1179

  • LocationPorto, Portugal

Posted 18 April 2012 - 11:47 AM

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

#12 onjegolders

onjegolders

    Hero Member

  • Members
  • PipPipPipPipPip
  • 828 posts
  • 217

  • LocationMidlands, UK

Posted 19 April 2012 - 05:13 AM

Thanks a lot Diogo, I will take a look in detail at this later on. Cheers!

#13 onjegolders

onjegolders

    Hero Member

  • Members
  • PipPipPipPipPip
  • 828 posts
  • 217

  • LocationMidlands, UK

Posted 19 April 2012 - 05:57 AM

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)

#14 diogo

diogo

    Hero Member

  • Moderators
  • 2,068 posts
  • 1179

  • LocationPorto, Portugal

Posted 19 April 2012 - 06:20 AM

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}.";


#15 onjegolders

onjegolders

    Hero Member

  • Members
  • PipPipPipPipPip
  • 828 posts
  • 217

  • LocationMidlands, UK

Posted 19 April 2012 - 07:04 AM

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?

#16 ryan

ryan

    Hero Member

  • Administrators
  • 5,980 posts
  • 3382

  • LocationAtlanta, GA

Posted 19 April 2012 - 01:43 PM

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.

#17 onjegolders

onjegolders

    Hero Member

  • Members
  • PipPipPipPipPip
  • 828 posts
  • 217

  • LocationMidlands, UK

Posted 19 April 2012 - 04:43 PM

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 :)

#18 DaveP

DaveP

    Sr. Member

  • Members
  • PipPipPipPip
  • 302 posts
  • 156

  • LocationChorley, UK

Posted 20 April 2012 - 03:07 AM

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.
Twitter : Facebook : GitHub : G+ : Blog : Powered by C8H10N4O2 and C10H14N2

#19 onjegolders

onjegolders

    Hero Member

  • Members
  • PipPipPipPipPip
  • 828 posts
  • 217

  • LocationMidlands, UK

Posted 20 April 2012 - 04:27 AM

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.

#20 diogo

diogo

    Hero Member

  • Moderators
  • 2,068 posts
  • 1179

  • LocationPorto, Portugal

Posted 20 April 2012 - 06:09 AM

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
}






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users