Jump to content

Best way to display relational data from another page?


kathep
 Share

Recommended Posts

Hello all, and Merry Christmas!

i have a seemingly simple problem that I don't know how to fix.

I have seen a range of posts on this topic (this one and this one were particularly helpful) and tried to combine them to fit my use case, but so far no luck. I am a beginner with php.

The problem includes two kinds of pages, with the following associated fields:

  • course.php
    • course_name
    • course_number
  • assignment.php
    • course_name_from_list

i have a list of assignments, and a list of courses, each assigned one of the above templates.

I am using the 'course_name_from_list' field to associate each assignment with a particular course. It is a page fieldtype referencing my course pages (which are stored at '/teaching/courses'.

My question is:

How do I get each assignment page to display the course_number on the course page associated with the selection in 'course_name_from_list'?

My best guess so far is like this:

$call_courses = $pages->get('parent=/teaching/courses');

$get_course_number = $course->course_number;

$content = $get_course_number . " " . $page->course_name_from_list

But I am doing something wrong, because this does not display the course number!

Does you have an idea of how I can fix this code to get the result I want?

Link to comment
Share on other sites

Hope I understood it correctly.

The code above will show all courses which are selected with course_name_from_list if included in the assignment.php.

$course = $page->course_name_from_list; // the page inputfield returns a page object if max=1, or a PageArray, if max. is above

$content = '';

// because I don't know your settings I do it as flexible as possible, but of course you could make it shorter
// Case 1: You have not set a max or max is above 1 and you chosre more than one page
if($course instanceof PageArray) {
	foreach($course as $course_item) {
		$content .= $course_item->course_number . " " . $course_item->title;
	}
// Case 2: One page selected
} elseif($course instanceof Page) {
	$content .= $course->course_number . " " . $course->title;
}

echo $content;
  • Like 4
Link to comment
Share on other sites

Hello @nico and all

I have adjusted your code to fit my page. I only used your second example, because there will only ever be one course selected in the field course_name_from_list, and there will only be one entry in field course_number associated. Perhaps I have broken something in the process of adapting the code...

//sidebar variables
$course = $page->course_name_from_list; // the page inputfield returns a page object if max=1, or a PageArray, if max. is above

$course_number_test = '';

if($course instanceof Page) { 
	$course_number_test .= $course->course_number . " " . $course->title; 
	}

echo $course_number_test;

$course_w_heading = "<h4>Course: " . $course_number_test . "<br>" . $page->course_name_from_list->first()->title . "</h4>";

// Primary content goes here
$sidebar = $course_w_heading . $course_section;

I changed $content in your example to $course_number_test (for testing purposes) because $content is already on use in the page, and I want the course number to appear in the sidebar. 

Adding the code listed above to the assignment.php template did not change the output result. Any ideas as to why that is? What am I missing?

Link to comment
Share on other sites

UPDATE: Improving my code

Hello all

I am working hard to understand @nico's code posted above. I have changed my code to be closer to his example: 

$course = $page->course_name_from_list; 

$sidebar = '';

if($course instanceof Page) { 
	$sidebar = $course->course_number . " " . $course->course_name ; 
	}

echo $sidebar;

However, this code does not display a sidebar. Any suggestions?

My best guess is that 

if($course instanceof Page)

 is returning a null value for some reason. My next step will be to test with different Input Field Types.

I will keep working on this, and if anyone has another suggestion, please let me know! 

Link to comment
Share on other sites

@kathep. Welcome to the forums.

As Nico pointed out in his post, he didn't know whether you are using a Single page field or a Multiple pages field, hence the use of 'instanceof Page/PageArray. That is not code you would normally use in a template file. Nico also pointed out how you would handle either page field type which I want to further clarify by asking, is your 'course_name_from_list' a Multiple or a Single page field? The fact that:

because there will only ever be one course selected in the field course_name_from_list

does not answer my question either :D. This is because, your 'course_name_from_list' could be a Multiple page field but you are using it to select only one course. In that case, because it would be a Multiple page field, whether you select one or 10 courses from it, it would return an array that you would have to loop through. On the other hand, if it is a Single page field, you would only ever be able to select one page in the field; PW will not let you choose more. You would not have to loop through it if it was a Single page field. Which of this is your case? If not the latter, I would suggest you change it to be the latter since you will only ever want to force the selection of a maximum of 1 page. 

Then you would be able to do as Nico suggested in his second example...(and it would work if your 'course_name_from_list' was a Single page field type), e.g.

if($page->course_name_from_list) echo $page->course_name_from_list->title;

Sorry for long-windedness! 

Btw: If on development/local server, you want to turn debug on.... :-)

  • Like 3
Link to comment
Share on other sites

Hi @kongondo, and thank you for your long-windedness. It really helps me to learn.

Which of this is your case? If not the latter, I would suggest you change it to be the latter since you will only ever want to force the selection of a maximum of 1 page. 

The field course_name_from_list is currently a Multiple page field. I would prefer it to be a single page field, but when I choose either option 'Single page (Page) or boolean false when none selected' or 'Single page (Page) or empty page (NullPage) when none selected', my page returns a lot of errors, like this:

post-2947-0-39891700-1419701937_thumb.pn

I don't have enough knowledge to understand these errors, so I got scared and returned the field setting to Multiple page.  :huh:

UPDATE: Resolved

I just started working through the errors to try to fix them myself. I removed a '->first()->title' from an instance of $page->course_name_from_list and that removed all errors.

Now my page works, and the code provided by @nico works! It was a simple fix. I'll write up my steps for an absolute beginner and post them below. Thanks @kongondo! Thanks @nico!

  • Like 1
Link to comment
Share on other sites

Glad you sorted it out...

The error with first() is because, in a Single page field, there is no 'first' per se; there is only one value there. first() will only work with a Multiple page field (or similar fields that return multiple items). To be a bit verbose, it is like telling a student 'go get me the first Head Teacher' :huh:  :wacko: - it doesn't make sense since there is only one Head Teacher (only one possible - Single page field). But you could tell the student, 'go get me the first teacher you find in the staff room, or the next five teachers you meet in the corridors ' (multiple possible) OK, you get the point :D

  • Like 1
Link to comment
Share on other sites

Ah, I see  :) , thank you for the further explanation.

Here is my write-up of steps for displaying relational data for absolute beginners, based on what the steps I have taken to fix my problem. Please chip in with corrections if any of you know a better way!

Displaying Relational Data from another page, using fieldtype Page and Input Field Type Single page.

Original problem:

I have a list of assignments, and a list of courses, each assigned one of the following templates:

  • course.php
    • title
    • course_number
  • assignment.php
    • course_name_from_list

I am using the 'course_name_from_list' field to associate each assignment with a particular course. 

 
I wanted to get each assignment page to display the course_number on the course page associated with the selection in 'course_name_from_list' but didn't know how. I wanted it displayed in the sidebar. Here I will show you how I fixed this!
 

Steps to fix:

  1. Change field course_name_from_list to Single page (choose option: Single page (Page) or empty page (NullPage) when none selected).
     
  2. Change $sidebar code from this:
  • $course_w_heading = "<h4>Course: " $page->course_name_from_list . "</h4>";
    
    $sidebar = $course_w_heading;
    
    // I made an array and added it to $sidebar because I had extra arrays to add, which I have left out here for the sake of keeping the examples simple.
    

    to this:

  • // array 1: calls the Page field
    $course = $page->course_name_from_list; 
    
    // array 2: includes fields from $course and formatting I want outputted on page
    $course_w_heading = "<h4>Course: " . $course->course_number . "<br>" . $course->title . "</h4>";
    
    // call sidebar as blank - I'm not sure why this is necessary 
    $sidebar = '';
    
    // if the Page field has a selection, output 
    if($course instanceof Page) {$sidebar = $course_w_heading ; }

It looks simple, and it is! However, I had many headaches and false starts getting here. I hope documenting this can help save other beginners some time.

Link to comment
Share on other sites

Thanks for the writeup....Here's another way of doing it (no need to use instance of Page :-)). Also, only output stuff you have confirmed exist..

//prepare a variable to use later on. Setting one like this ensures we don't get 'unknown $sidebar' errors in case things go wrong
$sidebar = '';

//if we found a course selected in the page field
if($page->course_name_from_list) {

	$course = $page->course_name_from_list; 
	$sidebar =  "<h4>Course: " . $course->course_number . "<br>" . $course->title . "</h4>";
}

else {
	//Oops, course not selected! Quick, hide everything!
	$sidebar = '<h4>Sorry, we do not have yet have the details for this course. Please check back soon, thanks. Alternatively, if your case is urgent, you can contact us on 12345-4567-0000.</h4>';
}

echo $sidebar;

Btw, If I understood you correctly, the page selected in the Page field 'course_name_from_list' has a field called 'course_number' and of course a title. In that case, you don't need to first save those fields in an array as you implied above:

// array 2: includes fields from $course and formatting I want outputted on page

The fields will be available to you automatically in the 'page/object' 'course' :-). You will be able to reference them as $course->name_of_field. If any of the fields is an array, you would have to loop through it, of course..

Edited by kongondo
  • Like 2
Link to comment
Share on other sites

Ah cool. Thank you for suggesting a more correct alternative. I am still learning about echo. 

I also like the 'else' option - this is a very front end user friendly option! I will make use of it. 

In case you are interested, I am using these things here.

  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...
if {}
else {
	//Oops, course not selected! Quick, hide everything!
	$sidebar = '<h4>Sorry, we do not have yet have the details for this course. Please check back soon, thanks. Alternatively, if your case is urgent, you can contact us on 12345-4567-0000.</h4>';
}

echo $sidebar;

@kongondo thanks for this little example of if {} else {} in action! I just used it for another situation. Very helpful.  ^-^

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