I have a dynamic page setup in wordpress which uses a $_GET['id'] php variable to make a query to the database. The problem is that my url format looks like the following:
http://site.com/business/id?=123
What's the best way to make the url look like:
http://site.com/business/business-name-here
Is it done using rewrite rules in the .htaccess file?
Thanks in advance
I've found a great class to do just that by Kyle E try it.
<?php
/*
//Author Kyle E Gentile
//To use this class you must first include the file.
//After including the file, you need to create an options array. For example:
$options = array(
'query_vars' => array('var1', 'var2'),
'rules' => array('(.+?)/(.+?)/(.+?)/?$' => 'index.php?pagename=$matches[1]&var1=$matches[2]&var2=$matches[3]')
);
//After creating our $option array,
//we will need to create a new instance of the class as below:
$rewrite = new Add_rewrite_rules($options);
//You must pass the options array, this way. (If you don't there could be problems)
//Then you can call the filters and action functions as below:
add_action('wp_head', array(&$rewrite, 'flush_rules'));
add_action( 'generate_rewrite_rules', array(&$rewrite, 'add_rewrite_rules') );
add_filter( 'query_vars', array(&$rewrite, 'add_query_vars') );
//That is it.
*/
//prevent duplicate loading of the class if you are using this in multiply plugins
if(!class_exists('add_rewrite_rules')){
class Add_rewrite_rules{
var $query_vars;
var $rules;
function __construct($options){
$this->init($options);
}
function init($options){
foreach($options as $key => $value){
$this->$key = $value;
}
}
function rules_exist(){
global $wp_rewrite;
$has_rules = TRUE;
foreach($this->rules as $key => $value){
if(!in_array($value, $wp_rewrite->rules)){
$has_rules = FALSE;
}
}
return $has_rules;
}
//to be used add_action with the hook 'wp_head'
//flushing rewrite rules is labor intense so we better test to see if our rules exist first
//if the rules don't exist flush its like after a night of drinking
function flush_rules(){
global $wp_rewrite;
if(!$this->rules_exist()){
//echo "flushed"; // If want to see this in action uncomment this line and remove this text and you will see it flushed before your eyes
$wp_rewrite->flush_rules();
}
}
//filter function to be used with add_filter() with the hook "query_vars"
function add_query_vars($query_vars){
foreach($this->query_vars as $var){
$query_vars[] = $var;
}
return $query_vars;
}
//to be used with a the add_action() with the hook "generate_rewrite_rules"
function add_rewrite_rules(){
global $wp_rewrite;
$wp_rewrite->rules = $this->rules + $wp_rewrite->rules;
}
}
}
?>
Add the following function to the init of your plugin / functions file.
public function rewriteRules()
{
//Add the query variables to the list so wordpress doesn't discard them or worse use them to try and find by itself what page to serve.
$options = array(
'query_vars' => array('trainingid', 'vakname'),
'rules' =>
array( 'uncategorized/vak/([^/]+)/([^/]+)/?$' => 'index.php?p=1316&vakname=$matches[1]&level=$matches[2]'
)
);
//I use a autoloader but if you don't you have to include the class.
//include_once('path/to/AddRewriteRules.php');
$rewrite = new AddRewriteRules($options);
add_action('wp_head', array(&$rewrite, 'flush_rules'));
add_action('generate_rewrite_rules', array(&$rewrite, 'add_rewrite_rules'));
add_filter('query_vars', array(&$rewrite, 'add_query_vars'));
}
Related
I've been trying to access timber context in add shortcode function but it doesn't seem to work.
My code is
add_action( 'init', array($this, 'create_shortcodes' ) );
public function create_shortcodes() {
add_shortcode( 'social_media', array($this, 'social_shortcode') );
}
public function social_shortcode($atts) {
$params = shortcode_atts(array(
'id' => 0
), $atts);
$data = Helpers::create_social_media( $atts['id'], false, true );
add_filter( 'timber_context', array($this, 'add_to_context_social_media'), 11 );
return \Timber\Timber::compile('social-media.twig', array('data' => $data['content'] ));
}
public function add_to_context_social_media($context) {
echo '<pre style="margin:200px">';
print_r($context);
echo '</pre>';
return $context;
}
If I add the filter inside the create_shortcodes function it works, but it doesn't isnide the add_shortcode function which also is inside the create_shortcodes function.
Any help will be appreciated.
Thanks
Would it be better to render the returned output instead of rendering it inside the shortcode ?
$returned_shortcode = do_shortcode('[your_shortcode]');
return \Timber\Timber::compile('social-media.twig', array('data' => $returned_shortcode ));
When you use this line
add_filter( 'timber_context', array($this, 'add_to_context_social_media'), 11 );
Then you would need to call Timber::get_context() for the filter to be applied. However, calls to Timber::get_context() are cached. This means that if you wanted to use the timber_context filter, you’d have to do add it before your first call to Timber::get_context(). If you wanted to use that in a shortcode, you probably already call Timber::get_context() in the singular or archive PHP template that displays the post’s content.
I guess you could build up the data context for your social-media.twig template like follows:
public function social_shortcode($atts) {
$params = shortcode_atts(array(
'id' => 0
), $atts);
// Get cached context.
$context = Timber::get_context();
// Add to context.
$context['data'] = Helpers::create_social_media(
$atts['id'],
false,
true
);
return \Timber\Timber::compile( 'social-media.twig', $context );
}
In addition to your custom data, you would also have the global context available in your Twig file.
I am trying to add some site-specific functionality to the Wordpress plugin Appointments+. When a user is making an appointment, they select certain services and enter information into some fields for confirmation.
What I want to do is add some code so the extra information fields are related to which service they choose. For example, if they choose Service A, they have to fill in some information and those fields are validated. But if they choose Service B, hide the fields and skip the validation.
Here is an example of the original code:
function post_confirmation() {
...some extra stuff
$values = explode( ":", $_POST["value"] );
$location = $values[0];
$service = $values[1];
do_action('app-additional_fields-validate');
...more stuff
}
Here is the kind of thing I want to do, but not alter this original plugin file:
function post_confirmation() {
...some extra stuff
$values = explode( ":", $_POST["value"] );
$location = $values[0];
$service = $values[1];
if (($service == 1) || ($service == 3)) {
do_action('app-additional_fields-validate');
}
...more stuff
}
I admit that I am new to using hooks and filters. I want to disable/enable that action based on a variable in the function. How can I do that with another hook/filter?
Thank you.
Unhook the hook used for calling post_confirmation and override this function from your functions.php like
remove_action( 'current_action_hook', 'post_confirmation' );
add_action( 'current_Action_hook', 'post_custom_confirmation' );
function post_custom_confirmation(){
...some extra stuff
$values = explode( ":", $_POST["value"] );
$location = $values[0];
$service = $values[1];
if (($service == 1) || ($service == 3)) {
do_action('app-additional_fields-validate');
}
...more stuff
}
I think this should work, I have used this way during a woocommerce plugin development before nearly 2 months below is working code example , so that if you need any modification on code above, you can take reference .
remove_action( 'woocommerce_checkout_order_review', 'woocommerce_order_review', 10 );
add_action( 'woocommerce_checkout_order_review', 'pk_order_review', 10, 1 );
function pk_order_review($template) {
global $woocommerce;
$template = wc_get_template ( 'checkout/review-order.php', FALSE, FALSE, untrailingslashit( plugin_dir_path( __FILE__ ) ) . '/templates/');
return $template;
exit;
}
Another way you can do it is
add_action( 'app-additional_fields-validate', 'foo' );
function foo(){
if (($service == 1) || ($service == 3)) {
/* Your stuffs */
}
}
This is actually part answer, part new question. If that is possible to do here.
So, I finally found a way to affect the desired function.
The function I was trying to modify is contained in a class so, I did something like this:
class my_Check extends Appointments {
function __construct() {
$this->unregister_parent_hook();
add_action( 'wp_ajax_post_confirmation', array( $this, 'post_confirmation' ) );
add_action( 'wp_ajax_nopriv_post_confirmation', array( $this, 'post_confirmation' ) );
}
function unregister_parent_hook() {
global $appointments; //this was the object created with the parent class
remove_action( 'wp_ajax_post_confirmation', array( $appointments, 'post_confirmation' ) );
remove_action( 'wp_ajax_nopriv_post_confirmation', array( $appointments, 'post_confirmation' ) );
}
function post_confirmation() {
...do the stuff with my mods...
}
}
$new_Check = new my_Check();
Only, I have a new problem now. The parent class does a lot more in the __construct() (many 'add_action()'s, etc.). And $this is populated with a lot more data. The problem is, these other things and data do not seem to be carrying over into the child class. I tried adding a parent::__construct() in the child's __construct() function, but that did not seem to work.
The code with my mods works except for things that need more data in the $this carried over from the parent class.
How can I maintain all the parent class's variable, functions, hooks & filters, etc. into the child class?
I am using Wordpress 3.5. I have created a page with name tpage. I want to pass query string like this tpage/param1. For this i have paste following code in functions.php but it is not working
add_rewrite_tag('%var1%','([^&]+)');`
add_rewrite_rule('^tpage/([^&]+)/?','index.php?page_id=4&var1=$matches[1]','top');
//Ensure the $wp_rewrite global is loaded
global $wp_rewrite;
//Call flush_rules() as a method of the $wp_rewrite object
$wp_rewrite->flush_rules();
What thing i am missing out here?
Theres a great class for this by someone called Kyle E that does all the heavy lifting for you.. you have to use get_query_var('Your-Var'); to get the var out. $_GET doesnt work. good luck!
<?php
/*
//Author Kyle E Gentile
//To use this class you must first include the file.
//After including the file, you need to create an options array. For example:
$options = array(
'query_vars' => array('var1', 'var2'),
'rules' => array('(.+?)/(.+?)/(.+?)/?$' => 'index.php?pagename=$matches[1]&var1=$matches[2]&var2=$matches[3]')
);
//After creating our $option array,
//we will need to create a new instance of the class as below:
$rewrite = new Add_rewrite_rules($options);
//You must pass the options array, this way. (If you don't there could be problems)
//Then you can call the filters and action functions as below:
add_action('wp_head', array(&$rewrite, 'flush_rules'));
add_action( 'generate_rewrite_rules', array(&$rewrite, 'add_rewrite_rules') );
add_filter( 'query_vars', array(&$rewrite, 'add_query_vars') );
//That is it.
*/
//prevent duplicate loading of the class if you are using this in multiply plugins
if(!class_exists('add_rewrite_rules')){
class Add_rewrite_rules{
var $query_vars;
var $rules;
function __construct($options){
$this->init($options);
}
function init($options){
foreach($options as $key => $value){
$this->$key = $value;
}
}
function rules_exist(){
global $wp_rewrite;
$has_rules = TRUE;
foreach($this->rules as $key => $value){
if(!in_array($value, $wp_rewrite->rules)){
$has_rules = FALSE;
}
}
return $has_rules;
}
//to be used add_action with the hook 'wp_head'
//flushing rewrite rules is labor intense so we better test to see if our rules exist first
//if the rules don't exist flush its like after a night of drinking
function flush_rules(){
global $wp_rewrite;
if(!$this->rules_exist()){
//echo "flushed"; // If want to see this in action uncomment this line and remove this text and you will see it flushed before your eyes
$wp_rewrite->flush_rules();
}
}
//filter function to be used with add_filter() with the hook "query_vars"
function add_query_vars($query_vars){
foreach($this->query_vars as $var){
$query_vars[] = $var;
}
return $query_vars;
}
//to be used with a the add_action() with the hook "generate_rewrite_rules"
function add_rewrite_rules(){
global $wp_rewrite;
$wp_rewrite->rules = $this->rules + $wp_rewrite->rules;
}
}
}
?>
As the title reads I'm trying to modify a function called by a parent theme in my child, I know that the child theme is set to be loaded beforehand so I'm curious if this is even possible?
My parent theme has a function called ajax_search_box() that I'd like to modify a query in, and I'd rather not modify the parent theme files in case I need to update it down the road.. what would be the best way to do this?
Also, for bonus points, how would I go about doing this with a widget as well? Thanks in advance!
function SearchFilter($query) {
// If 's' request variable is set but empty
if (isset($_GET['s']) && empty($_GET['s']) && $query->is_main_query()){
$query->is_search = true;
$query->is_home = false;
}
return $query;
}
add_filter('pre_get_posts','SearchFilter');
function ajax_search_box() {
if (isset($_GET["q"]))
{
$q = $_GET["q"];
global $wpdb;
$q = mysql_real_escape_string($q);
$q = $wpdb->escape($q);
$query = array(
'post_status' => 'publish',
'order' => 'DESC',
's' => $q
);
$get_posts = new WP_Query;
$posts = $get_posts->query( $query );
// Check if any posts were found.
if ( ! $get_posts->post_count )
die();
//Create an array with the results
foreach ( $posts as $post )
echo $post->post_title . "|" . $post->ID . "\n";
}
die();
}
// creating Ajax call for WordPress
add_action( 'wp_ajax_nopriv_ajax_search_box', 'ajax_search_box' );
add_action( 'wp_ajax_ajax_search_box', 'ajax_search_box' );
the parent theme needs to check if(function_exists('ajax_search_box')) and if it doesn't exist then it will declare it.
If the parent theme checks to see if the function exists, then you can declare it first and have it do what you want.
If the parent theme does not check, get in touch with the theme author to see if they will throw that change in for the next update....and code it yourself too. That way when the theme updates then you will still be good to go.
Break free of functions.php, write your own plugin.
<?php
/**
* Plugin Name: Manipulate the Parent
* Requires: PHP5.3+
*/
add_action( 'after_setup_theme', function()
{
remove_filter( 'pre_get_posts','SearchFilter' );
// now add your own filter
add_filter( 'pre_get_posts', 'your_callback_for_your_filter' );
});
function your_callback_for_your_filter()
{
// do stuff
}
I created a plugin... I use my custom variable in this plugin and I want to rewrite this url for SEO, but I can't. If I use the Permalink generator of WordPress, then rewrite is work, but if I want to use the offical codes in my plugin for rewrite then it doesn't work.
Here it is a simple code what is not work. I don't no why.
add_filter('rewrite_rules_array','wp_insertMyRewriteRules');
add_filter('query_vars','wp_insertMyRewriteQueryVars');
add_filter('init','flushRules');
// Remember to flush_rules() when adding rules
function flushRules(){
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
// Adding a new rule
function wp_insertMyRewriteRules($rules)
{
$newrules = array();
$newrules['(project)/(\d*)$'] = 'index.php?pagename=$matches[1]&id=$matches[2]';
return $newrules + $rules;
}
// Adding the id var so that WP recognizes it
function wp_insertMyRewriteQueryVars($vars)
{
array_push($vars, 'id');
return $vars;
}
function search_url_rewrite_rule() {
if ( is_search() && !empty($_GET['s'])) {
wp_redirect(home_url("/search/") . urlencode(get_query_var('s')));
exit();
}
}
add_action('template_redirect', 'search_url_rewrite_rule');
I wrote a new code into my plugin, but it has not effect:
add_action('admin_init', 'flush_rewrite_rules');
add_action('generate_rewrite_rules', 'geotags_add_rewrite_rules');
function geotags_add_rewrite_rules( $wp_rewrite )
{
$new_rules = array(
'p/(.+)' => 'index.php?p=' .
$wp_rewrite->preg_index(1) );
// Add the new rewrite rule into the top of the global rules array
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
have you tried looking at this page
http://codex.wordpress.org/Class_Reference/WP_Rewrite
and i think you have to flush the rules every time..