I have a custom WordPress plugin that is showing me a list of data from database. I am registering it's page via:
add_menu_page(
'Naročila',
'Vsa naročila',
'administrator',
'listaj-narocila',
array( &$this, 'listaj_narocila' )
);
And then of course I have function lista_narocila which is showing me my data.
So, currently my URL is:
http://domain.com/wp-admin/admin.php?page=listaj-narocila
And I show my data from database in a table. Now I have button DELETE and EDIT for each record, but I have a hard time figuring it out, how to register custom "url" or "custom page" inside WordPress that would allow me to have URL:
http://domain.com/wp-admin/admin.php?page=single-narocilo?id=X
I know I can try with add_menu_page but I don't want this page to be in admin menus. Just to be available as URL. Currently I get no access error.
You can create a sub menu page and pass null as its parent:
$parent_slug
Use NULL or set to 'options.php' if you want to create a page that doesn't appear in any menu.
A demo:
add_action('admin_menu', function()
{
# Main page
add_menu_page(
'Vsa',
'Vsa',
'add_users', // Capability, not role
'listaj-narocila',
function(){
printf(
'<h2>%s</h2>%s',
__( 'Main page' ),
admin_url( 'admin.php?page=single-norcilo&id='.rand(1,25) ),
__( 'Hidden sub page' )
);
},
'http://sstatic.net/stackexchange/img/favicon.ico'
);
# Child page
$hook = add_submenu_page(
null,
'Norcilo',
'Norcilo',
'add_users',
'single-norcilo',
function(){
printf(
'<h2>%s</h2>%s',
__( 'Hidden sub page' ),
admin_url( 'admin.php?page=listaj-narocila' ),
__( 'back' )
);
}
);
# Enqueue script in submenu page to fix the current menu indicator
add_action( "admin_footer-$hook", function()
{
echo <<<HTML
<script type="text/javascript">
jQuery(document).ready( function($) {
$('#toplevel_page_listaj-narocila')
.removeClass('wp-not-current-submenu')
.addClass('current');
});
</script>
HTML;
});
});
An alternative approach: https://wordpress.stackexchange.com/a/114818/12615
Related
Works on small home project, and want to add checkmark option bellow "Proceed to Checkout" button into Cart page into my Woocommerce site. I found this function, that is add that option:
add_action( 'woocommerce_after_cart', 'bbloomer_add_checkout_privacy_policy', 9 );
function bbloomer_add_checkout_privacy_policy() {
woocommerce_form_field( 'privacy_policy', array(
'type' => 'checkbox',
'class' => array('form-row privacy'),
'label_class' => array('woocommerce-form__label woocommerce-form__label-for-checkbox checkbox'),
'input_class' => array('woocommerce-form__input woocommerce-form__input-checkbox input-checkbox'),
'required' => true,
'label' => 'By proceeding, you are agreeing to our Terms and Conditions',
));
}
// Show notice if customer does not tick
add_action( 'woocommerce_proceed_to_checkout', 'bbloomer_not_approved_privacy' );
function bbloomer_not_approved_privacy() {
if ( ! (int) isset( $_POST['privacy_policy'] ) ) {
wc_add_notice( __( 'Please acknowledge the Terms and Conditions' ), 'error' );
}
}
But seems that something is not fine with this function, because no matter if checked or not, customer can proceed to checkout page. I want to ensure that ONLY customers who will check the checkbox, can proceed to checkout. In opposite, warning message will be shown at top.
Can someone to tell me where is issue with this function or to point me to some working solution? Thanks in advance. This is image how currently looks with this function i posted before.
The following code will work in cart page for your privacy policy checkbox using mandatory jQuery code to make it work as "proceed to checkout" button is just linked to checkout page without submitting any data.
The code will disable the button on start:
It use "Sweet alert 2" JS message to display an error message on button click when the checkbox is not checked:
The complete code:
add_action( 'woocommerce_proceed_to_checkout', 'cart_privacy_policy_checkbox', 5 );
function cart_privacy_policy_checkbox() {
woocommerce_form_field( 'privacy_policy', array(
'type' => 'checkbox',
'class' => array('form-row privacy'),
'label_class' => array('woocommerce-form__label woocommerce-form__label-for-checkbox checkbox'),
'input_class' => array('woocommerce-form__input woocommerce-form__input-checkbox input-checkbox'),
'required' => true,
'label' => sprintf( __( "I've read and accept the %s", "woocommerce" ),
''.__( "Privacy Policy", "woocommerce" ).'' ),
));
// jQuery code start below
?>
<script src="https://unpkg.com/sweetalert2#8.8.1/dist/sweetalert2.all.min.js"></script>
<script src="https://unpkg.com/promise-polyfill#8.1.0/dist/polyfill.min.js"></script>
<script type="text/javascript">
jQuery( function($){
var a = '.checkout-button', b = '#privacy_policy',
c = '<?php echo wc_get_checkout_url(); ?>', d = 'disabled';
// Set disable button state
$(a).addClass(d).prop('href', '#');
// Woocommerce Ajax cart events
$('body').on('updated_cart_totals removed_from_cart', function(){
if( ! ( $(a).hasClass(d) && $(b).prop('checked') ) ){
$(a).addClass(d).prop('href', '#');
}
})
// On button click event
$('body').on('click', a, function(e){
if( ! $(b).prop('checked') ) {
// Disable "Proceed to checkout" button
e.preventDefault();
// disabling button state
if( ! $(a).hasClass(d) ){
$(a).addClass(d).prop('href', '#');
}
// Sweet alert 2
swal({
title: '<?php _e("Pricacy Policy", "woocommerce"); ?>',
text: '<?php _e("Please acknowledge the privacy policy Terms and Conditions", "woocommerce"); ?>',
type: 'error',
timer: 3500,
showConfirmButton: false
});
}
});
// On checkbox change event
$(b).change(function(){
if($(this).prop('checked')){
if( $(a).hasClass(d) ){
$(a).removeClass(d).prop('href', c);
}
} else {
if( ! $(a).hasClass(d) ){
$(a).addClass(d).prop('href', '#');
}
}
});
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Sweet Alert Two documentation
Thanks a lot for this code!
It works for me, except for when the cart is updated via ajax such as when deleting an item.
In that situation, the checkbox no longer enables the Proceed to Checkout button unless I refresh the page. I finally found a solution:
Add the following snippet to the header to reload the cart page after an item is deleted from the cart.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
jQuery( document.body ).on( 'updated_cart_totals', function () {
location.reload( true );
} );
</script>
Which file do I need to edit if I don’t want user to click the link to apply the coupon code?
In simple, I want no LINK to be clicked on.
I want the apply coupon appear below the text "Have a coupon?" so that user can ALWAYS see the section.
Updated
This can be done very easily using dedicated woocommerce_checkout_coupon_message filter hook:
add_filter( 'woocommerce_checkout_coupon_message', 'custom_checkout_coupon_message', 20, 1 );
function custom_checkout_coupon_message( $message ) {
?>
<script type='text/javascript'>
jQuery(document).ready( function($){
setTimeout(function(){
$('form.checkout_coupon').css('display','block');
}, 300);
});
</script>
<?php
// HERE your custom message
return __( 'Have a coupon?', 'woocommerce' ) . ' <a class="showcoupon-off">' . __( 'Below you can enter your coupon code', 'woocommerce' ) . '</a>';
}
Code goes in function.php file of the active child theme (or active theme). Tested and works.
Is it possible to count how many times a certain link in post has been clicked?
(for example purpose, let's say that the certain link has an ID named 'bla')
<a id="bla" href="#">download</a>
I got a feeling it should be possible by using custom-fields/post-meta (to keep the count), just like the ever-so-popular 'visitor count' trick. Unfortunately, I'm rather clueless about PHPs.
It could be done with ajax call that updates post meta field before the link is followed. Example below registers ajax action for users that are not logged in, and increases link_click_counter custom field by 1 on each click. Link must have id attribute countable_link. This is a basic example that works for only one link in post. To use it as a plugin create file like wp-content/plugins/click-counter /click-counter.php and copy-paste example code, or put the code in functions.php inside theme folder. First time the link is clicked, new custom field link_click_counter will be created for that post, and there you can track how many clicks link has.
HTML:
<a id="countable_link" href="#">download</a>
PHP:
<?php
/*
Plugin Name: Link Clicks Counter
*/
if ( is_admin() ) add_action( 'wp_ajax_nopriv_link_click_counter', 'link_click_counter' );
function link_click_counter() {
if ( isset( $_POST['nonce'] ) && isset( $_POST['post_id'] ) && wp_verify_nonce( $_POST['nonce'], 'link_click_counter_' . $_POST['post_id'] ) ) {
$count = get_post_meta( $_POST['post_id'], 'link_click_counter', true );
update_post_meta( $_POST['post_id'], 'link_click_counter', ( $count === '' ? 1 : $count + 1 ) );
}
exit();
}
add_action( 'wp_head', 'link_click_head' );
function link_click_head() {
global $post;
if( isset( $post->ID ) ) {
?>
<script type="text/javascript" >
jQuery(function ($) {
var ajax_options = {
action: 'link_click_counter',
nonce: '<?php echo wp_create_nonce( 'link_click_counter_' . $post->ID ); ?>',
ajaxurl: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
post_id: '<?php echo $post->ID; ?>'
};
$( '#countable_link' ).on( 'click', function() {
var self = $( this );
$.post( ajax_options.ajaxurl, ajax_options, function() {
window.location.href = self.attr( "href" );
});
return false;
});
});
</script>
<?php
}
}
?>
One possible way is to redirect all through a common PHP gateway and from there, redirect to the original page you wanted to redirect using Header('Location: yourpage.html');
In the gateway PHP page count the number by incrementing a saved value by 1.
I have created a plugin that adds a input box, 'Logo URL' on the Settings > General page in WordPress. This input can be called and works correctly. I have created another plugin that pulls the 'Logo URL' and applies the path to pull an image for the Login screen. Everything appears peachy.
The only issue I am having is that I would like to move the 'Logo URL' on the Settings > General page to up under 'Site Address (URL)'. I am at a loss on how to do this. I have scoured the web and been unable to find a helpful answer.
I am currently removing the original General page and adding a New General page but am unsure how to parse the correct options-general.php.
How to move the Logo_URL higher on the General Page?
/**
* This is the code to create the Settings box on the Settings > General
*/
$new_general_setting = new new_general_setting();
class new_general_setting {
function new_general_setting( ) {
add_filter( 'admin_init' , array( &$this , 'register_fields' ) );
}
function register_fields() {
register_setting( 'general', 'URL_logo', 'esc_attr' );
add_settings_field('URL_logo', '<label for="URL_logo">'.__('Website logo (URL)' , 'URL_logo' ).'</label>' , array(&$this, 'fields_html') , 'general' );
}
function fields_html() {
$value = get_option( 'URL_logo', '' );
echo '<input type="text" id="URL_logo" name="URL_logo" value="' . $value . '" />';
}
}
No, there's no way of ordering that natively. WordPress first prints its stuff then ours. It has to be done with jQuery.
add_action( 'admin_footer-options-general.php', function()
{
?>
<script type="text/javascript">
jQuery(document).ready( function($)
{
var son = $("label[for='URL_logo']").parent().parent(); // Our setting field
var father = $("label[for='home']").parent().parent(); // WordPress setting field
son.insertAfter(father);
});
</script>
<?php
});
The recommended way is to enqueue the JS inside an action call for "admin_print_scripts-$hookname". Note the hook name use in admin_footer and admin_head too.
As your field only changes after the page loaded, we can notice the "jump". To smooth it, we can use:
add_action( 'admin_head-options-general.php', function()
{
echo '<style>#wpbody .wrap form{display:none}</style>';
});
And add this jQuery after replaceWith():
$('#wpbody .wrap form').fadeIn('slow');
I create post options and I want to implement wordpress color picker core inside it
I tried this code I got it from many tutorials and sources but unfortunately It's not working at all, It's like I never added the code.
HTML
<input name="mv_cr_section_color" type="text" id="mv_cr_section_color" value="#ffffff" data-default-color="#ffffff">
PHP
function Colorpicker(){
wp_enqueue_style( 'wp-color-picker');
wp_enqueue_script( 'wp-color-picker');
}
add_action('admin_enqueue_scripts', 'Colorpicker');
JQuery
jQuery(document).ready(function(){
jQuery('#mv_cr_section_color').wpColorPicker();
});
You don't say how you're creating the Theme Options page, but the following is a working example. It's almost the same code as your sample code, but the enqueue is done directly on the custom menu page callback and jQuery is being referenced as $ (note its declaration in ready(function($)):
<?php
/**
* Plugin Name: Testing the Color Picker
*/
add_action( 'admin_menu', 'b5f_demo_menu' );
function b5f_demo_menu()
{
add_menu_page(
'Test',
'Test',
'edit_pages',
'test-slug',
'b5f_callback_function'
);
}
function b5f_callback_function()
{
wp_enqueue_script('wp-color-picker');
wp_enqueue_style( 'wp-color-picker' );
?>
<input name="mv_cr_section_color" type="text" id="mv_cr_section_color" value="#ffffff" data-default-color="#ffffff">
<script type="text/javascript">
jQuery(document).ready(function($) {
$('#mv_cr_section_color').wpColorPicker();
});
</script>
<?php
}
When using admin_enqueue_scripts, the callback function has one parameter $hook_suffix. With it, you can make sure the scripts and styles are only added in the correct screen:
add_action( 'admin_enqueue_scripts', 'b5f_custom_enqueue' );
function b5f_custom_enqueue( $hook_suffix )
{
// CHECK IF CORRECT PAGE, IF NOT DO NOTHING
# if ( 'my_hook-name' != $hook_suffix )
# return;
?>
<script type="text/javascript">
// Use this to check the hook_suffix name
console.log('<?php echo $hook_suffix; ?>');
</script>
<?php
}
Just include a jQuery file and stylesheet file by this script.
// Register Scripts & Styles in Admin panel
function custom_color_picker_scripts() {
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script( 'iris', admin_url( 'js/iris.min.js' ), array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), false, 1 );
wp_enqueue_script( 'cp-active', plugins_url('/js/cp-active.js', __FILE__), array('jquery'), '', true );
}
add_action( 'admin_enqueue_scripts', custom_color_picker_scripts);
Now create a new javascript file as like cp-active.js and keep it avobe defined “/js/cp-active.js” file path using bellows code.
jQuery('.color-picker').iris({
// or in the data-default-color attribute on the input
defaultColor: true,
// a callback to fire whenever the color changes to a valid color
change: function(event, ui){},
// a callback to fire when the input is emptied or an invalid color
clear: function() {},
// hide the color picker controls on load
hide: true,
// show a group of common colors beneath the square
palettes: true
});
Add a textbox to your settings page with a CSS class for the color picker, where you want to display the input text. I have use “color_code” for input $variable.
<input id="color_code" class="color-picker" name="color_code" type="text" value="" />
Please see more details on Add jQuery Color Picker WordPress Theme or Plugin