Attribute as shortcode

Hello, greetings from Spain.
I will like to put an attribute as a shortcode so I can handle and use it in the listing template.
I found this snippet but I can’t figured out where to put my shortcode in order to show the attribute in the frontend. I tried to put it in the shortcode block but with no results, by the way, my attribute field name is “precios”, so I put [precios] in the shortcode block, but the frontend shows the same “[precios]”, and should show a list of prices as the attribute value.
I don’t know if it is possible, to put an attribute as a shortcode so I can located it anywhere in the listing template, in case not, what exactly do the snippet above?
Thanks in advanced and Happy New Year for everybody.
Regards.

add_filter(
 'hivepress/v1/templates/listing_view_page/blocks', 
 function($blocks, $template) {
  $listing = $template->get_context('listing');
  
  if(!$listing){
   return $blocks;
  }
  
  $custom_attribute = $listing->get_precios();
  
  if(!$custom_attribute){
   return $blocks;
  }
  
  return hivepress()->template->merge_blocks(
   $blocks,
   [
    'page_content' => [
     'blocks' => [
      'custom_short' => [
       'type' => 'content',
       'content' => do_shortcode('['.$custom_attribute.']'),
       '_order' => 80,
      ],
     ]
    ]
   ]
  );
 },
 1000,
 2
);

Hola compadre !

I am not sure I can help you here, as this type of coding is new and quite cryptic to me, though I have been developing for two decades now. I am really interested in getting to know how to handle it better though. For the moment, it seems like I am mostly trying to “game the system”.

Incidentally, yesterday I was facing a similar problem.
So I managed to create a shortcode displaying some custom attributes in my custom templates.

Basically, I retrieve the current user id from the context (from the vendor / listings being displayed, not being connected). From there I go down the SQL tree to gain access to the value stored in the database. It may break all the rules implemented by the MVC framework, but it works ! The good old way. Oldies but goldies.

Here’s a sample code :

function get_portfolio_urls(){
	$current_user = wp_get_current_user();
	global $wpdb;
	$attr_name = "hp_url_%"; //my attributes are hp_url_1, hp_url_2 etc...
	
	$query = $wpdb->prepare(
		"
		SELECT pm.meta_value
		FROM (({$wpdb->postmeta} as pm 
		INNER JOIN {$wpdb->posts} as p
		on p.id = pm.post_id) 
		INNER JOIN {$wpdb->users} as u
		on p.post_author = u.id) 
		where pm.meta_key LIKE '". $attr_name ."' and u.id=%d
		",
		$current_user->ID
	);

	// Execute the query
	$results = $wpdb->get_results($query);

	// Check and output results
	if (!empty($results)) {
		$output ="<h2>Mon travail</h2>";
		foreach ($results as $result) {
			//return ;
			$url  = esc_attr($result->meta_value); 
			$output .='<a href="' . $url . '" title="' . $url . '" target="_blank" class="portfolio-url"><img alt="' . $url . '" src="https://lancelo.fr/thumbs/?url='. $url  .'" height="225" width="400"/></a>';	
		}
		return $output; 
	}	
}
add_shortcode('urls', 'get_portfolio_urls'); //use case : [urls]

Conversely, I found out yesterday, that you can use your own shortcode in attribute UI table, which was a great aha moment :

It seems this HivePress framework is quite powerful, but a whole new world for me.For the moment, it’s mostly a trial-and-error / learning-by-doing process.

But the support looks great which is a consolation.

Hope this helps.

1 Like

¡Hola amigo cotasson!

First of all, thank you for try to help me with this issue.

I’m not very good with coding, I can understand it a little bit, but your answer sounds complicated for my coding skills, anyway, I’m studying your code deeply, trying to understand it line by line in order to evaluate its application.

I’m more a frontend designer so I manage myself better with CSS, and in case someone else is looking for an answer to this problem, I just put the attribute in a block, attributes secondary block for example, put the block in the template design, and in case I need an attribute of this block on a different position, I just put again the same block in the new location, grouped it, add a unique CSS class or ID, and then display or not the attributes needed with CSS (display: none, for example). You also can put them on a flexbox div and change the order position.

It works, but this is not an elegant solution I think, the best one should be to put any attribute in a shortcode and could be located anywhere on the template, let see if the Hivepress support team have a best and elegant way to achieve this.

Thank you, best regards.

Another quick-and-easy (dirty?) solution would be to place in the block (primary / secondary…), as you know and then move it to another place, it’s called DOM manipulation.

So basically, you have an HTML nested in the primary block for instance, and you want to embed it in another element in the page, or next to an element in the page.

You do it with javascript. I am a big fan of jQuery for this.

Here a video tutorial about it.

abrazos

Sorry for the delay.

Please clarify the required result, do you want to use the attribute value as a shortcode (e.g. to allow users input shortcodes to the attribute field), or you mean just inserting a single attribute anywhere in the listing layout? If so, I can provide a code snippet for this, but there’s also a way to do this using the Attributes blocks (although in this case you’re limited to 3 display areas, each Attributes block shows attributes assigned to the current display area).

Hello!

I use shortcodes extensively, also to display custom attributes wherever I need. Try installing a plugin to insert code snippets, like WP Code Lite or “Code snippets”. You can also write the PHP/HTML code directly into the Wordpress “Custom HTML” block I believe, but it’s easier with those plugins.

Create a PHP snippet and insert the shortcode from WP Code into the listing template. Try this to get the data (adjust as needed):

$listing_id = get_the_id();  //Gets the post ID, which is the listing ID when on the listing page

if ( !$listing_id ){
	return;
}

$listing=\HivePress\Models\Listing::query()->get_by_id($listing_id);  //Finds the respective listing object

if (  !$listing ){
	return;
}

$custom_attribute = $listing->get_precios();  // Gets your attribute

if ( !$custom_attribute ) {
	return;
}

echo $custom_attribute;  //Display wherever you want

You can also echo the html code with styling included to avoid using CSS. I’m not sure what’s more efficient. Like this

echo '<div style="display:block; background-color:blue; ....> ' . $custom_attribute . 'rest of div....close div ';

As an aside, @ihor , when I know the listing ID, is there a way to get the exact listing object without having to query/loop the database every time?

Hope this helps!

1 Like

Hello Ihor.
Yes, I mean to insert a single attribute anywhere in the listing layout. I found and try the snippet in my first post, but with the result I explain there, which mean, no results.
Please, can you provide the snippet and how to use it? I mean, should be inside a shortcode block, which I already use without luck, or inside a Custom HTML block?
Thanks in advance. Regards.

Thank you Jay 3, awesome!
The snippet should be inside an add filter() or a function? Just by itself I don’t know how to apply it, I use to put the snippets in the php file of the child theme, but it usually comes inside a filter or a function.
Being able to put an attribute anywhere in the template through a shortcode can give you a complete design freedom.
Thanks again, regards.

Hello again @edosantillana,

To proceed with my findings, as I wrote earlier, you can append a shortcode to an existing attribute

…and move it anywhere you want in the page.

I will try to show where I am at so far, as it could be helpful to you too.

So basically, I am not really interested in showing since when the vendor is registered, but I want to show when he connected for the last time on the website instead.

.

My [lastlogin] returns something like this :

<div class="last-login">Dernère connexion : il y a 11 heures</div>

At it is appended to an existing attribute (first screenshot).
With CSS I just hide it.

.last-login{display:none;}

Then comes the fun part, I copy the content of my last-login DIV in lieu of “Member since…”.

To achieve this, I iterate with jQuery over each dontaining element (I am in the Vendors page, so there are several .hp-vendor__content), and do exactly as I said : replace the content (text) of the “member since” by the one from hidden last-login DIV, via DOM manipulation.

Here’s the jQuery code :

jQuery(document).ready(function($) {
	$( ".hp-vendor__content" ).each(function( index ) {
  		$( this ).find('.hp-vendor__registered-date').text(
			$( this ).find('.last-login').text()
		);
	});
}); 

And here’s the result :
image

Hope this helps.

1 Like

Hey,

if you use the WP Code plugin, it will let you create PHP, Javascript, Html, CSS, and other snippets.

You can write a PHP snippet and let the plugin transform it into a shortcode by itself.

Then you simply copy the shortcode it throws and you paste it in the listing template or wherever using the “Shortcode” block from the Wordpress editor itself. There is no need to include it into a filter function or anything. Simply write the code I wrote before in a php snippet (check for errors first) and it will execute in the page you put the shortcode.

This saves you having to tinker with child themes, and it also lets you re-use the same shortcode for different pages.

Saludos!
PS: I am not a WP Code developer :slight_smile: but that plugin saved my life!

1 Like

Thanks for sharing! @Jay3 @condorito.fr

@edosantillana You can also try this snippet, it adds a shortcode which accepts the attribute name (e.g. [hivepress_listing_attribute name="attribute_name_here"]) and displays the attribute value (note that it works within the listing page template only):

add_shortcode(
	'hivepress_listing_attribute',
	function( $atts ) {
		if ( ! isset( $atts['name'] ) || ! is_singular( 'hp_listing' ) ) {
			return;
		}

		$listing = \HivePress\Models\Listing::query()->get_by_id( get_the_ID() );

		if ( ! $listing ) {
			return;
		}

		return call_user_func( [ $listing, 'display_' . $atts['name'] ] );
	}
);

Hope this helps

Great, that snippet made the trick, works awesome.
Thank you @ihor, and also thank you @condorito.fr and @Jay3 for your help, great community, I will post the website once its finished.
Best regards.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.