Should I use $post = Timber::query_post() or $post = new TimberPost() in single wordpress template? - wordpress-theming

I've read on the official Timber repository that general question about usage should be posted here.
I'm new to Timber/Twig and I have a a very "basic" question.
On the starter theme I've seen that in the single.php the $post variable that get passed to the $context is setted up with
$post = Timber::query_post()
while the page.php it is setted up with
$post = new TimberPost();
So, when I need to setup a single-cpt.php what method should I use? Timber::query_post() or new TimberPost()?
I've tried both of them and both of them are working, but what's the right way to do it?
Thanks!
PS: I've seen that in the index.php the $context['post'] is being setup with new Timber\PostQuery(). Does this basically reproduce the standard loop of the template hierarchy?

I understand there can be quite some confusion about which methods to use. Currently, there are a lot of ways to do it, and all that you’ve tried should work.
With the upcoming version 2 of Timber, we try to unify this and we will deprecate some of the methods that are still around. So, here’s how you should do it from now on.
Update March 2020 – We’ve gone back and forth as to how the new API for 2.x should like and we’ve come up with a solution that is pretty much fixed. Some things will change there, you can check out this pull request if you want to learn more.
Until then, here’s our recommended way of doing things:
Get a single post
$post = new Timber\Post();
$post = Timber::get_post();
Get a collection of posts
$post = new Timber\PostQuery();
$post = Timber::get_posts();
If you want to use pagination with your posts, you will still have to use Timber\PostQuery:
$post = new Timber\PostQuery();
(In Timber 2.x Timber::get_posts() will work with pagination, but not in 1.x yet.)
The standard loop
I've seen that in the index.php the $context['post'] is being setup with new Timber\PostQuery(). Does this basically reproduce the standard loop of the template hierarchy?
Yes!
In fact, if you don’t pass any arguments to PostQuery(), you don’t even have to set $context['posts'], because Timber does that already for you in Timber::get_context().
index.php
<?php
use Timber\Timber;
$context = Timber::get_context();
Timber::render( 'index.twig', $context );
Use namespaced class names
Currently, you might still see TimberPost() instead of Timber\Post(). For version 1, all Timber classes were namespaced, so the recommended way to do it from now is to use the namespaced class names in PHP, e.g. Timber\Term instead of TimberTerm.
But! In Twig, you’d still use the non-namespaced version:
{% set post = Post(post_id) %}
or
{% set post = TimberPost(post_id) %}
I hope this clears things up.

Related

Windsor WcfFacility: Setting ServiceBehavior properties

I'm hosting a service using Windsor's WCF Facility, but I can't get UseSynchronisationContext and ConcurrencyMode set that one would normally do using the ServiceBehaviorAttribute. I've seen two options that apparently should work (but tried both to no avail):
Registering ServiceBehaviorAttribute as a Component for IServiceBehavior
Modifying the Description collection of Behaviors in the OnCreated configuration callback in the WCF registration.
A third method that I've tried is using AddExtensions, but that results in an exception because there's already a ServiceBehaviorAttribute (by default?) in the list of Behaviors. This is also the case with method 2, but in that case I can remove it and add a new one, or modify the existing entry.
It's really frustrating that there doesn't seem any documentation on this except a line stating 'Remove the ServiceBehaviorAttribute' from your services, apparently because it can conflict with the WcfFacility.
Can someone point me on how to properly do this? Any hint is appreciated!
Unfortunately I didn't properly test. Modifying the properties of the ServiceBehaviorAttribute in the list of Behaviors of the Description property in the OnCreated action actually works as intended.
Sample registration:
container.Register(Component.For<IWCFWarehouseServiceAsyncCallback>()
.ImplementedBy<WarehouseService>()
.AsWcfService(new DefaultServiceModel()
.AddBaseAddresses(baseAddress)
.OnCreated(host =>
{
var sb = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
sb.UseSynchronizationContext = false;
sb.ConcurrencyMode = ConcurrencyMode.Reentrant;
})
.AddEndpoints(WcfEndpoint.BoundTo(binding).At("WarehouseService"))));

Google Contacts API with Yii2

I am trying to use the Google contacts api from within Yii2.
Google provides a composer interface, so I added
"google/apiclient": "1.0.*#beta"
to my composer.json and did "composer update"
Now - how do I actually use this from within my Yii2 controller?
I have a working, standalone test script that works. In that, it does
require_once 'GoogleClientApi/autoload.php';
$client = new Google_Client();
However, this does not seem to work from Yii.
I've tried adding the require to my index.php file, as follows (copying autoload.php from a previous installation since autoload doesn't seem to come with the composer version - why would this be omitted?)
require(__DIR__ . '/../vendor/google/apiclient/autoload.php');
but this results in the following error when called in my controller:
Call to undefined function app\controllers\Google_Client()
I've read the post on http://www.yiiframework.com/doc-2.0/guide-tutorial-yii-integration.html but this doesn't make much sense to me.
Any help appreciated. Thanks
Your code is almost correct:
require_once 'GoogleClientApi/autoload.php';
$client = new \Google_Client();
The "\" is needed to indicate the class exists in the global namespace, as you are - in that piece of code - under the app\controllers namespace.

Generating an html link in CakePHP 2.2.1+?

How can I easily generate an HTML link, using the HtmlHelper class in CakePHP 2.2.1?
Imagine I declared a route that routes /finest-perfumes-ever-2012 to the Perfumes/Index Controller/Action.
I need this generated link to be:
somedomain.com/finest-perfumes-ever-2012 //Generate link HAS to obey Routes I've set.
Instead of:
somedomain.com/Perfumes/Index
The documentation doesn't seem to do much of a good job explaining how to achieve this.
Not sure if you have missed out the 2012 by accident or your question is more complicated than my answer below. Assuming the 2012 doesn't matter:
Cake makes use of quite a nifty feature - reverse routing.
If you've set up everything correctly, the following should output what you want.
<?php
Router::connect(
'/finest-perfumes-ever',
array('controller' => 'perfumes', 'action' => 'index')
);
echo $this->Html->link('View Finest Perfumes!', array('controller'=>'perfumes',
'action' => 'index'));
Providing your URL (when created using the HTML helper) has parameters that match the route exactly, the reverse routing will look up what you want the route to be, and output links accordingly.
If the 2012 is important you could probably get this working by passing parameters - there are some examples here
Define route configuration into your app/Config/routes.php at the last of all routing statements.
You can do the same by passing an argument to the action and define it in your routes.php file.
Kindly ask if it not worked for you.

Is it reasonable to modify the $post variable in Wordpress during the loop?

So I'm starting to write a Wordpress theme, and I'm trying to pass some variables from The Loop in my index.php to my actual content renderer in content.php.
Due to scope issues, I can't just create a variable in index.php then try and access it in content.php. The idea of using global makes me shudder, so I thought perhaps I'd tag it onto the $post variable (which is already global). Is this a standard practice? Is there any reason I wouldn't want to besides accidentally modifying a standard $post member var? Is there a idiomatic Wordpress way to do this?
Here is an example of my index.php:
$post->is_n = false; # bad idea?
if($post_number === $n){
$post->is_n = true
}
get_template_part( 'content', get_post_format() );
Then in my content.php:
if($post->is_n){$article_classes .= " is-n";}
The $post variable already is a global within WordPress so creating or not creating another global to pass the value would really just be a matter of style more than anything else. WordPress makes pretty extensive use of global values on its own, given its genesis in pre-OOP PHP 4.x days.
Attaching the value to $post would work, however there's a chance the $post object won't be completely destroyed between loop iterations, so your custom property may end up on a later iteration of the $post variable and potentially cause unintended side effects if you are not careful. As well, you'd have to be sure to namespace the property appropriately as to not conflict with future WordPress changes to $post.
Creating a new global to pass the variable wouldn't be out of the ordinary within WordPress, attaching custom properties to the $post variable would be a little unusual. If you wanted to namespace things and keep your values out of $_GLOBAL, you could create a quick registry class, but that may be overkill in this case.
Modifying the $post variable is common, though I would probably choose a different design then the one you describe. But as one is learning one must find these things out for him self :^)
When you have modified the $post variable you can call upon wp_reset_postdata function. This is more commonly used when you play with the WP_Query object.

.get mootools method not working in joomla 1.5

i have a problem in joomla 1.5.18. i'm trying to get text from an element using for instance
var divContent = $$('#myDiv').get('text');
but each time i get the error, in chrome: Uncaught TypeError: Object #<HTMLDivElement> has no method 'get'; in firefox: divContent.get is not a function. why i'm getting this error?
even following samples in mootools i get the same.
i know how to do it for each object in the collection. i got doing $$('.') and using the "each" method:
$$('p.classname').each(function (el){
el.addEvent('click', function() {
var txt = el.get('text');
...
});
});
and obviously i add the function onto domready. i don't use jquery 'cause mootools & jquery stops the events each one... -i tried once & what i needed didn't work- and i wish to use all joomla resources including mootools.
checking the version in mootools.js it says 1.13 (?)
not sure which version of mootools comes in joomla 1.5.18, it may be 1.2.5. if so, .get should work but not as you expect it to.
You are probably a jquery user, used to $("#myid") and find that the only way to get similar results with the # in there in mootools is via document.getElements, aka, $$.
the problem is, to get a single item by id in mootools, you actually do document.id("mydiv") or even $("mydiv"). $$("#mydiv") will actually return a COLLECTION of elements with a single member, so [obj], so the real element is $$("#mydiv")[0].
if you apply a .get method to a COLLECTION, the getter normally iterates via a .each through all members and performs the get individually. it will return a new array member for each member of the collection - i.e. ["innertext"]; - though there should be a method for the collection, make sure that the element is there, it's in domready / onload and it's a unique id.
Still, I'd swap to using the $("mydiv").get("text"), it ought to be fine. This is all all too common assumption of jquery users that don't read the manual, in my experience. It results in bad and un-performant code due to all the .each iterations mootools has to silently do to work with the collection for you. Just saying.
You can also (and should) upgrade your Joomla to the latest version (security fixes, etc) and I believe it was about version 1.5.20 they included a newer version of mootools right out of the box (also there is a plugin for mootools upgrade you can enable). I believe the version included out of 1.5.20 is like 1.2.5 or something...
That may help!