Thought I'd run this by some people who know what they're doing before I report this as a bug.

I have a multi-site configuration. One of the sites has a base URL of example.com and only contains one single (we'll call this one-page site "Homepage"), whereas the other 6 sites have base URLs of example.com/site and contain multiple pages each. By this arrangement, these 6 sites are basically children of the Homepage.

I created another single "Landing" which is the front page for each of the children sites. It is not made "available" to the Homepage site. Each of the sites have their own title and content for each of their Landings, even though it is a single section that is shared between them.

Now here comes the problem. On the Homepage I need to have a grid that contains links to each of the other sites' Landing pages. I could have done this with an entries loop on the template, but the client actually needs to have control over which ones are visible in the grid. So I set up an Entries field on the Homepage section, and fashioned it so that its only options are Landing pages.

Now when I go to the Homepage entry and choose my entries, it successfully shows me the Landing pages from each site (I have to select the site from the dropdown to see each one) and can successfully select them. But when I try to access the field on the template it breaks.

This is my template code (the field in question "page" is in a Matrix "navGrid"):

{% for item in entry.navGrid %}
  <a href="{{ item.page.one().url }}">{{ item.page.one().title }}</a>
{% endfor %}

This gives me the error Impossible to access an attribute ("url") on a null variable.

When I tried removing the .one(), I got the error Calling unknown method: craft\elements\db\EntryQuery::url()

And when I also removed the .url (and just ran {{ item.page }}), I got this nasty wad:

O:28:"craft\elements\db\EntryQuery":84:{s:8:"editable";b:0;s:9:"sectionId";N;s:6:"typeId";N;s:8:"authorId";N;s:13:"authorGroupId";N;s:8:"postDate";N;s:6:"before";N;s:5:"after";N;s:10:"expiryDate";N;s:17:"*defaultOrderBy";a:1:{s:16:"entries.postDate";i:3;}s:11:"elementType";s:20:"craft\elements\Entry";s:5:"query";N;s:8:"subQuery";N;s:12:"contentTable";s:12:"{{%content}}";s:12:"customFields";N;s:9:"inReverse";b:0;s:7:"asArray";b:0;s:18:"ignorePlaceholders";b:0;s:6:"drafts";b:0;s:7:"draftId";N;s:7:"draftOf";N;s:12:"draftCreator";N;s:9:"revisions";b:0;s:10:"revisionId";N;s:10:"revisionOf";N;s:15:"revisionCreator";N;s:2:"id";N;s:3:"uid";N;s:10:"fixedOrder";b:0;s:6:"status";a:1:{i:0;s:4:"live";}s:8:"archived";b:0;s:7:"trashed";b:0;s:11:"dateCreated";N;s:11:"dateUpdated";N;s:6:"siteId";i:1;s:6:"unique";b:0;s:11:"preferSites";b:0;s:14:"enabledForSite";b:1;s:6:"leaves";b:0;s:9:"relatedTo";N;s:5:"title";N;s:4:"slug";N;s:3:"uri";N;s:6:"search";N;s:3:"ref";N;s:4:"with";N;s:7:"orderBy";a:1:{s:19:"relations.sortOrder";i:4;}s:13:"withStructure";b:1;s:11:"structureId";N;s:5:"level";N;s:14:"hasDescendants";N;s:10:"ancestorOf";N;s:12:"ancestorDist";N;s:12:"descendantOf";N;s:14:"descendantDist";N;s:9:"siblingOf";N;s:13:"prevSiblingOf";N;s:13:"nextSiblingOf";N;s:16:"positionedBefore";N;s:15:"positionedAfter";N;s:53:"craft\elements\db\ElementQuery_placeholderCondition";N;s:51:"craft\elements\db\ElementQuery_placeholderSiteIds";N;s:39:"craft\elements\db\ElementQuery_result";N;s:47:"craft\elements\db\ElementQuery_resultCriteria";N;s:45:"craft\elements\db\ElementQuery_searchScores";N;s:6:"select";a:1:{s:2:"**";s:2:"**";}s:12:"selectOption";N;s:8:"distinct";N;s:4:"from";N;s:7:"groupBy";N;s:4:"join";a:1:{i:0;a:3:{i:0;s:10:"INNER JOIN";i:1;s:24:"{{%relations}} relations";i:2;a:4:{i:0;s:3:"and";i:1;s:40:"[[relations.targetId]] = [[elements.id]]";i:2;a:2:{s:18:"relations.sourceId";s:3:"107";s:17:"relations.fieldId";s:2:"11";}i:3;a:3:{i:0;s:2:"or";i:1;a:1:{s:22:"relations.sourceSiteId";N;}i:2;a:1:{s:22:"relations.sourceSiteId";s:1:"1";}}}}}s:6:"having";N;s:5:"union";N;s:6:"params";a:0:{}s:18:"queryCacheDuration";N;s:20:"queryCacheDependency";N;s:27:"yii\base\Component_events";a:0:{}s:35:"yii\base\Component_eventWildcards";a:0:{}s:30:"yii\base\Component_behaviors";a:1:{s:12:"customFields";O:35:"craft\behaviors\CustomFieldBehavior":16:{s:10:"hasMethods";b:1;s:10:"peopleGrid";N;s:10:"personName";N;s:10:"personLink";N;s:8:"research";N;s:9:"personPic";N;s:13:"featuredImage";N;s:10:"imageAlpha";N;s:7:"navGrid";N;s:5:"color";N;s:5:"alpha";N;s:4:"page";N;s:5:"image";N;s:55:"craft\behaviors\CustomFieldBehavior_customFieldValues";a:0:{}s:5:"owner";r:1;s:34:"yii\base\Behavior_attachedEvents";a:0:{}}}s:5:"where";N;s:5:"limit";s:1:"1";s:6:"offset";N;s:7:"indexBy";N;s:16:"emulateExecution";b:0;}

So my best guess is that since the Landing section is not "available" to the Homepage, it can't find the entries. So really my question about whether or not this is a bug comes from the fact that it lets me view and select those entries in the Entries picker field, which maybe shouldn't be the case if they actually can't be accessed. Or am I missing something? There are a lot of special settings all over the place having to do with multi-site stuff, so it's very possible I don't have mine perfectly arranged. Any workaround to how I can let the client select these Landing pages for the grid would be very welcome.

1 Answer 1


In order to fetch cross-site entries in element queries you'll need to specify the site parameter, otherwise it'll default to the current site only: https://docs.craftcms.com/v3/dev/element-queries/entry-queries.html#site


{% for item in entry.navGrid.all() %}
   {% set page = item.page.site('*')|length ? item.page.site('*').one() %}
   <a href="{{ page.url }}">{{ page.title }}</a>
{% endfor %}

(Aside: in practice, you'd also want to use eager loading for something like this to avoid the N+1 problem triggered by having a .one() call inside a loop.)

  • Perfect. Thank you very much. What's stupid is I had already used the site parameter on an entries query on the template, but for some reason I thought it was a totally different thing when dealing with fields.
    – Brimby
    Commented Mar 11, 2020 at 19:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.