Dynamic meta titles for pages with URL parameters? - php

I've got a page called /team-page/?id=x that's built in WordPress
The URL parameter of "id" determines the content that will dynamically show on that page. However, my meta title for that page is statically set. Is there a way I can dynamically set the meta title based on the page content? Each variation of /team-page will have a unique H1 - ideally, I'd love to just grab this H1 and set it as the meta title.

You can achieve it with document_title_parts filter. It takes $titles as parameter, which consist of two parts - title and site (except for front page - instead of site it's tagline)
So try this
add_filter( 'document_title_parts', 'custom_title' );
function custom_title( $title ) {
// Just to see what is $title
// echo '<pre>';
// print_r( $title );
// echo '</pre>';
// die();
$uri = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ); // get current uri without query params
// Change meta only on team-page.
if ( '/team-page/' === $uri ) {
// you can do here anything you want
$title['title'] = get_the_title() . ' and whatever string you want ' . $_GET['id'];
}
return $title;
}
Also don't forget to check and sanitize your $_GET['id'] if needed.

You're looking for get_query_var()
Retrieves the value of a query variable in the WP_Query class.
Source # https://developer.wordpress.org/reference/functions/get_query_var/
One small thing to understand is that get_query_var() only retrieves public query variables that are recognized by WP_Query.
So we need to register our variable first. This is considered best practice. Simply using $_GET['id'] is considered to be unsafe within the Wordpress ecosystem.
add_filter( 'query_vars', 'wpso66660959_query_vars' );
function wpso66660959_query_vars( $qvars ) {
$qvars[] = 'ref';
return $qvars;
};
Also you should use something other than id as it is already used by Wordpress to handle the WP_Query. I've used ref (reference) but you can choose whatever as long as it doesn't impact Wordpress core.
then we can simply built our custom title.
<?= '<title>' . get_the_title() . ' | Order N° ' . get_query_var( 'ref', 'undifined' ) . '</title>'; ?>
Note that, if your theme is using Wordpress to set your pages title, you might need to set some sort of conditional statement around add_theme_support( 'title-tag' );, in your function.php.
Something like...
//...
if ( ! is_page( 'team-page' ) )
add_theme_support( 'title-tag' );
The title-tag is usually included in your theme options.

Related

Adding an ID tag to a post title (Wordpress)

I've been trying for a while to find a way to add an ID tag to a post title by placing a function in a child theme's functions.php file.
I've tried the code below which works well for including an ID for any h1 to h6's that don't have an ID (& leave any that do alone) INSIDE the post content - but I can't find a way to add an ID to the actual displayed post title?
function auto_id_headings( $content ) {
$content = preg_replace_callback( '/(\<h[1-6](.*?))\>(.*)(<\/h[1-6]>)/i', function( $matches ) {
if ( ! stripos( $matches[0], 'id=' ) ) :
$matches[0] = $matches[1] . $matches[2] . ' id="' . sanitize_title( $matches[3] ) . '">' . $matches[3] . $matches[4];
endif;
return $matches[0];
}, $content );
return $content;
}
add_filter( 'the_content', 'auto_id_headings' );
I was thinking it was as simple as changing the_content in the "add_filter" part of the code to the_title but that hasn't worked! FYI the page I'm trying to do this on is here: https://www.futureproofpromotions.com/reaction-form/
Can anybody help?
I've included a screenshot of the page's chrome developer tools explaining what I'm trying to achieve below:
hook the_content return all post content (include HTML), but hook the_title return you value from post_title field (wp_post table).
So if you want to add tag id to id or class DOM element you need make changes in your child theme:
1. copy single.php (or another page template where you need make changes) in your child theme
2. find the place with the_title() function
3. change h1 class (add your function)

WordPress query string to change SEO friendly URL

I want to create SCO friendly URL in the WordPress. Also, I have added a hook in my functions.php file as below code but not working.
My URL:http://bddlabs.com/webinar01/?id=pzlyglhbepotwpvbigdatadim_data&storyid=Story_997e9391-71d7-4fac-804b-de891c7aa595
I want http://bddlabs.com/webinar01/pzlyglhbepotwpvbigdatadim_data/Story_997e9391-71d7-4fac-804b-de891c7aa595
Is it possible? I am not sure about it. URL query string is coming from the third party, URL query string is coming from the third party, page content render based on query string.
Below code added landing-page-15.php it WordPress theme base page template
function fb_change_search_url_rewrite() {
if ( ! empty( $_GET['storyid'] ) ) {
wp_redirect( home_url( "/webinar01/" ) . urlencode( get_query_var( 'storyid' ) ) );
load_template( realpath(__DIR__ . '/..') . '/landing-page-15.php' );
exit();
}
}
add_action( 'template_redirect', 'fb_change_search_url_rewrite' );
//additional rewrite rule + pagination tested
function rewrite_search_slug() {
set_query_var('storyid', $_GET['storyid']);
add_rewrite_rule(
'find(/([^/]+))?(/([^/]+))?(/([^/]+))?/?',
'index.php?id=$matches[2]&storyid=$matches[6]',
'top'
);
}
add_action( 'init', 'rewrite_search_slug' );
You may consider using WordPress builtin permalinks option located in Settings tab.
Set %category%/%postname%/ so that permalink should work as per your requirements.
When posting new content, select a sub category and put post title the same you want to appear in your permalink.
Hope it answers your question.
Wordpress can do this by default. https://codex.wordpress.org/Using_Permalinks

Moving Page/Post Titles outside the Loop in WordPress

I have a client site running on WordPress. It uses WooThemes Canvas as its base theme (with a customized child theme), and utilizes the Time.ly All-in-one-Event Calendar. It can be viewed here.
The design I came up with required me to move the page/post titles outside the main content area. I followed the instructions on this WooThemes customization document, and made modifications based on the comments so that it would also work for posts and the Time.ly event postings. The entries in my functions.php file looked like this:
add_filter( 'the_title', 'woo_custom_hide_single_post_title', 10 );
function woo_custom_hide_single_post_title ( $title ) {
if ( is_singular( array( 'post', 'ai1ec_event' ) ) && in_the_loop() ) { $title = ''; }
return $title;
} // End woo_custom_hide_single_post_title()
add_filter( 'the_title', 'woo_custom_hide_single_page_title', 10 );
function woo_custom_hide_single_page_title ( $title ) {
if ( is_page() && in_the_loop() ) { $title = ''; }
return $title;
} // End woo_custom_hide_single_page_title()
// Add Titles above Content Area on all Posts & Pages
add_action( 'woo_content_before_singular-post', 'woo_custom_add_title', 10 );
add_action( 'woo_content_before_singular-ai1ec_event', 'woo_custom_add_title', 10 );
add_action( 'woo_content_before_singular-page', 'woo_custom_add_title', 10 );
function woo_custom_add_title () {
if ( ! is_page_template(array('template-biz.php', 'template-brewpub.php')) ) {
global $post;
$title = '<h1 class="page-title">' . get_the_title( $post->ID ) . '</h1>' . "";
echo '<div id="title_container"><header class="col-full">';
echo $title;
woo_post_meta();
echo '</header></div>';
}
} // End woo_custom_add_post_title()
This produced some undesirable results, which can be seen on the DEV site I setup for this post (dev.thebrewworks.com):
Since the Time.ly event calendar also uses the_title to display it's events, in the three instances I used the calendar inside a page loop (the homepage and the two restaurant location pages), the event titles don't show up. This was confirmed by creating a Test Page (dev.thebrewworks.com/test-page), where you can see two instances of the calendar inside the loop, and one outside (in the sidebar). The two instances in the Loop have no titles, while the sidebar does.
Supressing the_title in the Loop didn't suppress the Post Meta, which still shows up in the main content area, but I want it under the title in the new DIV, so reposting woo_post_meta outside the Loop leaves me with two instances of the Post Meta.
In order to get the site live I had to make some concessions in my functions.php file:
// Hide Titles on All Posts & Pages
add_filter( 'the_title', 'woo_custom_hide_single_post_title', 10 );
function woo_custom_hide_single_post_title ( $title ) {
if ( is_singular( array( 'post', 'ai1ec_event' ) ) && in_the_loop() ) { $title = ''; }
return $title;
} // End woo_custom_hide_single_post_title()
add_filter( 'the_title', 'woo_custom_hide_single_page_title', 10 );
function woo_custom_hide_single_page_title ( $title ) {
if ( is_page() && in_the_loop() && is_page_template( array('page.php', 'template-contact.php' ) ) ) { $title = ''; }
return $title;
} // End woo_custom_hide_single_page_title()
// Add Titles above Content Area on all Posts & Pages
add_action( 'woo_content_before_singular-post', 'woo_custom_add_title', 10 );
add_action( 'woo_content_before_singular-ai1ec_event', 'woo_custom_add_title', 10 );
add_action( 'woo_content_before_singular-page', 'woo_custom_add_title', 10 );
function woo_custom_add_title () {
if ( ! is_page_template(array('template-biz.php', 'template-brewpub.php')) ) {
global $post;
$title = '<h1 class="page-title">' . get_the_title( $post->ID ) . '</h1>' . "";
echo '<div id="title_container"><header class="col-full">';
echo $title;
woo_post_meta();
echo '</header></div>';
}
} // End woo_custom_add_post_title()
// Disable Post Meta
function woo_post_meta() {}
?>
Note the changes:
I disabled the post_meta completely. Not exactly what I was looking for, but better than having it show up twice.
I modified the function that disables the page title so that it only works on pages that use certain templates (the three instances I mentioned above use the Business Template in Canvas that already suppresses the page title). This would require me to go in and add each new page template that I want to suppress the title on, though...and on top of that, it's not working. Take a look at the live site. The page title is showing up twice on static pages. Once inside the white content area and once outside in the yellow header.
I'm no PHP-developer...I'm more of an Design/HTML/CSS person. I know enough to be dangerous...how to modify existing code, etc., but not necessarily how to write my own from scratch. I have no idea if the way I came up with things is even the best/most elegant way to go about it. Now that you have all the facts, here are my questions:
In an ideal world, the Post Meta would ONLY show up on the blog entries (not on the calendar entries...no need for them there, really), and OUTSIDE the main content area underneath the page title that I moved. How can I achieve this? I'm guessing it's going to be some sort of conditional statement that removes the woo_post_meta from all instances inside the loop, and adds it to the woo_custom_add_title ONLY if it's a standard post, but how to get there I have no idea.
How can I suppress the_title that shows up at the top of the content area on ALL static pages, regardless of template, but have it not affect instances of the_title that appear elsewhere in the loop (like the calendar syndication). In my head there has to be a way to indicate that you ONLY want to disable the_title if it's in a certain div/id, etc., but again...only enough to be dangerous, unless I see it done elsewhere, I can't come up with the solution on my own.
Thanks in advance for your input.

How to modify page title in shortcode?

How do I modify a page title for specific pages in shortcode?
The following will change the title but it executes for every page. I need more control over where it executes.
function assignPageTitle(){
return "Title goes here";
}
add_filter('wp_title', 'assignPageTitle');
Is there a way to call the above in a shortcode function? I know how to use do_shortcode() but the above is a filter.
My goal is to modify the page title based on a URL parameter. This only happens for specific pages.
Although WordPress shortcodes was not designed to do this, it can be done. The problem is shortcodes are processed AFTER the head section is sent so the solution is to process the shortcode BEFORE the head section is sent.
add_filter( 'pre_get_document_title', function( $title ) {
global $post;
if ( ! $post || ! $post->post_content ) {
return $title;
}
if ( preg_match( '#\[mc_set_title.*\]#', $post->post_content, $matches ) !== 1 ) {
return '';
}
return do_shortcode( $matches[0] );
} );
add_shortcode( 'mc_set_title', function( $atts ) {
if ( ! doing_filter( 'pre_get_document_title' ) ) {
# just remove the shortcode from post content in normal shortcode processing
return '';
}
# in filter 'pre_get_document_title' - you can use $atts and global $post to compute the title
return 'MC TITLE';
} );
The critical point is when the filter 'pre_get_document_title' is done the global $post object is set and $post->post_content is available. So, you can find the shortcodes for this post at this time.
When the shortcode is normally called it replaces itself with the empty string so it has no effect on the post_content. However, when called from the filter 'pre_get_document_title' it can compute the title from its arguments $atts and the global $post.
Taken from the WordPress Codex
Introduced in WordPress 2.5 is the Shortcode API, a simple set of
functions for creating macro codes for use in post content.
This would suggest that you can't control page titles using shortcodes as the shortcode is run inside the post content at which point the title tag has already been rendered and is then too late.
What is it exactly that you want to do? Using the Yoast SEO Plugin you can set Post and Page titles within each post if this is what you want to do?
You could create your custom plugin based on your URL parameters as so:
function assignPageTitle(){
if( $_GET['query'] == 'something' ) { return 'something'; }
elseif( $_GET['query'] == 'something-else' ) { return 'something-else'; }
else { return "Default Title"; }
}
add_filter('wp_title', 'assignPageTitle');

How to pass extra variables in URL with WordPress

I am having trouble trying to pass an extra variable in the url to my WordPress installation.
For example /news?c=123
For some reason, it works only on the website root www.example.com?c=123 but it does not work if the url contains any more information www.example.com/news?c=123. I have the following code in my functions.php file in the theme directory.
if (isset($_GET['c']))
{
setcookie("cCookie", $_GET['c']);
}
if (isset($_SERVER['HTTP_REFERER']))
{
setcookie("rCookie", $_SERVER['HTTP_REFERER']);
}
Any Ideas?
To make the round trip "The WordPress Way" on the "front-end" (doesn't work in the context of wp-admin), you need to use 3 WordPress functions:
add_query_arg() - to create the URL with your new query variable ('c' in your example)
the query_vars filter - to modify the list of public query variables that WordPress knows about (this only works on the front-end, because the WP Query is not used on the back end - wp-admin - so this will also not be available in admin-ajax)
get_query_var() - to retrieve the value of your custom query variable passed in your URL.
Note: there's no need to even touch the superglobals ($_GET) if you do it this way.
Example
On the page where you need to create the link / set the query variable:
if it's a link back to this page, just adding the query variable
<a href="<?php echo esc_url( add_query_arg( 'c', $my_value_for_c ) )?>">
if it's a link to some other page
<a href="<?php echo esc_url(
add_query_arg( 'c', $my_value_for_c, site_url( '/some_other_page/' ) )
)?>">
In your functions.php, or some plugin file or custom class (front-end only):
function add_custom_query_var( $vars ){
$vars[] = "c";
return $vars;
}
add_filter( 'query_vars', 'add_custom_query_var' );
On the page / function where you wish to retrieve and work with the query var set in your URL:
$my_c = get_query_var( 'c' );
On the Back End (wp-admin)
On the back end we don't ever run wp(), so the main WP Query does not get run. As a result, there are no query vars and the query_vars hook is not run.
In this case, you'll need to revert to the more standard approach of examining your $_GET superglobal. The best way to do this is probably:
$my_c = filter_input( INPUT_GET, "c", FILTER_SANITIZE_STRING );
though in a pinch you could do the tried and true
$my_c = isset( $_GET['c'] ) ? $_GET['c'] : "";
or some variant thereof.
There are quite few solutions to tackle this issue. First you can go for a plugin if you want:
WordPress Quickie: Custom Query String Plugin
Or code manually, check out this post:
Passing Query String Parameters in WordPress URL
Also check out:
add_query_arg
Since this is a frequently visited post i thought to post my solution in case it helps anyone. In WordPress along with using query vars you can change permalinks too like this
www.example.com?c=123 to www.example.com/c/123
For this you have to add these lines of code in functions.php or your plugin base file.
From shankhan's anwer
add_filter( 'query_vars', 'addnew_query_vars', 10, 1 );
function addnew_query_vars($vars)
{
$vars[] = 'c'; // c is the name of variable you want to add
return $vars;
}
And additionally this snipped to add custom rewriting rules.
function custom_rewrite_basic()
{
add_rewrite_rule('^c/([0-9]+)/?', '?c=$1', 'top');
}
add_action('init', 'custom_rewrite_basic');
For the case where you need to add rewrite rules for a specifc page you can use that page slug to write a rewrite rule for that specific page. Like in the question OP has asked about
www.example.com/news?c=123 to www.example.com/news/123
We can change it to the desired behaviour by adding a little modification to our previous function.
function custom_rewrite_basic()
{
add_rewrite_rule('^news/([0-9]+)/?', 'news?c=$1', 'top');
}
add_action('init', 'custom_rewrite_basic');
Hoping that it becomes useful for someone.
add following code in function.php
add_filter( 'query_vars', 'addnew_query_vars', 10, 1 );
function addnew_query_vars($vars)
{
$vars[] = 'var1'; // var1 is the name of variable you want to add
return $vars;
}
then you will b able to use $_GET['var1']
<?php
$edit_post = add_query_arg('c', '123', 'news' );
?>
Go to New page
You can add any page inplace of "news".
One issue you might run into is is_home() returns true when a registered query_var is present in the home URL. For example, if http://example.com displays a static page instead of the blog, http://example.com/?c=123 will return the blog.
See https://core.trac.wordpress.org/ticket/25143 and https://wordpress.org/support/topic/adding-query-var-makes-front-page-missing/ for more info on this.
What you can do (if you're not attempting to affect the query) is use add_rewrite_endpoint(). It should be run during the init action as it affects the rewrite rules. Eg.
add_action( 'init', 'add_custom_setcookie_rewrite_endpoints' );
function add_custom_setcookie_rewrite_endpoints() {
//add ?c=123 endpoint with
//EP_ALL so endpoint is present across all places
//no effect on the query vars
add_rewrite_endpoint( 'c', EP_ALL, $query_vars = false );
}
This should give you access to $_GET['c'] when the url contains more information like www.example.com/news?c=123.
Remember to flush your rewrite rules after adding/modifying this.
to add parameter to post urls (to perma-links), i use this:
add_filter( 'post_type_link', 'append_query_string', 10, 2 );
function append_query_string( $url, $post )
{
return add_query_arg('my_pid',$post->ID, $url);
}
output:
http://yoursite.com/pagename?my_pid=12345678
This was the only way I could get this to work
add_action('init','add_query_args');
function add_query_args()
{
add_query_arg( 'var1', 'val1' );
}
http://codex.wordpress.org/Function_Reference/add_query_arg
In your case, Just add / after url and then put query arguments. like
www.example.com/news/?c=123 or news/?c=123
instead of
www.example.com/news?c=123 or news?c=123

Categories