Closed luukee closed 10 months ago
https://github.com/timber/timber/blob/dbb7139152ac95f67c7bd1cbf354276a59d82842/src/Post.php#L213
I think you are calling the above constructor as parent::__construct($query);
This is how to create an Archive class in v2 https://github.com/timber/timber/blob/dbb7139152ac95f67c7bd1cbf354276a59d82842/src/Archives.php#L90-L102
Good point @szepeviktor. But the curious thing is, when I switch to the __construct method I get the same exact error.
Let me send more code & error output when I'm back at my computer. . .
Thank you for commenting 👍
I think you’re mixing different things. Your Archive
class extends Timber\Post
, so that would mean that you would use this to work with single posts. But then you call this->posts = $this->queryIterator->get_posts();
and $this->pagination = $this->pagination();
inside the init()
function of your post. What do you want to do with that?
Should your archive.php display multiple archive posts? Or should Archive
be a class that handles multiple posts?
If your Archive
class should handle multiple posts, then you probably shouldn’t extend Timber\Post
.
If Archive
should act as the class for posts in archive.php, then you shouldn’t instantiate the post directly.
$context['archive'] = new Archive($options);
You’ve added a class map, which means you can use Timber::get_post( $post_id )
to get an archive posts and Timber::get_posts()
to get the collection of archive posts if you’re in archive.php.
public function init($query = false) {
// ...
parent::__construct($query);
}
If you’re overwriting the init()
method, you should call parent::init()
, but not parent::construct()
. If you extend Timber\Post
and run parent::construct()
, then it will do nothing, because we use empty constructors.
Thank you @gchtr for checking out my issue. I've been trying everything I can come up with to no avail.
What do you want to do with
this->posts = $this->queryIterator->get_posts();
and$this->pagination = $this->pagination();
inside theinit()
function?
These are actually used to build the sidebar taxonomy filters/categories.
Should your archive.php display multiple archive posts?
Yes, it should show a list of archive research
posts with a sidebar taxonomy filter menu. Here's an screenshot:
Here's the Timber 1.0 original src/Models/Archive.php
constructor:
public function __construct($query = false, $class = 'Engage\Models\Article')
{
// Set the 'verticals' taxonomy term
$this->setVertical();
$this->setCategory();
// Set the post type
$this->setPostType();
parent::__construct($query, $class);
$this->setQueriedObject();
$this->posts = $this->queryIterator->get_posts();
$this->pagination = $this->pagination();
// Assign the taxonomy term. ex. 'verticals' tax
// "$this->queriedObject" is a WP_Term
$this->taxonomy = $this->queriedObject->taxonomy;
// Set the slug ex. 'journalism'
$this->slug = $this->queriedObject->slug;
// Set the intro ex {{ archive.intro }} - tax term, tax title, tax excerpt
$this->setIntro();
}
Here's the original (Timber 1.0) archive.php
file:
$context = Timber::get_context();
$options = [];
$globals = new Engage\Managers\Globals();
$articleClass = 'Engage\Models\Article';
$teamGroups = [];
$options = [
'filters' => $globals->getVerticalMenu(get_query_var('verticals'))
];
// build intro
$query = false;
$archive = new Engage\Models\TileArchive($options, $query, $articleClass);
$context['archive'] = $archive;
Timber::render( ['archive.twig'], $context, ENGAGE_PAGE_CACHE_TIME);
getVerticalMenu
from src/Managers/Globals.php
:
public function getVerticalMenu($vertical) {
$menu = get_transient('vertical-filter-menu--'.$vertical);
if(!empty($menu)) {
return $menu;
}
$vertical = get_term_by('slug', $vertical, 'verticals');
// The filter menu will be built in this order
$postTypes = [ 'research', 'blogs', 'announcement', 'tribe_events', 'post', 'team' ];
$posts = new Timber\PostQuery([
'post_type' => $postTypes,
'tax_query' => [
[
'taxonomy' => 'verticals',
'field' => 'slug',
'terms' => $vertical->slug
]
],
'posts_per_page' => -1
]);
$options = [
'title' => $vertical->name,
'slug' => $vertical->slug.'-menu',
'posts' => $posts,
'taxonomies' => ['research-categories', 'blogs-category', 'announcement-category', 'tribe_events_cat', 'category', 'team_category'],
'postTypes' => $postTypes
];
// we don't have the vertical menu, so build it
$filters = new \Engage\Models\FilterMenu($options);
$menu = $filters->build();
set_transient('vertical-filter-menu--'.$vertical->slug, $menu );
return $menu;
}
Lastly the src/Models/TileArchive.php
file:
namespace Engage\Models;
class TileArchive extends Archive
{
public $filters = []; // when you want things organized by vertical
public function __construct($options, $query = false, $class = 'Engage\Models\Article')
{
$defaults = [
'filters' => []
];
$options = array_merge($defaults, $options);
$this->filters = $options['filters'];
parent::__construct($query, $class);
// loop through the posts and if it's an event, set it as the event model instead
foreach($this->posts as $key => $val) {
if($val->post_type === 'tribe_events') {
$this->posts[$key] = new Event($val->ID);
}
}
// This is usually already set from a global. If it's empty, then there's no sidebar
if(!empty($this->filters)) {
// get the current filter menu item
$this->setCurrentFilter();
}
}
// set the current filter based on the archive
// this is way too confusing, but seems to work fine... :/
public function setCurrentFilter() {
// search for the current slug.
// If we're displaying all verticals, we'll be looking for the vertical slug as the current match.
// if it's by postType, then we're looking for the current displayed postType
// Needed to add ability to add team category info to array and filter css.
// Might consider re-doing some of the filter stuff to acount for things like these.
if ($this->filters['structure'] === 'vertical') {
if (isset($this->vertical->slug)) {
$currentSlug = $this->vertical->slug;
} elseif (isset($this->category->slug)) {
$currentSlug = $this->category->slug;
}
} else {
$currentSlug = $this->postType->name;
}
if($this->filters['terms']) {
foreach($this->filters['terms'] as $parentTerm) {
if($currentSlug === $parentTerm['slug']) {
// found the parent match!
$this->filters['terms'][$parentTerm['slug']]['currentParent'] = true;
// now see if this is just the current parent or actually the current one
if($this->category->taxonomy === 'verticals') {
$this->filters['terms'][$parentTerm['slug']]['current'] = true;
} else {
if(!empty($parentTerm['terms'])) {
// let's find the child
foreach($parentTerm['terms'] as $childTerm) {
if($childTerm['slug'] === $this->category->slug) {
$this->filters['terms'][$parentTerm['slug']]['terms'][$this->category->slug]['current'] = true;
break;
}
}
}
}
break;
}
}
}
}
}
Also, if I {{ dump(archive) }}
from the archive.twig
file on the Timber 1.0 theme I get this:
slug: "journalism"
intro: array:3 [▼
"vertical" => WP_Term {[#5943 ▶](http://localhost:3003/vertical/journalism/research/#sf-dump-1957750531-ref25943)}
"title" => "Journalism"
"excerpt" => ""
]
vertical: WP_Term {[#5943 ▼](http://localhost:3003/vertical/journalism/research/#sf-dump-1957750531-ref25943)
+term_id: 240
+name: "Journalism"
+slug: "journalism"
+term_group: 0
+term_taxonomy_id: 240
+taxonomy: "verticals"
+description: ""
+parent: 0
+count: 184
+filter: "raw"
}
category: WP_Term {[#5942 ▶](http://localhost:3003/vertical/journalism/research/#sf-dump-1957750531-ref25942)}
filters: array:5 [▼
"title" => "Journalism"
"slug" => "journalism-menu"
"structure" => "postTypes"
"link" => false
"terms" => array:3 [ …3]
]
My attempt is to migrate this code to Timber 2.0, but running into troubles with the class maps & using the classes on the archive.php
file. I really appreciate your help.
I can always provide more into if you need.
@szepeviktor @gchtr I was able to resolve the issue. I will share the fix when I get back to work tomorrow.
Thanks for your help.
Glad you were able to fix your issue @luukee , I will close the issue here but please do share your fix.
@luukee I encounter the same problem, how did you solve it on your side?
Of course @Jonathan-Scapin & @Levdbas. With the help from @gchtr I was able to get Timber 2.0 working on our theme.
All code below is compared to my original post,
src/Models/Archive.php
I was able to replace my constructor (__construct
) with init
and excluded the $class
parameter. Then for the constructor's parent::__construct($query, $class);
I just removed the $class
parameter and lastly instead of getting the posts with $this->queryIterator->get_posts()
I used Timber::get_posts($query)
.
These are three changes you'll want to take note of for any other files with similar structure.
Original (Timber 1.0):
public function __construct($query = false, $class = 'Engage\Models\Article')
{
// other code
parent::__construct($query, $class);
$this->setQueriedObject();
$this->posts = $this->queryIterator->get_posts();
// other code
}
Updated (Timber 2.0):
public function init($query)
{
// other code
parent::__construct($query);
$this->setQueriedObject();
$this->posts = Timber::get_posts($query); // Get posts using Timber
// other code
}
archive.php
For archive.php
file:
Original (Timber 1.0):
$context = Timber::get_context();
$options = [];
$globals = new Engage\Managers\Globals();
$articleClass = 'Engage\Models\Article';
$archive = new Engage\Models\TileArchive($options, $query, $articleClass);
$context['archive'] = $archive;
Timber::render( ['archive.twig'], $context, ENGAGE_PAGE_CACHE_TIME);
Updated (Timber 2.0):
$context = Timber::context();
$options = [];
$globals = new Engage\Managers\Globals();
global $wp_query; // Get WP global query
use Engage\Models\TileArchive; // from class maps in functions.php
// remove $articleClass
// same code
$archive = new TileArchive( $options, $wp_query );
$context['archive'] = $archive;
Timber::render( ['archive.twig'], $context, ENGAGE_PAGE_CACHE_TIME);
src/Managers/Globals.php
For my src/Managers/Globals.php
file I only updated the $posts
var:
Original (Timber 1.0):
public function getVerticalMenu($vertical) {
// other code
$posts = new Timber\PostQuery([
// other props
]);
// other code
}
Updated (Timber 2.0):
public function getVerticalMenu($vertical) {
// same code
$posts = Timber::get_posts([
// same props
]);
// same code
}
src/Models/TileArchive.php
I left the constructor, removed the $className
param and called the parent init
function instead of __construct
:
Original (Timber 1.0):
public function __construct($options, $query = false, $class = 'Engage\Models\Article')
{
parent::__construct($query, $class);
}
Updated (Timber 2.0):
public function __construct($query = false, $options')
{
parent::init($query, $options);
}
I hope that helps. I tried to outline everything I changed to get it working. Let me know if you have any other questions.
We are updating our theme from Timber 1.0 to 2.0 but we cannot seem to get past the
Call to protected Timber\Post::__construct()
error.We are trying our best to follow the Upgrade to 2.0 docs (extending Timber, class maps, etc.)
Main point in our code where the issue lies (the links ex. /archive.php: are to the repo code):
/archive.php:
src/Models/Archive.php:
functions.php classmap
Managing Timber with composer & using Timber 2.x-dev.
If I did not provide enough info/code/error logs please let me know and I will update the question. Any help is very much appreciated.