I'm creating a plugin OOP for wordpress. The plugin creates a new custom post type called teams. Within a team page a could use the shortcode [program] to generate some predefault html code. Also i've created custom fields with new meta boxes.
The problem however is: when i'm entering the page thats calling the plugin, equal the team page with the sortcode i need to get post id within my plugin to retrieve get_post_meta().
I've tried the following things:
public function __construct(){
// not working
$post;
$post->ID;
// not working
global $wp_query;
$post_id = $wp_query->post->ID;
$post = get_post( $post_id );
// not workiing
echo '<pre>';
print_r('post_id:' . get_the_ID());
echo '</pre>';
}
How could i receive the custom post id within my plugin when i visited the page from frontend (so the plugin is called, runs the shortcode)
My main class gets loaded like this:
function run_plugin() {
$plugin = new MyPlugin();
$plugin->run();
}
run_plugin();
Within MyPlugin the constructor looks like
public function __construct() {
if ( defined( 'PLUGIN_NAME_VERSION' ) ) {
$this->version = PLUGIN_NAME_VERSION;
} else {
$this->version = '1.0.0';
}
$this->plugin_name = 'MyPlugin';
if(!empty(get_option($this->plugin_name))){
$this->clientID = get_option($this->plugin_name)['client_id'];
}
$this->load_dependencies();
$this->set_locale();
$this->define_admin_hooks();
$this->define_public_hooks();
$this->define_shortcodes();
}
If your plugin constructor is getting called too early, the post data won't be set up and ready to use.
You'll need to hook into one of WPs actions that run after everything is ready. The init action should be enough for the post data, but depending on what else you need you can hook into wp_loaded, as it doesn't run until after WordPress is fully loaded.
function run_plugin() {
$plugin = new MyPlugin();
$plugin->run();
}
/* run_plugin(); */ // <- instead of this....
add_action( 'wp_loaded','run_plugin' ); // <- ...do this
Try to define post as global like
global $post
I have a bunch of pages, which are paginated using the url parameter ?page=
I am using wordpress and would like each page to have a custom made title. So far I've created a custom template an set up the following code:
$titletags = array('Title1','Title2');
if ($page==2) {$arrayno = 1}
function ChangeTitle($title) {
$title = $titletags[$arrayno];
return $title;}
add_filter( 'wpseo_title', 'ChangeTitle' );
I run this before the call to get the header. Now this code is not working, although it should change the title to Title2, when the url parameter is 2.
The code works if don't use the array inside the function, i.e. I do:
function ChangeTitle($title) {
$title = 'SomeTitle';
return $title;}
add_filter( 'wpseo_title', 'ChangeTitle' );
You have not access to $titletags array. first use global then get it. try this code:
$titletags = array('Title1', 'Title2');
function ChangeTitle( $title ) {
global $titletags, $page;
if ( $page == 2 ) {
return $titletags[1];
}
return $title;
}
add_filter( 'wpseo_title', 'ChangeTitle' );
Is there a hook / filter to process the link being added into a WordPress post ?
My aim is to pre-process the link inserted in a post using the following button and shorten it using a third party API like bit.ly
I want to do this for both internal / external links.
One solution that I an think of is to add an extra button to my editor that does this but I would prefer a hook / filter that does the job, that way it would be more clean and I will convert that into a custom plugin for my website (there by allowing my WordPress to be up-gradable).
I went through the WordPress docs and skimmed through the following hooks / filters which were of no use to me
https://developer.wordpress.org/reference/hooks/add_link/
https://developer.wordpress.org/reference/hooks/post_link/
And most of the ones listed here
https://developer.wordpress.org/?s=link
Update 1: As far as I know, external URLs are inserted into post content by TinyMCE editor link plugin, PHP does nothing.
In WordPress, there're two plugins which located at wp-includes/js/wplink.js and wp-includes/js/tinymce/plugins/wplink/plugin.js. Note that if you're not in SCRIPT_DEBUG mode, they have .min suffix.
wp-includes/js/wplink.js handles this dialog:
To filter URLs inserted via this dialog box, we must override wpLink.getAttrs method. For example, to add so39115564 string to every URLs:
jQuery(document).ready(function($) {
wpLink.getAttrs = function() {
wpLink.correctURL();
return {
href: $.trim( $("#wp-link-url").val() + "so39115564" ),
target: $("#wp-link-target").prop("checked") ? "_blank" : ""
};
}
});
You should take a look at the wp-includes/js/wplink.js for more info. It's too long to explain in detail here.
And let say the above script is mylink.js, here is how we should enqueue it:
add_filter('admin_enqueue_scripts', function()
{
// { Maybe some conditions for a valid screen here. }
wp_enqueue_script('mylink', 'link/to/the/mylink.js', ['link'], '1.0', true);
}, 0, 0);
wp-includes/js/tinymce/plugins/wplink/plugin.js handles this dialog:
This time, we also have to override setURL method of tinymce.ui.WPLinkPreview. But, it's almost impossible, unless you deregister this script and register a modified version. Then manage that script yourself with unpredictable changes from WordPress.
Now, choose it wisely! Shorten any external URLs before pasting them into your posts or mess up with WordPress TinyMCE plugins or use dialog box of wp-includes/js/wplink.js plugin.
Yes! WordPress inserts inline links via wp_link_ajax action which is executed by wp_ajax_wp_link_ajax() function.
As you can see in source code of that function, $results is retrieved by _WP_Editors::wp_link_query. Check out this method, you will meet wp_link_query filter. This filter accept two arguments: $results and $query. $results will be what we need to filter.
For example, we need to append so39115564 to the queried link:
add_filter('wp_link_query', function(array $results, array $query)
{
$results[0]['permalink'] = $results[0]['permalink'] . 'so39115564';
return $results;
}, PHP_INT_MAX, 2);
Now, you should know how to do it. Make sure to take a look at _WP_Editors::wp_link_query to filter the $results more efficient.
Have you considered not processing the link until you save the post? There is an action in the wordpress plugin api called "save_post" that's triggered on save.
Using "save_post" you could parse the content of the post and replace links using a url shortener then.
https://codex.wordpress.org/Plugin_API/Action_Reference/save_post
There might be plugins available for this , but here is the default logic behind.
1st Way : To save the shortened URL in DB also
add_action( 'save_post', 'save_book_meta', 10, 3 );
function save_book_meta( $post_id, $post, $update ) {
global $wpdb;
$slug = 'event';
// If this isn't a 'book' post, don't update it.
if ( $slug != $post->post_type ) {
return;
}
preg_match_all('|<a.*(?=href=\"([^\"]*)\")[^>]*>([^<]*)</a>|i', $post->post_content, $match);
$new_content = $post->post_content;
foreach($match[1] as $link){
$url = 'https://www.googleapis.com/urlshortener/v1/url?key=AIzaSyAnw98CCy5owhpgB2HvW3SkoXfm0MrLjks';
$json_data = json_encode( array( 'longUrl' => $link ) );
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
$result = json_decode($result);
$new_content = str_replace($link, $result->id, $new_content);
}
// unhook this function so it doesn't loop infinitely
remove_action('save_post', 'save_book_meta' );
$post_new = array(
'ID' => $post_id,
'post_content' => $new_content
);
$post_id = wp_update_post( $post_new, true );
if (is_wp_error($post_id)) {
$errors = $post_id->get_error_messages();
foreach ($errors as $error) {
echo $error;
}
}
add_action( 'save_post', 'save_book_meta' );
}
To achieve the above thing you will have to do following things :
Use save_post hook to get the post content after saving.
In this hook fetch all the external links in an array (modify the
conditions as per requirements).
Shorten the URL by using google API (key is required).
Get response from the Google API and update the post_data
accordingly in the database also.
At wp_update_post we are removing the hook to avoid infinite loop.
2nd Way : To show the front-end user shortened URL , (DB will have longUrl though)
Use the filter hook instead and with the same logic.
3rd Way : Plugin Usage (Not used personally).
https://wordpress.org/plugins/url-shortener/
https://wordpress.org/plugins/shortnit/
I am not perfect in TinyMCE because i didn't used TinyMCE in several project but i have experience with javascript so i found a some TinyMCE event api to use you can make a short url. I checked in WP latest version and TinyMCE version 4.x. You can also find for right api to trigger your custom callback.
Before tinymce initialize in wordpress editor register setup function using wordpress hook tiny_mce_before_init.
add_filter( 'tiny_mce_before_init', 'my_plugin_tiny_mce_before_init' );
function my_plugin_tiny_mce_before_init( $in ){
$in['setup'] = 'myplugin_tinymce_setup'; // javascript callback
return $in;
}
add_action( 'admin_footer', 'add_admin_footer' );
After add javascript callback in admin footer. I have two methods for this solution.
#1 method
function add_admin_footer(){
?>
<script type="text/javascript">
var counter = 1, insert_url, shorten_url;
function myplugin_tinymce_setup( editor ){
editor.onNodeChange.add(function(ed, cm, e) {
// Activates the link button when the caret is placed in a anchor element
if (e.nodeName.toLowerCase() == 'a'){
var element = jQuery(e).not('a[href="_wp_link_placeholder"],a[data-wplink-edit="true"]');
if( element.length ){
if( is_shorten = getShortenUrl( element.attr( 'href') ) ){
element.attr( 'href', is_shorten );
element.attr( 'data-mce-href', is_shorten );
}
}
}
});
var hostname = new RegExp(location.host);
var shorten_host = new RegExp('http://www.example.com'); // enter your short url generate host name
function getShortenUrl( url ){
// add more condition here...
// Add here ajax or shorten javascript api etc.
// filter and return short url
if( hostname.test( url ) ){
// internal link
// Return internal url with shorten
return 'http://www.example.com/Internal/'+counter++;
}else if( shorten_host.test( url ) ){
// not update already update with shorten url
return false;
}else{
// Return external url with shorten
return 'http://www.example.com/External/'+counter++;
}
}
</script>
<?php
#2 method
function add_admin_footer(){
?>
<script type="text/javascript">
var counter = 1, insert_url, shorten_url;
function myplugin_tinymce_setup( editor ){
editor.on('ExecCommand', function(e) {
// Eexcute command when click on button apply on insert/edit link
if( e.command == 'wp_link_apply' ){
if( editor.selection.getContent() ){
element = tinymce.$(editor.selection.getContent()); // Create new link
}else{
element = tinymce.$(editor.selection.getNode()); // Edit link option
}
if( element.prop('tagName').toLowerCase() == 'a' ){
current_link_url = element.attr('href'); // Real url added in editor.
// and also check current_link_url is not shorten url
// add more logic here. Get short url using ajax or bitly javascript api.
if( is_shorten_url = getShortenUrl( element.attr('href')) ){
editor.execCommand('mceInsertLink',false,{ href: is_shorten_url });
}
}
}
});
}
var hostname = new RegExp(location.host);
var shorten_host = new RegExp('http://www.example.com'); // enter your short url generate host name
function getShortenUrl( url ){
// add more condition here...
// Add here ajax or shorten javascript api etc.
// filter and return short url
if( hostname.test( url ) ){
// internal link
// Return internal url with shorten
return 'http://www.example.com/Internal/'+counter++;
}else if( shorten_host.test( url ) ){
// not update already update with shorten url
return false;
}else{
// Return external url with shorten
return 'http://www.example.com/External/'+counter++;
}
}
</script>
<?php
}
Best of luck :)
I have this PHP script:
function myshortcode_title( ){
return get_the_title();
}
add_shortcode( 'page_title', 'myshortcode_title' );
What is the shortcut i need for the page title to be shown? What do i need to put in the HTML for the fetched title to be shown
Add this to your theme, or make an plugin from it.
/* title to get the post title */
function getPageTitle() {
global $wp_query;
return get_post_title($wp_query->post->ID);
}
/* Add shortcode */
add_shortcode('page_title', 'getPageTitle');
for more ShortCode Api
You may use this.
echo do_shortcode('[page_title]');
https://developer.wordpress.org/reference/functions/do_shortcode/
How could I remove classes from the body element in Wordpress?
Default:
body class="page page-id-7 page-template-default logged-in"
What I'm looking for:
body class="page-id-7"
On Post's:
body class="postid-40"
This is how you find something like this out:
Find the relevant function by looking in a theme file, in this case header.php
Look this function up in the Wordpress Codex (http://codex.wordpress.org/Function_Reference/body_class)
Is there any examples that look similar to what I want to do? Yes:
// Add specific CSS class by filter
add_filter('body_class','my_class_names');
function my_class_names($classes) {
// add 'class-name' to the $classes array
$classes[] = 'class-name';
// return the $classes array
return $classes;
}
So basically, to remove all classes, just add this to functions.php:
add_filter('body_class','my_class_names');
function my_class_names($classes) {
return array();
}
t
4. But I want to keep page id and post id - how can I do that? Because you don't know on what index in the array that you can find this information on, and searching through the array is lame, you need to first empty the array like we did above, and then add the stuff you really want. How do you get the right information, that is, page id and post id? This is step five.
(5) At the bottom of the codex page you will find a link to the source code. This is the link you'll find: http://core.trac.wordpress.org/browser/tags/3.2.1/wp-includes/post-template.php If you look at the function, you'll see it uses a function which simply populates the same array that we can manipulate with aforementioned filter. By looking how they do it, you can do it too.
add_filter('body_class','my_class_names');
function my_class_names($classes) {
global $wp_query;
$arr = array();
if(is_page()) {
$page_id = $wp_query->get_queried_object_id();
$arr[] = 'page-id-' . $page_id;
}
if(is_single()) {
$post_id = $wp_query->get_queried_object_id();
$arr[] = 'postid-' . $post_id;
}
return $arr;
}
Hopefully this code works. If it does not, try to figure out what's wrong by following the steps above. I hope I helped at least a little bit :)
currently working code to remove and add a class
//remove body class
add_filter('body_class', function (array $classes) {
if (in_array('class_name', $classes)) {
unset( $classes[array_search('class_name', $classes)] );
}
return $classes;
});
// Add specific CSS class by body.
add_filter( 'body_class', function( $classes ) {
return array_merge( $classes, array( 'class-name' ) );
} );