Product page details tabs to lightbox - wordpress

in my woocomere product page there is tabs of a product to display different information (description, etc). But i wish to be able to in a specific tab turn in a ligthbox popup that shows text or a image. Is there any plugin available in wordpress for it?

Please try below code in function.php to show tab content in light box. Might be you will have to customize more but basic structure i am sharing with you.
add_action( 'woocommerce_product_write_panel_tabs','outputTabTitle');
add_action( 'woocommerce_product_write_panels','outputTabEditContent');
add_filter( 'woocommerce_product_tabs','productTab');
function outputTabTitle ()
{
?>
<li class="custom_tab">
Additional Information
</li>
<?php
}
function outputTabEditContent ()
{
global $woocommerce, $post;
echo '<div id="custom-tab" class="panel woocommerce_options_panel">';
/************Please put you lightbox text and image here.
echo '</div>';
}
function productTab ( $tabs )
{
$tabs['custom-tab'] = array(
'title' => __( 'Additional Information', 'woocommerce' ),
'priority' => 50,
'callback' => 'outputTabEditContent'
);
return $tabs;
}

Related

Wordpress plugin add_settings_field exact code works in one instance but not in a second instance?

I am writing a plugin making admin options pages using the combo "register_setting", "add_settings_section", "add_settings_field". I have a parent menu and 2 sub-menus. Making admin pages in Wordpress is pretty straight forward... it starts when you make the admin page. Here are my parameters for it. (this is done in OOP)
'parent_slug' => 'Tee_Off',
'page_title' => 'Tee-Off Reports',
'menu_title' => 'Tee-Off Reports',
'capability' => 'manage_options',
'menu_slug' => 'tee_offs_reports',
'callback' => 'path to my template file goes here'; //this is correct in my code
so remember my menu slug "tee_offs_reports" posted above is needed for the next step...
class ClubHouseReports
{
function register()
{
add_action( 'admin_init', array( $this, 'teeoff_report_sellector') );
}
function teeoff_report_sellector() {
register_setting( 'my_options_group', 'timer_month' );
register_setting( 'my_options_group', 'timer_day' );
register_setting( 'my_options_group', 'timer_year' );
add_settings_section( 'teeoff-club-options', 'Get Monthy Report', array( $this, 'teeoff_month_section'), 'tee_offs_reports');
add_settings_field( 'timer_month', 'Month', array( $this, 'teeoff_month'), 'tee_offs_reports', 'teeoff-club-options');
add_settings_field( 'timer_day', 'Day', array( $this, 'teeoff_day'), 'tee_offs_reports', 'teeoff-club-options');
add_settings_field( 'timer_year', 'Year', array( $this, 'teeoff_year'), 'tee_offs_reports', 'teeoff-club-options');
}
function teeoff_month_section() {
echo '<p>Reports</p>';
}
function teeoff_month() {
$timer_month = esc_attr( get_option( 'timer_month' ) );
echo '<input type="text" class="regular-text" name="timer_month" value="'.$timer_month.'" placeholder="Month" />';
}
function teeoff_day() {
$timer_day = esc_attr( get_option( 'timer_day' ) );
echo '<input type="text" class="regular-text" name="timer_day" value="'.$timer_day.'" placeholder="Day" />';
}
function teeoff_year() {
$timer_year = esc_attr( get_option( 'timer_year' ) );
echo '<input type="text" class="regular-text" name="timer_month" value="'.$timer_year.'" placeholder="Year" />';
}
}
This class above is being call from the root plugin file, just like the one that works. An instance is made then the method "register()" is called.
In my template file I do this.... just like the one that does work.
<?php settings_errors(); ?>
<form method="post" action="options.php">
<?php settings_fields( 'my_options_group' ); ?>
<?php do_settings_sections('teeoff-club-options'); ?>
<?php submit_button(); ?>
</form>
SO my problem is... except for where the values need to change when you repeat the same code, in this case like, you need to assign a new menu slug, a new name for the "register_setting", and making sure it's aiming at the right callback, which I assure you everything is set right... for some reason this wont render.
I get no errors, all I see is the submit button, and if I use it I get a "success" message, so everything is in scope... but nothing is rendering on the "tee_offs_reports" page except for the submit button... which makes sense since it's hard coded there.
All this to say... I went over my code dozens of time to look for the smallest/stupidiest syntax mistake, or anything why this admin area wont work, while the other which uses the exact same structure and logic, works 100%. Do you see anything wrong with this code? Don't mind the big space between code above, that only happened when I pasted it here.... Is there a restriction in wordpress that I don't know of yet? Why is this not working? While a blue print of it works just fine.
OK, now I'm really baffled... I got it to work, but I highly doubt I'm following the codex rules... or am I?????
here is the code that is working 100%
function teeoff_report_sellector() {
register_setting( 'my_options_group', 'timer_month' );
register_setting( 'my_options_group', 'timer_day' );
register_setting( 'my_options_group', 'timer_year' );
add_settings_section('tee-off-reports', 'Get Monthy Report', array( $this, 'teeoff_month_section'), 'tee-off-reports');
add_settings_field('timer_month', 'Month', array( $this, 'teeoff_month'), 'tee-off-reports', 'tee-off-reports');
add_settings_field('timer_day', 'Day', array( $this, 'teeoff_day'), 'tee-off-reports', 'tee-off-reports');
add_settings_field('timer_year', 'Year', array( $this, 'teeoff_year'), 'tee-off-reports', 'tee-off-reports');
}
function teeoff_month_section() {
echo '<p>Reports</p>';
}
function teeoff_month() {
$timer_month = esc_attr( get_option( 'timer_month' ) );
echo '<input type="date" class="regular-text" name="timer_month" value="'.$timer_month.'" placeholder="Month" />';
}
function teeoff_day() {
$timer_day = esc_attr( get_option( 'timer_day' ) );
echo '<input type="text" class="regular-text" name="timer_day" value="'.$timer_day.'" placeholder="Day" />';
}
function teeoff_year() {
$timer_year = esc_attr( get_option( 'timer_year' ) );
echo '<input type="text" class="regular-text" name="timer_year" value="'.$timer_year.'" placeholder="Year" />';
}
What I did is... instead of using the menu slug like the codex tells you to do, ...(and the first admin page I created works well that way) I replaced that by the "add_settings_section" ID... so if you look at the before last parameter for each "add_settings_field" they are now assigned the ID of the section, codex is supposed to be looking for the menu slug... I always thought anyways... again the first one I did, works awesome that way... so the 2 last parameters of the "add_settings_field" are the same. Weird! Nowhere is the page slug mention in the code above, yet this works 100% and does not break any other code.
Now I'm wondering... did I find a bug in the Settings API? that will be fixed later on, and my plugin is going to stop working? Or did I stumble on the solution by being desperate trying a whole bunch of stuff???
I don't get it... if there's a real WordPress guru out there that can explain this to me I would be very appreciative!

Need to Change Sale Badge Text in WooCommerce

The following works for the Product page but it does not work for the Shop page.
<?php
add_filter('woocommerce_sale_flash', 'woocommerce_custom_sale_text', 10, 3);
function woocommerce_custom_sale_text($text, $post, $_product)
{
return '<span class="onsale">PUT YOUR TEXT</span>';
}
Please suggest modifications.
Thanks!
Use This
add_filter( 'woocommerce_sale_flash', 'wooc_custom_replace_sale_text' );
function wooc_custom_replace_sale_text( $html ) {
return str_replace( __( 'Sale!', 'woocommerce' ), __( 'Your Text', 'woocommerce' ), $html );
}
I tried your code and it works perfectly for the shop page as well. You may try increasing the priority or it can be a conflict with some other plugin or theme.
You may also check the following file to confirm it has applied the woocommerce_sale_flash filter
woocommerce\templates\loop\sale-flash.php

WordPress unlimited sidebars

Just wondering if someone could give me some advice on how to create unlimited sidebars for a WordPress theme.
So, basically I am looking into adding a meta box on posts and pages with a drop down list of all available sidebars, where the user can then select a specific sidebar for any post or page. This part I have figured out, however I would also like to add functionality here to allow users to create custom sidebars for any post or page. So, essentially the user could choose any sidebar for any post or page or create new sidebars for any post or page which then could be filled with widgets on the widgets page.
I half there, just not sure how to go about creating the functionality to create new sidebars.
There is a way to do it but it's a bit lengthy.
Create a customizer control to add multiple sidebars
The easiest way is to just take the custom control called Multi Input field from here. Also, be sure to add this custom control, and all the jQuery functionality that goes with it (in the .js file).
With that, add to your customizer file (or if you don't have a dedicated customizer file, to your functions.php file)
if(!function_exists('yourtheme_text_sanitization')){
function yourtheme_text_sanitization($input){
return wp_kses_post( force_balance_tags($input) );
}
}
/**
------------------------------------------------------------
SECTION: Sidebars
------------------------------------------------------------
**/
$wp_customize->add_section('section_sidebars', array(
'title' => esc_html__('Sidebars', 'yourtheme'),
'priority' => 0,
));
/**
Sidebars
**/
$wp_customize->add_setting('sidebars', array(
'default' => '',
'sanitize_callback' => 'yourtheme_text_sanitization',
));
$wp_customize->add_control(new Multi_Input_Custom_control($wp_customize, 'sidebars', array(
'label' => esc_html__( 'Sidebars', 'yourtheme' ),
'description' => esc_html__( 'Add as many custom sidebars as you need', 'yourtheme' ),
'settings' => 'sidebars',
'section' => 'section_sidebars',
)));
The first function is the sanitization function for your customizer sanitization callback.
So now you should have 'Sidebars' in your Appearance > Customize menu.
Create sidebars dynamically
But now you need to add your sidebars. If you have a dedicated sidebar file like sidebars.php where you register your theme sidebars, you can put this there, or in your functions.php file
if ( function_exists( 'register_sidebar' ) ) {
$sidebars=get_theme_mod('sidebars','');
if($sidebars!=''){
$sidebars = explode('|', $sidebars);
$i = 0;
foreach($sidebars as $sidebar){
$i++;
register_sidebar(array(
'name'=>$sidebar,
'id' => 'sidebar-'.$i,
'before_widget' => '<div id="%1$s" class="widget %2$s">',
'after_widget' => '</div>',
'before_title' => '<div class="sidebar-widget-heading"><h3>',
'after_title' => '</h3></div>',
));
}
}
}
This is the minimum you need so that you can add multiple sidebars in the theme, and they should appear in Appearance > Widgets.
Add sidebar metabox
Now adding a metabox to display them is relatively easy. In your functions.php, or a separate file where you add metaboxes to posts/pages/CPT, add
// Add metabox
add_action('admin_init', 'yourtheme_post_add_meta');
if ( ! function_exists( 'yourtheme_post_add_meta' ) ){
function yourtheme_post_add_meta(){
add_meta_box('post-sidebar', esc_html__('Select Sidebar', 'yourtheme'), 'yourtheme_post_sidebar_meta_box', 'post');
}
}
//Metabox
if ( ! function_exists( 'yourtheme_post_sidebar_meta_box' ) ){
function yourtheme_post_sidebar_meta_box( $post ){
$values = get_post_custom( $post->ID );
$custom_sidebar = (isset($values['custom_sidebar'][0])) ? $values['custom_sidebar'][0] : '';
wp_nonce_field( 'my_meta_box_sidebar_nonce', 'meta_box_sidebar_nonce' );
?>
<p>
<select name="custom_sidebar" id="custom_sidebar">
<?php
global $wp_registered_sidebars;
$sidebar_replacements = $wp_registered_sidebars;
if(is_array($sidebar_replacements) && !empty($sidebar_replacements)){
foreach($sidebar_replacements as $sidebar){
echo "<option value='{$sidebar['name']}'".selected($sidebar['name'], $custom_sidebar, false).">{$sidebar['name']}</option>";
}
}
?>
</select>
</p>
<?php
}
}
//Save Metabox
add_action( 'save_post', 'yourtheme_post_save_sidebar_meta_box' );
if ( ! function_exists( 'yourtheme_post_save_sidebar_meta_box' ) ){
function yourtheme_post_save_sidebar_meta_box( $post_id ){
if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ){
return;
}
if( !isset( $_POST['custom_sidebar'] ) || !wp_verify_nonce( $_POST['meta_box_sidebar_nonce'], 'my_meta_box_sidebar_nonce' ) ) {
return;
}
if( !current_user_can( 'edit_pages' ) ) {
return;
}
if( isset( $_POST['custom_sidebar'] ) ){
update_post_meta( $post_id, 'custom_sidebar', wp_kses( $_POST['custom_sidebar'] ,'') );
}
}
}
And this should be it. A bit lengthy, but a way to add as many sidebars to your theme as you wish :)
Hope it helps.
Giving the users option to choose a sidebar is fine, but i dont think its a good idea to give them functionality to create their own sidebars. You will quickly get into the problem where you will have tons of sidebars in your widget area each for a different post.
However if i was in your situation, i would have created a single sidebar and then dynamically added widgets to this sidebar depending on the post that is being viewed. For the end user both will look the same. Anyways there is no right or wrong answer here, it depends on how you want to tackle the situation.

How to add custom post type archive to menu

I have been searching for weeks and I still haven't found a proper solution to this problem.
I am writing a Wordpress Theme. I have a custom post type called Works. I would like to add my Works archive to my menu and have it as well as it's posts highlighted when I access them.
I can access my archive and posts on the following links
Works archive: /works/
Works single post: /works/postname/
My solution so fare have been to name my archive-works.php template file with a template name (Work archive). Then create an empty page using that template and adding the page to the menu. This highlights the archive in the menu but not the single posts.
I can easily solve this with a custom link and some javascript but there must be a better and cleaner way.
You can do a simple trick in your functions.php:
add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2);
function current_type_nav_class($classes, $item) {
// Get post_type for this post
$post_type = get_query_var('post_type');
// Go to Menus and add a menu class named: {custom-post-type}-menu-item
// This adds a 'current_page_parent' class to the parent menu item
if( in_array( $post_type.'-menu-item', $classes ) )
array_push($classes, 'current_page_parent');
return $classes;
}
In your case, you just have to add a class 'works-menu-item' with that archive menu item by the admin panel;
To add "custom posttype archive link" to menu, please look at the following guide
Open file functions.php , and enter code below
add_action('admin_head-nav-menus.php', 'wpclean_add_metabox_menu_posttype_archive');
function wpclean_add_metabox_menu_posttype_archive() {
add_meta_box('wpclean-metabox-nav-menu-posttype', __('Custom Post Type Archives'), 'wpclean_metabox_menu_posttype_archive', 'nav-menus', 'side', 'default');
}
function wpclean_metabox_menu_posttype_archive() {
$post_types = get_post_types(array('show_in_nav_menus' => true, 'has_archive' => true), 'object');
if ($post_types) :
$items = array();
$loop_index = 999999;
foreach ($post_types as $post_type) {
$item = new stdClass();
$loop_index++;
$item->object_id = $loop_index;
$item->db_id = 0;
$item->object = 'post_type_' . $post_type->query_var;
$item->menu_item_parent = 0;
$item->type = 'custom';
$item->title = $post_type->labels->name;
$item->url = get_post_type_archive_link($post_type->query_var);
$item->target = '';
$item->attr_title = '';
$item->classes = array();
$item->xfn = '';
$items[] = $item;
}
$walker = new Walker_Nav_Menu_Checklist(array());
echo '<div id="posttype-archive" class="posttypediv">';
echo '<div id="tabs-panel-posttype-archive" class="tabs-panel tabs-panel-active">';
echo '<ul id="posttype-archive-checklist" class="categorychecklist form-no-clear">';
echo walk_nav_menu_tree(array_map('wp_setup_nav_menu_item', $items), 0, (object) array('walker' => $walker));
echo '</ul>';
echo '</div>';
echo '</div>';
echo '<p class="button-controls">';
echo '<span class="add-to-menu">';
echo '<input type="submit"' . disabled(1, 0) . ' class="button-secondary submit-add-to-menu right" value="' . __('Add to Menu') . '" name="add-posttype-archive-menu-item" id="submit-posttype-archive" />';
echo '<span class="spinner"></span>';
echo '</span>';
echo '</p>';
endif;
}
Thanks
Thanks to rasmussvanejensen for her/his nice question and thethangtran for the answer, I am still confused why Wordpress has not yet added such a good feature to its code base by default.
By the way I think there is even a better solution than the one provided by thethangtran, as it may break on some situations.
Note 1
According to the Codex, using register_post_type, one can add extra post_types to the installation. There is chance, some one need to change the 'query_var' and thus the provided code will break.
Note 2
In addition, it may not handle the current-menu-item class, which will be used for css customization to show the menu item as active.
Note 3
As another note on the code, there is no need to define the loop_index, item and items variables. they are absolutely useless.
A better solution
So I suggest using this alternative, for those who want a more robust solution to on this:
function prefix_add_metabox_menu_posttype_archive(){
add_meta_box( 'prefix_metabox_menu_posttype_archive', __( 'Archives' ), 'prefix_metabox_menu_posttype_archive', 'nav-menus', 'side', 'default' );
}
add_action( 'admin_head-nav-menus.php', 'prefix_add_metabox_menu_posttype_archive' );
function prefix_metabox_menu_posttype_archive(){
$post_types = get_post_types( array( 'show_in_nav_menus' => true, 'has_archive' => true ), 'object' );
if( $post_types ){
foreach( $post_types as $post_type ){
$post_type->classes = array( $post_type->name );
$post_type->type = $post_type->name;
$post_type->object_id = $post_type->name;
$post_type->title = $post_type->labels->name;
$post_type->object = 'cpt_archive';
}
$walker = new Walker_Nav_Menu_Checklist( array() );?>
<div id="cpt-archive" class="posttypediv">
<div id="tabs-panel-cpt-archive" class="tabs-panel tabs-panel-active">
<ul id="ctp-archive-checklist" class="categorychecklist form-no-clear"><?php
echo walk_nav_menu_tree( array_map( 'wp_setup_nav_menu_item', $post_types ), 0, (object) array( 'walker' => $walker ) );?>
</ul>
</div>
</div>
<p class="button-controls">
<span class="add-to-menu">
<input type="submit"<?php disabled( $nav_menu_selected_id, 0 ); ?> class="button-secondary submit-add-to-menu" value="<?php esc_attr_e( 'Add to Menu' ); ?>" name="add-ctp-archive-menu-item" id="submit-cpt-archive" />
</span>
</p><?php
}
}
function prefix_cpt_archive_menu_filter( $items, $menu, $args ){
foreach( $items as &$item ){
if( $item->object != 'cpt_archive' ) continue;
$item->url = get_post_type_archive_link( $item->type );
if( get_query_var( 'post_type' ) == $item->type ){
$item->classes []= 'current-menu-item';
$item->current = true;
}
}
return $items;
}
add_filter( 'wp_get_nav_menu_items', 'prefix_cpt_archive_menu_filter', 10, 3 );
Navigate to Appearance > Menus;
Make sure you have the Works' custom post type selected at Screen Options;
Click on the name of your custom post type to expand it and then click on the ‘View all’ tab;
You will see an option for All Works. Check the box next to it and then click on the Add to Menu button;
Your custom post type archive will now appear as a menu item in the right column;
By default, the label will be "All Works". You can change this by writing something different at the Navigation Label;
Click on the Save Menu button to save your changes.
I found a solution on GitHub and it works out of the box by simply adding it to the functions.php without any walkers or extra classes.
This code solves it by comparing the slug of the current post type
with the navigation items, and adds a class accordingly.
Code on GitHub

how to insert shortcode into wordpress menu

I have made a menu item with this code.
The menu item shows up but the shortcode output is not there.
Is there something I can add or a different method that will do this.
I have added also in hopes this might help.
add_filter('wp_nav_items', 'do_shortcode', 7);
Or maybe someone knows this is not possible and can tell me.
/* Nav Menu */
function add_profile_link_to_nav(){
if ( is_user_logged_in() ) { ?>
<ul>
<li class="menu-item"id="one"> All Members
<ul class="sub-menu">
<li class="menu-item"><?php echo custom_execute_shortcode(); ?> </li>
</ul>
</li>
</ul> <!--end menu--->
<?php }
}
add_action( "wp_nav_items","add_profile_link_to_nav" );
function custom_execute_shortcode() {
$myfunction= '[my shortcode"]';
$myfunction_parsed = do_shortcode($myfunction);
return $myfunction_parsed;
}
Thanks
#Tim
This code will work
put it in functions.php file
add_filter('wp_nav_menu_items', 'do_shortcode');
You can't use shortcodes directly in the menu URL on the menu page, because the brackets get stripped out. But you can use placeholders like this: #profile_link#.
With the following code in functions.php, you can create a custom menu item with the URL #profile_link#, and it will replace that with your shortcode.
/**
* Filters all menu item URLs for a #placeholder#.
*
* #param WP_Post[] $menu_items All of the nave menu items, sorted for display.
*
* #return WP_Post[] The menu items with any placeholders properly filled in.
*/
function my_dynamic_menu_items( $menu_items ) {
// A list of placeholders to replace.
// You can add more placeholders to the list as needed.
$placeholders = array(
'#profile_link#' => array(
'shortcode' => 'my_shortcode',
'atts' => array(), // Shortcode attributes.
'content' => '', // Content for the shortcode.
),
);
foreach ( $menu_items as $menu_item ) {
if ( isset( $placeholders[ $menu_item->url ] ) ) {
global $shortcode_tags;
$placeholder = $placeholders[ $menu_item->url ];
if ( isset( $shortcode_tags[ $placeholder['shortcode'] ] ) ) {
$menu_item->url = call_user_func(
$shortcode_tags[ $placeholder['shortcode'] ]
, $placeholder['atts']
, $placeholder['content']
, $placeholder['shortcode']
);
}
}
}
return $menu_items;
}
add_filter( 'wp_nav_menu_objects', 'my_dynamic_menu_items' );
You just need to set 'shortcode' in the $placeholders array, and optionally 'atts' and 'content'.
For example, if your shortcode is like this:
[example id="5" other="test"]Shortcode content[/example]
You would update:
'#placeholder#' => array(
'shortcode' => 'example';
'atts' => array( 'id' => '5', 'other' => 'test' );
'content' => 'Shortcode content';
),
Note that I don't use do_shortcode() because it is a resource intensive function and isn't the right tool for the job in this case.
Enable description on the menu page, paste to the description textarea of the link your shortcode, in functions.php add next code:
add_filter('walker_nav_menu_start_el', function($item_output, $item) {
if (!is_object($item) || !isset($item->object)) {
return $item_output;
}
if ($item->ID === 829) {
$item_output = do_shortcode($item->description);
}
return $item_output;
}, 20, 2);

Resources