Wordpress Rewrite URL from API NOT the database - php

I am building a site using WP and the Prosperent API. I have built out product category pages where the user can see all the "Backpacks" and even sub categories. I now want to build product detail pages. Because the data comes from an API, and not stored in my database I don't have an easy want to have pretty links.
On the category pages, I am linking each product like this:
$pageLink = esc_url( add_query_arg( array (
'gearID' => $value['catalogId'],
'gearTitle' => $value['keyword']
),
'http://www.example.com/products/g/' ) );
Which looks like this:
http://www.example.com/products/g/?gearID=65198586171ee0ea97f3e39935468f4d&gearTitle=The%20North%20Face%20Inferno%20Sleeping%20Bag:%20-20%20Degree%20Down%20Asphalt%20Grey/Caution%20Orange,%20Long
I AM Successfully capturing the "gearID" & gearTitle query variables, This allows me to display the product on the product detail page template. This is working great. But the URL has my query strings in it.
I have tried several different variations, but this is my code for the rewrite:
add_filter( 'query_vars', 'add_query_vars_filter' )
function custom_rewrite_basic() {
$gearID = get_query_var( 'gearID', false );
add_rewrite_rule('^products/g/([0-9]+)/?', 'index.php/products/g/?gearID=$matches[1]', 'top');
flush_rewrite_rules();
}
add_action('init', 'custom_rewrite_basic');
You can see in the code I have a get_query_var for the gearID, I attempted to insert where $match[1] is placed and didn't work. Perhaps I need to store data in DB so WP knows what to rewrite? Can't do it on the fly?
Ultimately, I want it to look like this:
http://www.cascadegear.com/products/g/The%20North%20Face%20Inferno%20Sleeping%20Bag:%20-20%20Degree%20Down%20Asphalt%20Grey/Caution%20Orange,%20Lon

Related

Adding .php extension to one plugin page in Wordpress

I'm searching for a solution to add .php extension to the page of my wordpress plugin.
I already found similar posts but none of them was about adding the .php extension to only on page generated by a plugin.
I already tried to work with the global $wp_rewrite; but it would apply the .php extension to all pages.
All I want is simply something like that:
www.mydomain.com/myfile => www.mydomain.com/myfile.php but only for this one particular page.
Update:
The file myfile.php doesn't exist. It's the permalink of a wp page. I basically want to add .php to the permalink of one page (only this one page). I know it's possible to change the permalink of an page, but wp would not let me add .php to the permalink. It automatically changes it to -php (it doesn't accept the dot).
It is not necessary to change the link format for all pages via wp_rewrite. You can add rewrite_rule for a specific page without changing the format for the entire Post Type.
add_rewrite_rule(
'^myfile.php',
'index.php?page_id=1234',
'top'
);
1234 = your page $post_id
Next, we change permalink generation for our page
add_filter( 'page_link', 'filter_function_myfile_link', 10, 3 );
function filter_function_myfile_link( $link, $post_id, $sample ){
if ( $post_id == 1234 ) {
$link = home_url('/myfile.php', 'https');
}
return $link;
}

Wordpress Filtering Woocommerce Structured Data

I'm figuring out a filter but can't be figured :)
Just want to change PrimaryImageOfPage value with an og:image value in CollectionPage for Taxonomies.
It may be that I have to use woocommerce_structured_data_product to filter here and look for the image $markup['image'] = $image;
I have created some filters, but it isn't woocommerce_structured_data_product I guess.
One of them was like that but it... nah.
add_filter( 'woocommerce_structured_data_product', function( $markup ) {
$markup['image'] = ('rank_math/opengraph/{$network}/image');
return $markup;
});
What am I doing wrong? I have been doing this whole day -_-
If You inspect the code of the class WC_Structured_Data, You would see that woocommerce_structured_data_product filter is executed inside function generate_product_data
WC Complete Source of the class WC_Structured_Data : https://github.com/woocommerce/woocommerce/blob/b88b868ab8919b7c854173098b7d6d4ab227f9ee/includes/class-wc-structured-data.php
$this->set_data( apply_filters( 'woocommerce_structured_data_product', $markup, $product ) );
And generate_product_data function is executed on action woocommerce_single_product_summary
add_action( 'woocommerce_single_product_summary', array( $this, 'generate_product_data' ), 60 );
So, your code would work on product single page only and not archive/list pages, such as the taxonomy page.
The feature you want to achieve is not feasible out of the box in WC, You will need to customize yourself.
Logically, structured data on a single product page is feasible due to the fact there is only one product and product information is available, on the other hand, product list has more than one product (you might need to consider like you want to show details of first product) so it is ambiguous and not feasible out of the box for WC.

switch_to_blog() within WordPress shortcode

Using a WordPress multisite network, I need to access custom post types from our main site from within a shortcode.
For example, our main site (ID 1) is where the custom post types (Case Studies) are stored. In functions.php I have the following:
//[casestudy]
add_shortcode( 'casestudy', 'casestudy_shortcode' );
function casestudy_shortcode( $atts ) {
$a = shortcode_atts( array(
'id' => ''
), $atts );
switch_to_blog(1);
//Get fields from custom post type with Advanced Custom Fields Pro
//and return HTML output with them
restore_current_blog();
}
Then call the shortcode with [casestudy id="123"] where the ID is the post ID of the case study.
The problem is, doing this returns the Case Study HTML fine but breaks some features of the page and also populates the 'recent posts' widget with blog posts of the main site.
Any ideas on what's going wrong? Thanks.
Adding my comment as an answer:
Reading the OP code comments, it looks like restore_current_blog() is never called, because the HTML is returned before calling it.
Make sure that the return part is the last line in there.

wordpress functions.php - use different page template for each post category

I want to hook into the save_post function, find out what category the post is in, and then assign a different page template for posts in each category. I've tried about 30 different versions of this with no luck. Will someone please help point me in the right direction?
add_action( 'save_post', 'assign_custom_template' );
function assign_custom_template($post_id) {
$category = get_the_category($post_id);
$cat_id = $category->cat_ID;
if( $cat_id == 1 ) {
update_post_meta($post_id, "_wp_page_template", "template1.php");
}
if( $cat_id == 2 ) {
update_post_meta($post_id, "_wp_page_template", "template2.php");
}
}
You just need to create category-1.php which rendered as template1.php and category-2.php which rendered as template2.php in your theme root.
See template hierarchy for more info.
I tried to emulate the official WP hierarchy scheme among my posts & custom post types, but it just wasn't happening. I ended up using Custom Post Types so that I could assign templates to both the "list" pages and the "individual" pages. And then I wrote some javascript that looks for the post-type string in the URL, and if it's detected, it adds the current_page_parent/ancestor classes to the appropriate menu items. Not perfect or totally future-proof, but it gets the job done.
If someone comes up with a better solution, please post it!

Wordpress URL Routing, Multiple permalinks with different templates

This question is based on an unanswered question in Wordpress Development which has not gotten a solid answer.
I have a wordpress website which lists hotels. the url for a single hotel looks like:
/hotels/the-marriot-hotel
I also have a custom taxonomy for Locations, which allows me to browse the hotels in various locations, which works fine, the urls are like:
/Locations/Liverpool
For URL's like /hotels/* I would like to use a custom template, which I have done already and works fine.
The Problem
I also want to be able to drilldown the Locations taxonomy creating a breadcrumb type URL and also use a different template for the hotel page.
For Example, if a user is browsing /Locations/Liverpool and clicks the Marriot Hotel I would like it to click through to /Locations/Liverpool/the-marriot-hotel instead of /hotels/the-marriot-hotel and also use a slightly different template, which can also load a different sidebar and recommend other hotels in the area specific to the location slug in the URL
So basically I want two routes to a single post and a different template used based on the route used.
How would I go about implementing this?
What have I tried?
I've tried adding a new page and using a rewrite rule to point to it to be the locations hotel page.
I've tried adding a slug on the end of the /Locations/{location-slug} url and reading this in the page template and loading the hotel post instead of the list it doesn't seem to be working but also feels like a terrible hack anyway
An idea that I've had is to add a rewrite to the hotels/{slug} page and using code to detect the URL used and switch templates dynamically but I'm not sure this is the best approach
I have managed to get this working using the second method mentioned above (adding a rewrite to the locations landing page and checking for a query_var).
I will post the code below that I used but although this works and seems to be working very well, It does not feel like the best way of doing it. If someone know of a better way of doing this please post the answer.
I used this online post for reference.
Note: The listing page shows the list of hotels in the taxonomy in a side column down the side and shows the currently selected or a random one in the main content area. Which will explain how I am using the loop below.
function prefix_locations_rewrite_rule() {
add_rewrite_rule( 'Locations/([^/]+)/([^/]+)', 'index.php?locations=$matches[1]&hotel=$matches[2]', 'top' );
}
function prefix_register_query_var( $vars ) {
$vars[] = 'hotel';
return $vars;
}
function prefix_url_rewrite_templates() {
if ( get_query_var( 'hotel' ) && is_singular( 'hotel' ) ) {
add_filter( 'template_include', function() {
return get_template_directory() . '/taxonomy-locations.php';
});
}
}
add_action( 'template_redirect', 'prefix_url_rewrite_templates' );
add_filter( 'query_vars', 'prefix_register_query_var' );
add_action( 'init', 'prefix_locations_rewrite_rule' );
In my template file for the hotels landing page:
$hotelSlug = get_query_var( 'hotel', false);
if ( have_posts() ) {
while (have_posts()) : the_post();
if ($post->post_name == $hotelSlug) {
break;
}
endwhile;
}
This bit of code will iterate over the posts and if the hotel slug matches the query var it will break there so that the current post is the one we wanted.
We could just use a query here but as I already have a list of posts within the taxonomy I thought I'd just iterate over it. Below this I check to see if a specific hotel has been selected otherwise I show a random one from the list.
I am still to add additional logic and error handling to this code, I hope it helps someone with a similar issue

Categories