Wordpress add rewrite rule doesn't work for me - wordpress

I'm developing a plugin that creates 2 pages: one listing page and one details page.
I don't use custom types. I have created a table into the database where I save the company details and also a slug for the details page.
It's working properly but I have a problem with the URLs. They are not pretty.
On the listing page I use this code to create the link:
<?php echo stripslashes($value->company_name); ?>
The generated link looks like this:
https://www.website.com/company/details/?companyname=new-company-name
I use the query because I need it on the details page, where I use this code:
$company_slug = $_GET['companyname'];
$company_details = $wpdb->get_row("SELECT * FROM $table_company WHERE company_slug = '$company_slug'");
This is how I retrieve the company details from sql and it also works just fine.
I have created manually in Wordpress the details page.
The problem is that I want the details URL to look pretty, like this:
https://www.website.com/company/details/new-company-name/
Generating it like this it's easy but when I click, I get a 404, since the query from URL is missing.
I was thinking it's easy to create directly the pretty URL and on the details page to parse the URL and get the company slug. It didn't work. I get a 404 maybe because the page doesn't physically exist.
So, I've done some research about URL rewrite and I have found some examples but none worked.
I have found tried this code also:
add_filter('query_vars', function($vars) {
$vars[] = "companyname";
return $vars;
});
function custom_rewrite_rule() {
add_rewrite_rule('^companyname/?([^/]*)/?','company/details/?companyname=$matches[1]','top');
}
add_action('init', 'custom_rewrite_rule', 10, 0);
I've read that I shouldn't use matches if I use a custom URL instead of index.php, so I have also tried without matches:
add_rewrite_rule('^companyname/?([^/]*)/?','company/details/?companyname=$1','top');
No results. If course, after every change I have saved again the permalinks.
This should be an easy task but somehow it doesn't work.
https://developer.wordpress.org/reference/functions/add_rewrite_rule/
Does anyone of you know how can I make this work?
Thank you.
Regards,
AG

I am assuming that the details page you created has the slug company/details. Here's what you need to do to make it work-
1. Add the custom rewrite rules in functions.php file:
function theme_custom_rewrites() {
add_rewrite_tag("%companyname%", "([a-z0-9\-_]+)");
add_rewrite_rule('^company/details/([a-z0-9\-_]+)/?$', 'index.php?pagename=company/details&companyname=$matches[1]', 'top');
}
add_action('init', 'theme_custom_rewrites');
It registers a new rewrite tag/query var named companyname to be used later and registers a custom rewrite rule for the specific URL structure you want (/company/details/company_name).
2. Get the company name on the template file and use it: After you have added the above code and saved the permalinks, you can get the companyname just by using the get_query_var() function.
$companyname = get_query_var( 'companyname' );
Hope it helps. Thanks.

Thank you very much for your fast reply. It worked.
Of course, I had to change the link on the listing page to:
<?php echo stripslashes($value->company_name); ?>
I have removed the query from the link and it looks like this now:
https://www.website.com/company/details/new-company-name/
What I don't understand, is how does WP know which is the query, since I removed it from the link.
I can see the same data if I access
https://www.website.com/company/details/?companyname=new-company-name
or
https://www.website.com/company/details/new-company-name/
But, basically, this part (?companyname=) doesn't exist anymore in the link, since I changed it.
I have no query now in my plugin, but somehow everything works properly. :)
I did not declare it somewhere. It's completely gone and it works.
How does this code know that the query exists and it's retrieving the slug from the database?
$companyname = get_query_var( 'companyname' );
I only have this code now:
<?php echo stripslashes($value->company_name); ?>
So, no query in URL.
Thank you for your time.
Regards,
AG

Related

add_rewrite_rule not working when referencing child page name as matches

Is anyone able to comment why this does not work.
I have created a custom post type called "knowledge-hub". I also then created a page called "knowledge-hub" to act as the landing page for my CPT listings, which I show using code. On one of the CPT pages, "minimum-wage-policies", I want to be able to access a variable in the URL, e.g. ?some_var=xyz. But I want it friendly like /knowledge-hub/minimum-wage-policies/xyz.
So I have created rewrite URLs. The page name "minimum-wage-policies" will vary for many of the CPT pages, so I cant hard code this. I want to access it using a URL part.
But I cant get the add_rewrite_rule() to match matches[1] to the page name. If I hard code this page name in the add_rewrite_rule it works! But as soon as I replace it with matches[1] it does not work, its either a 404 or a redirect back to minimum-wage-policies with no variable on the end.
URL would be:
http://my-domain.com/knowledge-hub/minimum-wage-policies/some_var
Referencing the child page name works:
add_rewrite_rule(
'knowledge-hub/([^/]*)?/([^/]*)/?$',
'index.php?post_type=knowledge-hub&pagename=minimum-wage-policies&my_var=$matches[2]',
'top'
);
matches[2] is working in this case as I can see the value passed in the URL in my code.
But using matches[1] does not work and returns a 404:
add_rewrite_rule(
'knowledge-hub/([^/]*)?/([^/]*)/?$',
'index.php?post_type=knowledge-hub&pagename=$matches[1]&my_var=$matches[2]',
'top'
);
Visiting the WP URL http://my-domain.com/index.php?post_type=knowledge-hub&pagename=minimum-wage-policies&my_var=xyz works, so that structure is OK.
I have tried various regex expressions used by various others on the internet, so not just ([^/])?. So am not sure if it is to do with the regex and I just have not found the right one. I want to match anything. Same issue with (.)
I also have this:
function add_my_vars($vars)
{
$vars[] = 'my_var';
return $vars;
}
add_filter('query_vars', 'add_my_vars');
Update:
Using $request->matched_query I could see the URLs being called.
When I use pagename=minimum-wage-policies the URL is as expected:
post_type=knowledge-hub&pagename=minimum-wage-policies&my_var=xyz
When I use matches[1] is completely changed which is quite bizarre:
knowledge-hub=minimum-wage-policies%2Fxyz&page=
I managed to get it working with this rewrite_rule but I have not found this structure online so not sure if its technically correct but it works. Note the use of knowledge-hub=$matches[1]. This was discovered from viewing the $request->matched_query I mentioned was bizarre above. Replicating it in the rewrite_rule makes it work.
add_rewrite_rule(
'knowledge-hub/([^/]*)?/([^/]*)/?$',
'index.php?knowledge-hub=$matches[1]&my_var=$matches[2]',
'top'
);

Home page url rewriting Wordpress

I want to do a URL rewrite in the WordPress home page
I want to change my URL http://mysite.loc/?pays=senegal to look like http://mysite.loc/senegal.
The problem is that I am on the WordPress home page, so it will be confused with the URL of another page like http://transfert.loc/page-example.
I have already tried several optins but am completely blocked.
Here is my code example:
public function rewrite_urls(){
add_rewrite_tag( '%pays%','([^&]+)' );
add_rewrite_rule(
'([^/]+)',
'index.php?pays=$matches[1]',
'top'
);
}
Can someone help me please!
Thanks
Two problems I see- rewrite rules need to set query vars that will result in a successful main query. Setting just a custom var like slide doesn't parse to anything WordPress can load. Additionally, slide needs to be added to the recognized query vars for it to get parsed within a rule.
So, what would a rule look like that would load the front page posts in the main query? That's a good question- the posts page is a special case, the absence of any other query vars. I haven't found a way to do that with a rule, though it may exist.
An easier way to do this is with a rewrite endpoint:
function wpd_endpoint(){
add_rewrite_endpoint( 'page-example', EP_ROOT );
}
add_action( 'init', 'wpd_endpoint' );
Keep in mind that if you have code accessing values via $_GET, this still won't work, because WordPress doesn't put query vars there when rules are parsed. You can change the code to use get_query_var, or just assign it before the code tries to access it:
$_GET['page-example'] = get_query_var('page-example');

Multi Param URL redirect issue in wordpress

I have a bit of an issue I cannot seem to get around.
On a WordPress install we have these special profile pages that were triggered by a URL structure such as this
/our-firm/profile/1/Some.Name
They wanted the name appended to the URL so the URL's were prettier. This looks like it was previously managed through some type of plugin before we got it. Now a recent WordPress update has corrupted that plugin, and this functionality no longer works. I have it where it at least works if you do not use the name, example:
/our-firm/profile/1/
But that of course is not what the client wants. I have attempted to remedy the issue with some .htaccess rewriting that follows:
RewriteRule ^our-firm/profile/([0-9]+)/([^+]+)?$ our-firm/profile?id=$1&name=$2 [L,QSA]
But I am not getting anywhere with it. What weirder is, and it may just be something I am over looking, but if I visit:
/our-firm/profile?id=1&profile_name=Some.Name
That even works fine.
Any help would be great on this. Thanks in advance!!
You can use add_rewrite_rule of WP (http://codex.wordpress.org/Rewrite_API/add_rewrite_rule)
Example:
function wptuts_add_rewrite_rules() {
add_rewrite_rule('^path-1/([^/]*)?$','index.php?page_id=PAGE_ID&nameSurname=$matches[1]','top');
flush_rewrite_rules();
}
add_action( 'init', 'wptuts_add_rewrite_rules' );
function add_query_vars($aVars) {
$aVars[] = "nameSurname";
return $aVars;
}
add_filter('query_vars', 'add_query_vars');
and You get the params in the page using $wp_query->query_vars["nameSurname"];

WordPress plugins - don't print the comments on a post page

I'm making a plugin where I want the comments in a single post page not to be printed at all. I need to query the database myself and print my own html with the results.
How can I make WordPress to not print the comments, without disabling them?
Thank you
EDIT:
as a suggestion, I am using:
apply_filters('comments_template', array($this,'comments_template'), 10, 1);
function comments_template($template){
$template = '';
return $template;
}
nothing happens, what am I doing wrong?
You could use the comments_template filter to make WordPress use your plugin's template file rather than the current theme's.
EDIT: based on your edited code: unfortunately you need to have an actual file, the path to which you return in $this->comments_template()...
class MyPlugin{
//add the filter somewhere...
function comments_template($template){
return dirname(__FILE__) . "/my_comments_template.php";
}
}
The file plugin_dir/my_comments_template.php must exist, otherwise WP falls back on the default theme's comments.php. See wp-includes/comment-template.php on lines 911-917.
In plugin_dir/my_comments_template.php you could call `MyPlugin::do_comments() or something like that. I don't know any other way around this. Let me know if you find a better way.
Cheers, Chris

Wordpress auto-generated "canonical" links - how to add a custom URL parameter?

Does anyone know how to modify the Wordpress canonical links to add a custom URL parameter?
I have a Wordpress site with a page that queries a separate (non-Wordpress) database. I passed the URL parameter "pubID" to display individual books and it is working OK.
Example: http://www.uglyducklingpresse.org/catalog/browse/item/?pubID=63
But the individual book pages are not showing up properly in Google - the ?pubID parameter is stripped out.
I think maybe this is because all the item pages have the same auto-generated "canonical" URL link tag in the source - one with the "pubID" parameter stripped out.
Example: link rel='canonical' href='http://www.uglyducklingpresse.org/catalog/browse/item/'
Is there a way to perhaps edit .htaccess to add a custom URL parameter to Wordpress, so that the parameter is not stripped out by permalinks and the "canonical" links?
Or maybe there's another solution ... Thank you for any ideas!
You should be able to replace Wordpress's rel_canonical action function with your own function in which (when your conditions are meet) you create a canonical link appending the query string variable. The following should work, although you'll probably need to change the conditions to meet your needs.
remove_action('wp_head', 'rel_canonical');
add_action('wp_head', 'my_rel_canonical');
function my_rel_canonical() {
if (is_page('item') && isset($_GET['pubID'])) {
global $post;
$link = get_permalink($post->ID) . '?pubID=' . absint($_GET['pubID']);
echo "<link rel='canonical' href='$link' />\n";
} else {
rel_canonical();
}
}

Resources