Timber: Access Advanced Custom Field From Another Page - php

I am trying to access ACF data from another page to be displayed on another using Timber (Twig).
The ACF name is the_unstrung_hero in the "About" page (id = 7).
page-home.php:
<?php
$context = Timber::get_context();
$post = new TimberPost();
$about_page_id = 7;
$about = new TimberPost($about_page_id);
$about->acf = get_field_objects($about->ID);
$context['post'] = $post;
Timber::render( array( 'page-' . $post->post_name . '.twig', 'page.twig' ), $context );
Within page-home.twig:
<p>{{ acf.the_unstrung_hero|print_r }}</p>
This is just the last combination attempt of many. Frankly I am just not getting something (PHP is not a forte of mine)... Your help will be greatly appreciated.

In your example above, I see that you get the field data from the about page, but you’re not adding it to the context. Your template doesn’t display that data, because you didn’t hand it over to the template.
You set up your context first:
$context = Timber::get_context();
Then you get the current post data that should be displayed:
$post = new TimberPost();
Now you did load $post, but it’s not in your context yet. You have to put the data you want to display on your page into the $context array. Then you render it trough Timber::render( 'template.twig', $context ). Your Twig template will only contain data that is is present in $context (to be complete: you can also use functions in your Twig templates to get data, but that is another topic).
To also add the data you loaded from the about page, you’d have to do this:
$about_page_id = 7;
$about = new TimberPost( $about_page_id );
$context['about'] = $about;
See that the line $about->acf = get_field_objects($about->ID) is not there anymore? You don’t need it, because Timber automatically loads your ACF fields into the post data. Your field would now be accessible through {{ about.the_unstrung_hero }} in your Twig template.
To come back to what you want to achieve:
I’d solve it like this.
Like Deepak jha mentionend in the comments of your question, I’d also make use the second parameter of the get_field() function to get field data from a post by post ID.
You don’t really need to load the whole post of the about page if you just want to display the value of one ACF field.
page-home.php
$context = Timber::get_context();
$post = new TimberPost();
$context['post'] = $post;
// Add ACF field data to context
$about_page_id = 7;
$context['the_unstrung_hero'] = get_field( 'the_unstrung_hero', $about_page_id );
Timber::render( array( 'page-' . $post->post_name . '.twig', 'page.twig' ), $context );
And then in within page-home.twig you can access the field data in post.
<p>{{ the_unstrung_hero }}</p>

Related

Dinamically create a link using ACF (Advanced Custom Field) custom value

I'm trying to create a custom link based on a custom field, something like this:
<a href='htts://wa.me/55[acf field="phone-number"]?text=more%20text%here'>Whatsapp</a>
Maybe creating another shortcode loading de ACF field, but I don't know how do that.
I've tried do customized the following code, but without success:
function diwp_enclosed_shortcode_social_links($attr, $content){
$args = shortcode_atts( array(
'url' => '#',
'color' => '#F0F',
'textsize' => '16px'
), $attr );
$output = ''.$content.'';
return $output;
}
add_shortcode( 'enclosed_social_links', 'diwp_enclosed_shortcode_social_links' );
Hello as explained in the documentation you can load the acf field just by adding the id of the post it is associated with:
$value = get_field( "phone-number", 123 );
You can find the post id in the url on the edit post in the backend for example: https://your-url/wp-admin/post.php?post=161&action=edit
In that case we will get the phone-number from the post 161 and it should all be set, if the whole thing need to be done dynamically then we can just use get_field() because we should be in the page in which the field is saved.
Merry christmas!
I solved my problem with the following code:
function numero_whatsapp_dinamico( $attr ) {
$post_id = $attr['post_id'];
$phone_number = get_field( 'numero_de_whatsapp', $post_id );
$output = '<a class="botao-whatsapp-estabelecimento" href="https://wa.me/55' . $phone_number . '?text=more%20text%20here" ">Whatsapp</a>';
return $output;
}
add_shortcode( 'numero_whatsapp_estabelecimento', 'numero_whatsapp_dinamico' );
Hope It'll help someone else with the same problem.

How do I get and set Advanced Custom Fields data as a variable in Timber $context to use in a post query?

I want to get and set the value of an ACF field into a variable in my home.php file and then use this as part of a query.
So, for example, if a user enters the word 'event' in the the field 'cat_name' in the CMS, I wanted to get and set this as a variable and then use this as part of a basic query to return all posts with a category of event..
What I have at the moment is below. How do I access ACF data in home.php / $context and then store it in the $my_var variable. Is this possible?
<?php
$context = Timber::get_context();
$context['post'] = new Timberpost();
$my_var = get_field('cat_name');
$context['posts'] = Timber::get_posts(array(
'post_type' => 'post',
'category_name' => $my_var
));
Timber::render('home.twig', $context);
?>
You need to get the field value with the TimberPost method get_field() :
$my_var = $context['post']->get_field('field_name');

Retrieve meta field values of ACF flexible content items using get_post_meta - WordPress

Thanks for your help in advance. Here's what I'm trying to achieve:
I have a custom post type called 'Campaigns' and I have a custom taxonomy called 'Countries' that is related to the campaign custom post type. When a user adds a new country to a campaign a new campaign post is generated that is the child of the current campaign. I'm duplicating the ACF fields that are assigned to the parent campaign and replicating the values in the child post, however I've run into an issue using the ACF flexible content fields. Here'a snippet of my code that is retrieving the parent post fields and updating the newly created ACF field in the child post with that value.
$action_text = get_post_meta($parent_id, 'action_text', true);
update_field('action_text', $action_text, $post_id);
I've tried doing this with flexible content, but I know I need to loop through and find what content blocks have been created. What is the best way to go about this?
// About Fields
$about_fields = get_post_meta($parent_id, 'content');
var_dump($about_fields);
$meta_key = // How to retrieve the flexible content keys
$meta_value_of_flexible_content = get_post_meta($parent_id, $meta_key);
if($about_fields) {
}
For clarification 'content' is the flexible container name. 'text_and_image' is an example name of one of the flexible content blocks I've created.
Thanks again for any insights.
I've tried doing this with flexible content, but I know I need to loop
through and find what content blocks have been created.
You could just use the get_field() and update_field() functions to duplicate any ACF fields, including Flexible Content fields.
So for example, to clone the whole content field:
$about_fields = get_field( 'content', $parent_id );
if ( $about_fields ) {
update_field( 'content', $about_fields, $post_id );
}
// How to retrieve the flexible content keys
foreach ( $about_fields as $arr ) {
echo 'Layout: ' . $arr['acf_fc_layout']; // e.g. "Layout: text_and_image"
// The rest of items in `$arr` are the SUB-fields of that specific layout as
// identified by the `$arr['acf_fc_layout']`, which is the layout's name. So
// if you have two SUB-fields named `text1` and `image1` respectively, then
// these items are set: `$arr['text1']` and `$arr['image1']`
}
Additional Code
To clone all ACF fields:
$fields = get_fields( $parent_id );
foreach ( $fields as $name => $value ) {
update_field( $name, $value, $post_id );
}
Additional Note
I'd change this to use the get_field() function:
$action_text = get_post_meta($parent_id, 'action_text', true);
So:
$action_text = get_field('action_text', $parent_id);

Get post ID in variable in Grid Builder Visual Composer

I’m trying to get some custom fields inside my custom grid builder. I have added some extra taxonomy and would like to add custom data to display. I’ve read your article here: https://kb.wpbakery.com/docs/developers-how-tos/adding-custom-shortcode-to-grid-builder/ and when implementing it, I’m getting a problem when trying to get the id of the current post ID. I know the code is as follows:
add_shortcode( 'vc_post_id', 'vc_post_id_render' );
function vc_post_id_render() {
return '<h2>{{ post_data:ID }}</h2>'; // usage of template variable post_data with argument "ID"
}
The thing is that the {{ post_data:ID }} cannot be saved to a variable to later get the post and play with it as such:
$post_id = '{{ post_data:ID }}';
$post = get_post($post_id);
as it will fail. Could you please tell me how to get the current post ID as a variable so I can show custom data on the grid?
Thank you very much.
Ok, here what I'm thinking. In my scenario, I have a custom field called price.
So I was able to show the price by using
{{ post_data:price }}
This. But when I was trying to assign it to a variable, it failed. When I var_dump the variable it gives me (21) characters for every time. So I thought there must be invisible characters. so I
echo bin2hex($price)
The result was 7b7b20706f73745f646174613a7072696365207d7d
And after ASCII to text conversion, it became this
{{ post_data:price }}
Then I realized it. Oh silly me. These are template tags. Like in smarty or angular. They injected values once the page has loaded. So PHP doesn't have a chance get value because everything happening on the client side.
you need to create vc_gitem_template_attribute_YOUR_ATTRIBUTE and there you can take id. like this:
add_filter( 'vc_gitem_template_attribute_producer_logo', 'vc_gitem_template_attribute_producer_logo', 10, 2 );
function vc_gitem_template_attribute_producer_logo( $value, $data ) {
extract( array_merge( array(
'post' => null,
'data' => '',
), $data ) );
$termini = get_the_terms( $post->ID, 'producer' );
$logo = get_field('prlogo', $termini[0]);
$image = '<img class="img-prod" src="' . $logo . '">';
return $image;
}
and render
add_shortcode( 'producer_logo', 'vc_producer_logo_render' );
function vc_producer_logo_render($atts, $content, $tag) {
return '{{producer_logo}}';
}

Display specific posts on pages in WordPress

In the website every product is a post, but when we add new products we want something like a newsletter, mostly like a post so in the sidebar of the home page you can see the new products or events of the month.
I'm using pages because I don't want to re-post a product on every new newsletter so I junt wanna display the posts inside the page.
In the products page I separate every product by category and sub-category but since I want to group specific post to publish them on the sidebar I think that pages was the best way to do it.
Right now I'm using this code:
<?php
$productos = new WP_Query(array(
'post__in'=> array(81, 83),
'orderby'=>'title',
'order'=>'ASC'
)
); if ($productos->have_posts()) : while ($productos->have_posts()) : $productos->the_post();
?>
It display the posts with the id of 81 and 83, I would like to show post by slug using 'name' as the codex says because is going to take some time to be checking the ids of the new post, instead of using the name of every new product but It doesn't work in array or I'm doing something wrong.
Now I will love to make something like this work
$names = get_post_meta($post->ID, "names", $single = true);
$productos = new WP_Query(array(
'name'=> array($names),
'orderby'=>'title',
'order'=>'ASC'
)
);
So every time I publish a new page I just write the slugs of the posts that I want to include in the page in a custom field, as you can see I'm not very good with php but I trying to learn and I search a lot for something that could work before asking in here.
I try the ggis inline post plugin and although it works I need the id for every post I want to include and I will need to edit the plugin because I want a different order in the output of the post thats why I don't like to depend to much on plugins.
Update:
So I'm now looking if I can make this using shortcodes, right now I have this:
function producto_func($atts) {
extract(shortcode_atts(array(
'nombre' => ''
), $atts));
global $post;
$pieza = get_page_by_title($nombre,OBJECT, 'post');
echo '<h1>'. $pieza->ID . '</h1>';
}
add_shortcode('producto', 'producto_func');
enter code here
So I just enter the shortcode [producto nombre="ff 244"] in the page and it show its ID, and I can add any number of shortcodes depending on the number of post I need.
But how can I show the entire content of the post.
Any idea?
I find I solution using Shortcodes.
So I put this on my functions.php page
function productos($atts, $content = null) {
extract(shortcode_atts(array(
"slug" => '',
"query" => ''
), $atts));
global $wp_query,$post;
$temp = $wp_query;
$wp_query= null;
$wp_query = new WP_Query(array(
'name'=> $slug,
));
if(!empty($slug)){
$query .= '&name='.$slug;
}
if(!empty($query)){
$query .= $query;
}
$wp_query->query($query);
ob_start();
?>
<?php while ($wp_query->have_posts()) : $wp_query->the_post(); ?>
<h1><?php the_title(); ?></h1>
<div><?php the_content() ?></div>
<?php endwhile; ?>
<?php $wp_query = null; $wp_query = $temp;
$content = ob_get_contents();
ob_end_clean();
return $content;
}
add_shortcode("producto", "productos");
And in my page template I just write [producto slug="MY-SLUG"] and that way I can display multiple post just with the slugs. Hope someone find this useful.
From the Wordpress Codex:
Display post by slug:
$query = new WP_Query( 'name=about-my-life' );
Display page by slug:
$query = new WP_Query( 'pagename=contact' );
UPDATE
Try changing this:
'name'=> array($names),
To this:
'name'=> $names,
The 'name' - and 'pagename' - parameter does not take in an array. Only a string. A comma delimited list SHOULD give you what you need from within your Custom Fields titled "names", though I haven't tested this approach.
Also, thank you for using WP_Query instead of query_posts.

Categories