Jump to content

references between pages with different templates


bilioso
 Share

Recommended Posts

I'm building a local test site with PW 3.0.165.
Server Wamp, Apache 2.4, php 7.3.

I created 2 templates: Articles and Authors.

Template Articles has the usual content and images fields, plus:
fieldAuthors (page reference to Authors pages, multiple)

Both templates render all the fields ok, namely the list of referenced authors in the Article page.

In template Authors I tried to make a list of Article pages related to that Author:
(sorry for having some words in Portuguese; please read 'author' where 'autor')

foreach($pages as $page) {
	if(count($page->autores)) {
		foreach ($page->autores as $autor) {
			if($autor->title == $page->title) $content .= $page->title;
		}
	}
}

It doesn't work. It complains about "PHP Notice: Trying to get property 'autores' of non-object in ...\www\cadppimport\site\templates\autor.php:22"
BTW it makes the same complain about the line with
     if($page->rootParent->hasChildren > 1) { ... renderNavTree($page->rootParent, 3) ... }
but in fact it renders right the navTree.

What am I doing wrong?

Link to comment
Share on other sites

Variables like $page are reserved by PW, so you shouldn't try to redefine them. PW tries to find a field 'autores', which is not available in the current $page, but in the page array you're looping through. Try:

foreach($pages as $p) {
	if(count($p->autores)) {

If you install Tracy Debugger (which every PW developer should, imho), you can include debug output for variables, which is a big help when developing.

  • Like 1
Link to comment
Share on other sites

Thanks, @dragan, you were right, of course: the use of a reserved word was a major problem.

As for Tracy Debugger , I was already using it (although I think I'm not getting the debug output)[*].

Now the page renders (with my previous code it always crashed without rendering, ). However, even after changing names of the variables, it was not showing the list I intended.

It took me half a day of experiments to find out that there is another essential point to put it rendering:

// referee pages from Article to Author

$articles = $pages->find("template=artigo");
 ... 
foreach($articles as $article) {
	if ($article->int == $page->id->int) ... ;
}
...

First: I had to use find() instead of count() to avoid problems.

Second: there is some problem/specification with the page reference field I can't get right. Finally I discovered, by random experiment, that I have to declare both the reference and the id of the page as integers (which I don't know how to do it in php, it was a wild guess). Then (finally!) it renders ok. But it is not yet right:

Tracy debugger still reports error «PHP Notice: Trying to get property 'int' of non-object ...»

Since I can see that several modules (including Tracy Debugger) also have error reports on running, I suppose I should not get anxious about it, since it renders fine.

I'm ready now for the next trouble on migrating from Drupal to PW.

 

(*) Side note with absolutely no interest for this case:
I can see PW is simpler, cleaner and more elastic than any other cms I came across before. And, as far as I can see, it is perfect for my site needs.
Unfortunately, I'm afraid I will never be able to take the most of it. Not because of PW, but because of my personal idiosyncrasy, which makes me unable to learn php, as if there was a concrete wall between me and the language. Two factors intervene:
First, the fact that the only programming language I learned and played around a little bit with (apart from Basic, 50 years ago) is Smalltalk/Squeak. After learning ST, php looks like a wild jungle with no sense and a dirty inhuman syntax. I would not complain and it would be much easier for me if I was total virgin in programming, I guess.
Secondly ... well, I can imagine that my 68 years old are not helping to learn fast...
However, I will insist a little bit more to see if I can migrate my site to PW. It is the most elegant system I ever tried.

Link to comment
Share on other sites

21 hours ago, bilioso said:

my personal idiosyncrasy, which makes me unable to learn php

The funny thing is that you do not have to! I mean, you don't have to learn too much about PHP in order to develop sites with ProcessWire. I recommend installing and studying Ryan's Skyscrapers 2 site profile (https://github.com/dadish/pw-skyscrapers-profile) and some other more recent ones which look interesting to you: https://modules.processwire.com/categories/site-profile/?sort=-created

Link to comment
Share on other sites

On 10/7/2020 at 1:11 AM, bilioso said:

Tracy debugger still reports error «PHP Notice: Trying to get property 'int' of non-object ...»

Since I can see that several modules (including Tracy Debugger) also have error reports on running, I suppose I should not get anxious about it, since it renders fine.

PHP Notices are not something to fix immediately but one should deal with them as soon as time permits. It is because they signal some unintended behavior and naturally, we are not aiming for such a thing.

Specifically, "Trying to get property 'XYZ' of non-object" is a common issue, which means that – for example – in the  $page->id->int expression the ID property is an integer and as such has no properties because it is not an object (aka "non-object"). Therefore trying to access ->int results in this notice. This also means that if ($article->int == $page->id->int) will not work as intended.

On 10/7/2020 at 1:11 AM, bilioso said:

I discovered, by random experiment

This is the way engineering works 🙂 However, sometimes just take a break and learn form professionally crafted tutorials, such as this one: https://www.youtube.com/watch?v=D8ZcKqevECY&list=PLLQuc_7jk__WTMT4U1qhDkhqd2bOAdxSo&index=1 The hard part is to find good tutorials, of course.

 

 

  • Like 1
Link to comment
Share on other sites

Ok, supposing a template Author,
and a template Article with a fieldAuthors (page reference, multiple),
the dynamic part of the Author template now goes:

$articles = $pages->find("template=article");
foreach($articles as $article) {
	foreach($article->authors as $author) {
		if($author->id == $page->id) {
			// ... some stuff 
		} } }

and there it is, the list of articles for that author, next to his/hers pretty face.

I imagine it is bad coding, but it works.

Link to comment
Share on other sites

  • 1 month later...
$articles = $pages->find("template=article, fieldAuthors=$page");
foreach ($articles as $article) {
	// something like echo $article->title;
}

You could also skip a few lines of code if you put the extra fieldAuthors=$page in your selector. Then your pages->find only returns pages where the current page's author is present in fieldAuthors.

Link to comment
Share on other sites

Thanks, Snobjorn. Much cleaner now.

However, it turns out that the selector doesn't accept variables and operators like $page - the concept is right, but the peace of code won't work.

The solution I could find:

$selector = "template=article, fieldAuthors=" . $page . ", sort=-published";
$articles = $pages->find($selector);
foreach($articles as $article) {
	#...
}

Note: The messy nested iteration in my first solution resulted from my (wrong) notion that because fieldAuthors is an Array, I should iterate to find the right value. Well, I was surprised to find out that the selector "fieldArray=someValue" magically iterates through fieldArray to find someValue.
The code is working, but please correct me if I'm wrong on this note, I don't want to induce other apprentices into mistake.
Otherwise this issue is solved.

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