I'm using a theme which i've used before and the wp_footer is loading fine in there. But in the new site the wp_footer is not loading can't find the solution by myself! Is there someone who could help me?
it's in the right place before the </body> tag.
<footer>
<div class="container">
<div class="footermenu">
<?php
$footer = array(
'theme_location' => '',
'menu' => 'footer',
'container' => 'div',
'container_class' => '',
'container_id' => '',
'menu_class' => 'menu',
'menu_id' => '',
'echo' => true,
'fallback_cb' => 'wp_page_menu',
'before' => '',
'after' => '',
'link_before' => '',
'link_after' => '',
'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
'depth' => 0,
'walker' => ''
);
wp_nav_menu($footer);
?>
<img src="http://www.web-lynx.nl/vandervalk/wp-content/uploads/2014/07/PBRB_logo-trans-300x41.png" width="300px" height="41px" class="logofooter"/>
<div class="clear"></div>
</div>
<h2><?php _e("ONZE SOCIAL MEDIA","vertaling"); ?></h2>
<div class="one_third">
<span data-icon="" class="footersocial"></span>
</div>
<div class="one_third">
<span data-icon="" class="footersocial"></span>
</div>
<div class="one_third">
<span data-icon="" class="footersocial"></span>
</div>
<div class="clear"></div>
<br>
Copyright © Van der Valk
</div>
</footer><!-- footer -->
</div><!-- site-wrapper -->
<script type="text/javascript">
jQuery('.googlemaps').click(function(){
if(jQuery('.gmap').css('display') == 'none'){
jQuery('.gmap').slideDown();
}else{
jQuery('.gmap').slideUp();
}
});
jQuery('.firstphone').click(function(){
jQuery('.otherphonenumbers').slideDown();
});
</script>
<script>
/*!
* classie v1.0.0
* class helper functions
* from bonzo https://github.com/ded/bonzo
* MIT license
*
* classie.has( elem, 'my-class' ) -> true/false
* classie.add( elem, 'my-new-class' )
* classie.remove( elem, 'my-unwanted-class' )
* classie.toggle( elem, 'my-class' )
*/
/*jshint browser: true, strict: true, undef: true, unused: true */
/*global define: false */
( function( window ) {
'use strict';
// class helper functions from bonzo https://github.com/ded/bonzo
function classReg( className ) {
return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
}
// classList support for class management
// altho to be fair, the api sucks because it won't accept multiple classes at once
var hasClass, addClass, removeClass;
if ( 'classList' in document.documentElement ) {
hasClass = function( elem, c ) {
return elem.classList.contains( c );
};
addClass = function( elem, c ) {
elem.classList.add( c );
};
removeClass = function( elem, c ) {
elem.classList.remove( c );
};
}
else {
hasClass = function( elem, c ) {
return classReg( c ).test( elem.className );
};
addClass = function( elem, c ) {
if ( !hasClass( elem, c ) ) {
elem.className = elem.className + ' ' + c;
}
};
removeClass = function( elem, c ) {
elem.className = elem.className.replace( classReg( c ), ' ' );
};
}
function toggleClass( elem, c ) {
var fn = hasClass( elem, c ) ? removeClass : addClass;
fn( elem, c );
}
var classie = {
// full names
hasClass: hasClass,
addClass: addClass,
removeClass: removeClass,
toggleClass: toggleClass,
// short names
has: hasClass,
add: addClass,
remove: removeClass,
toggle: toggleClass
};
// transport
if ( typeof define === 'function' && define.amd ) {
// AMD
define( classie );
} else {
// browser global
window.classie = classie;
}
})( window );
(function( window ){
var body = document.body,
mask = document.createElement("div"),
togglePushLeft = document.querySelector( ".toggle-push-left" ),
pushMenuLeft = document.querySelector( ".push-menu-left" ),
activeNav
;
mask.className = "mask";
/* push menu left */
togglePushLeft.addEventListener( "click", function(){
classie.add( body, "pml-open" );
document.body.appendChild(mask);
activeNav = "pml-open";
} );
/* hide active menu if mask is clicked */
mask.addEventListener( "click", function(){
classie.remove( body, activeNav );
activeNav = "";
document.body.removeChild(mask);
} );
})( window );
</script>
<?php wp_footer(); ?>
</body>
</html>
Think it has something to do with this bug!
wp-content/themes/ParadiseHotel/st-framework/admin/page-builder/page-builder.php:50 - Undefined variable: ajax_nonce
this variable is set like this
<?php
#-------------------------------------------------------------
# Smooth Theme Framework Version
#-------------------------------------------------------------
function st_framework_version_init(){
$st_framework_version = '1.0';
if(get_option('st_framework_version_init') != $st_framework_version){
update_option('st_framework_version',$st_framework_version);
}
}
add_action('init','st_framework_version_init',10);
#-------------------------------------------------------------
# Define Admin Path and URL
#-------------------------------------------------------------
define('ST_ADMIN_PATH',dirname(__FILE__));
define('ST_ADMIN_URL',ST_URL.'admin');
define('ST_PAGE_TITLE',ST_THEME_NAME.' Settings Page'); // Theme Option Title
define('ST_MENU_TITLE',ST_THEME_NAME); // Theme Option Menu Title
define('ST_PAGE_SLUG','smooththemes'); // Theme Option URL Slug
#-------------------------------------------------------------
# Load the required Framework Files
#-------------------------------------------------------------
// kiểm tra tính hợp lệ của ajax
$current_user = wp_get_current_user();
$ajax_nonce = wp_create_nonce($current_user->ID);
//check_ajax_referer( $current_user->ID, 'ajax_nonce' );
if(is_admin()){
add_action( 'wp_ajax_smooththemes_save_option_action', 'smooththemes_save_option_action' );
function smooththemes_save_option_action() {
$st_default_lang_code = get_bloginfo('language'); // DO NOT REMOVE
if(isset($_POST['save']) && $_POST['save']=='Y'){
$data = array();
foreach( $_POST as $key => $arr ){
if(strpos($key, ST_SETTINGS_OPTION)!==false){
$k = str_replace(ST_SETTINGS_OPTION.'_', '', $key);
$data[$k]= $arr;
}
}
if(st_is_wpml()){
// ICL_LANGUAGE_CODE
// echo var_dump($st_default_lang_code,ICL_LANGUAGE_CODE);
if($st_default_lang_code==ICL_LANGUAGE_CODE || ICL_LANGUAGE_CODE=='' || strpos($st_default_lang_code,ICL_LANGUAGE_CODE)!==false){
// update_option(ST_FRAMEWORK_SETTINGS_OPTION,$_POST[ST_FRAMEWORK_SETTINGS_OPTION]);
update_option(ST_SETTINGS_OPTION,$data);
}
update_option(ST_SETTINGS_OPTION.'_'.ICL_LANGUAGE_CODE, $data);
do_action('st_save_options',$data);
}else{
echo ST_SETTINGS_OPTION;
update_option(ST_SETTINGS_OPTION,$data);
do_action('st_save_options', $data );
}
flush_rewrite_rules();
}
echo 1;
die();
}
// for media
function st_image_attachment_fields_to_edit($form_fields, $post){
$form_fields["st_custom"]["label"] = '';
$form_fields["st_custom"]["input"] = "html";
$image_attributes = wp_get_attachment_image_src( $post->ID ,'medium' ); // returns an array
$form_fields["st_custom"]["html"] = '
<input type="hidden" class="st_attach_btn" data-src = "'.$image_attributes[0].'" post_id ="'.$post->ID.'" >
';
return $form_fields;
}
add_filter("attachment_fields_to_edit", "st_image_attachment_fields_to_edit", null, 99);
//----------------Show image size in mediabox-------------------
function st_insert_custom_image_sizes( $sizes ) {
// get the custom image sizes
global $_wp_additional_image_sizes;
// if there are none, just return the built-in sizes
if ( empty( $_wp_additional_image_sizes ) )
return $sizes;
// add all the custom sizes to the built-in sizes
foreach ( $_wp_additional_image_sizes as $id => $data ) {
// take the size ID (e.g., 'my-name'), replace hyphens with spaces,
// and capitalise the first letter of each word
if ( !isset($sizes[$id]) )
$sizes[$id] = ucfirst( str_replace( '-', ' ', $id ) );
}
return $sizes;
}
add_filter( 'image_size_names_choose', 'st_insert_custom_image_sizes' );
include(ST_ADMIN_PATH.'/editor/editor.php');
include(ST_ADMIN_PATH.'/admin-users.php');
include(ST_ADMIN_PATH.'/admin-functions.php');
include(ST_ADMIN_PATH.'/admin-menu.php');
include(ST_ADMIN_PATH.'/admin-scripts.php');
include(ST_ADMIN_PATH.'/ajax-media.php');
// include(ST_ADMIN_PATH.'/ajax-slidebar-generator.php');
//
if(file_exists(ST_ADMIN_PATH.'/page-builder/page-builder.php')){
include(ST_ADMIN_PATH.'/page-builder/page-builder.php');
}
if(file_exists(ST_ADMIN_PATH.'/review-control/review.php')){
include(ST_ADMIN_PATH.'/review-control/review.php');
}
include(ST_ADMIN_PATH.'/admin-meta-box.php');
include(ST_DIR.'/settings/meta-box-settings.php');
include(ST_ADMIN_PATH.'/admin-post-type.php');
include(ST_ADMIN_DIR.'admin-customize.php');
include(ST_ADMIN_DIR.'post-type-meta/event.php');
include(ST_ADMIN_DIR.'post-type-meta/room.php');
include(ST_ADMIN_DIR.'post-type-meta/gallery.php');
}
Related
I am new with wordpress, I create a image uploader which followed a youtube video. But I found that it is only showed when I create new page. I can not add the uploader to the new page.
This is my code:
For php file
namespace image_uploader;
function register_metaboxes() {
add_meta_box('image_metabox','Image Uploader', __NAMESPACE__ . '\image_uploader_callback');
}
add_action('add_meta_boxes', __NAMESPACE__ . '\register_metaboxes');
function register_admin_script() {
wp_enqueue_script('wp_img_upload', plugins_url('image-upload.js', __FILE__), array('jquery', 'media-upload'), '1.0', true);
}
add_action('admin_enqueue_scripts', __NAMESPACE__ . '\register_admin_script');
function image_uploader_callback( $post_id ) {
wp_nonce_field( basename( __FILE__ ), 'image_nonce' );
$image_stored_meta = get_post_meta( $post_id );
?>
<div class="image-preview-wrapper">
<img id="image-preview" src="<?php if ( isset ( $image_stored_meta['image_meta'] ) ) echo $image_stored_meta['image_meta'][0]; ?>" style="max-width: 250px;">
<input type="hidden" name="image_meta" id="image-meta">
<button type="button" id="image-upload-button" class="button">Upload Image</button>
<button type="button" id="image-remove-button" class="button">Remove Image</button>
</div>
<button id="nextPage">move to the next page</button>
<?php
}
function save_custom_meta( $post_id, $post, $update ) {
// Checks save status
$is_autosave = wp_is_post_autosave( $post_id );
$is_revision = wp_is_post_revision( $post_id );
$is_valid_nonce = ( isset( $_POST[ 'image_nonce' ] ) && wp_verify_nonce( $_POST[ 'image_nonce' ], basename( __FILE__ ) ) ) ? 'true' : 'false';
// Exits script depending on save status
if ( $is_autosave || $is_revision || !$is_valid_nonce ) {
return;
}
// Checks for input and sanitizes/saves if needed
if( isset( $_POST[ 'image_meta' ] ) ) {
$image_data = json_decode( stripslashes( $_POST[ 'image_meta' ] ), true );
if(is_object($image_data)) {
$image_data = array(
'id' => intval($image_data[0]->id),
'src' => esc_url_raw($image_data[0]->url),
'width' => intval($image_data[0]->width),
'height' => intval($image_data[0]->height)
);
} else {
$image_data=[];
}
update_post_meta( $post_id, 'image_meta', sanitize_text_field( $_POST[ 'image_meta' ] ) );
}
}
add_action( 'save_post', __NAMESPACE__ . '\save_custom_meta', 10, 3 );
add_filter('wp_handle_upload_prefilter','tc_handle_upload_prefilter');
function tc_handle_upload_prefilter($file)
{
$img=getimagesize($file['tmp_name']);
$fixedSize = array('width' => '400', 'height' => '600');
$width= $img[0];
$height =$img[1];
if ($width != $fixedSize['width'] )
return array("error"=>"Image dimensions are too small. Minimum width is {$fixedSize['width']}px. Uploaded image width is $width px");
elseif ($height != $fixedSize['height'])
return array("error"=>"Image dimensions are too small. Minimum height is {$fixedSize['height']}px. Uploaded image height is $height px");
else
return $file;
}
for js file
addEventListener("DOMContentLoaded", function() {
console.log('DOMContentLoaded');
var addButton = document.getElementById('image-upload-button');
var removeButton = document.getElementById('image-remove-button');
var image = document.getElementById('image-preview');
var hidden = document.getElementById('image-meta');
var next = document.getElementById('nextPage');
image.setAttribute('required', 'required');
var uploader = wp.media({
title: 'Select an image',
button: {
text: 'Use this image'
},
multiple: false
});
addButton.addEventListener('click', function(e) {
e.preventDefault();
if(uploader) {
uploader.open();
}
});
uploader.on('select', function() {
var attachment = uploader.state().get('selection').first().toJSON();
image.setAttribute('src', attachment.url);
hidden.setAttribute('value', JSON.stringify({id: attachment.id, url: attachment.url}));
});
removeButton.addEventListener('click', function(e) {
image.removeAttribute('src');
hidden.removeAttribute('value');
});
next.addEventListener('click', function(e) {
e.preventDefault();
window.location.href = "http://google.com";
});
});
I did a lot of research, but still can not figure it out.
Please give me some advices, thanks a lot!
I'm making Wordpress server side rendered block and it works well on frontend, but in editor attributes don't save (I have always default value in editor, although on frontend there is my saved value).
This is my code (not whole but minimal reproducible).
Register block on client side and set block options in editor:
const { __ } = wp.i18n;
const { ServerSideRender } = wp.editor;
const { InspectorControls } = wp.blockEditor;
const { PanelBody, __experimentalNumberControl: NumberControl } = wp.components;
registerBlockType(
'mysite/trainings',
{
title: __( 'Trainings list', 'mysite' ),
attributes: {
postsCount: {
type: 'number',
default: 9,
}
},
edit: ( { attributes, setAttributes } ) => {
const { postsCount } = attributes;
return (
<>
<InspectorControls>
<PanelBody
title={ __( 'Set number of displayed trainings', 'mysite' ) }
>
<NumberControl
value={ postsCount }
onChange={ ( value ) => setAttributes( { postsCount: value } ) }
min={ 1 }
max={ 9 }
/>
</PanelBody>
</InspectorControls>
<ServerSideRender
block="mysite/trainings"
attributes={ {
postsCount: 9,
} }
/>
</>
);
},
save() {
return null;
},
}
);
Register and render block on server side:
add_action( 'init', 'register_trainings_block' );
function register_trainings_block() {
register_block_type(
'mysite/trainings',
array(
'api_version' => 2,
'editor_script' => 'sm_editor_script',
'render_callback' => 'render_trainings_block',
'attributes' => array(
'postsCount' => array(
'type' => 'number',
'default' => 9,
),
),
)
);
}
function render_trainings_block( $attributes ) {
$query_args = array(
'post__in' => array(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 // IDs of posts
),
'post_type' => 'sm_training',
'orderby' => 'post__in',
'paged' => '1'
);
$posts = new WP_Query( $query_args );
$output = '<section class="wp-block-mysite-trainings">';
$i = 0;
foreach ( $posts->posts as $post ) {
if ( $i < $attributes['postsCount'] ) {
ob_start();
$output .= get_template_part( 'template-parts/content/training' );
$output .= ob_get_clean();
}
$i++;
}
$output .= '</section>';
return $output;
}
Enqueue editor script:
add_action( 'enqueue_block_editor_assets', 'load_editor_scripts' );
public function load_editor_scripts() {
wp_enqueue_script( 'sm_editor_script', get_template_directory_uri() . '/assets/dist/js/editor.js', array(
'wp-blocks',
'wp-i18n',
'wp-editor',
'wp-components',
'wp-block-editor'
), '1.0.0', true );
wp_localize_script( 'sm_editor_script', 'gutenbergBlocks', array( 'themeUrl' => get_template_directory_uri() ) );
}
What am I missing?
I know :)
Two things:
It should be:
<ServerSideRender
block="mysite/trainings"
attributes={ { postsCount } }
/>
(without default value here)
If attribute is number, you have to ensure that it will be saved as number.
In js change in onChange function:
<NumberControl
value={ postsCount }
onChange={ ( value ) => setAttributes( { postsCount: Number.parseInt( value ) } ) }
min={ 1 }
max={ 9 }
/>
and in php render_trainings_block function:
$attributes['postsCount'] = (int) $attributes['postsCount'];
I want to add an "insert button" on my toolbar tinymce editor.
An example of what I want :
An example of what I want
With the toolbar button, I would like to create a button in my editor and change its style. (Like the gutenberg editor does)
gutenberg editor
To use the tinymce editor, I have this code :
function wpc_boutons_tinymce($buttons) {
$buttons[] = 'underline';
$buttons[] = 'fontselect';
$buttons[] = 'fontsizeselect';
$buttons[] = 'edit-block';
return $buttons;
}
add_filter("mce_buttons_3", "wpc_boutons_tinymce");
$content = '';
$editor_id = 'mycustomeditor';
$settings = array(
'wpautop' => false,
'media_buttons' => false,
'quicktags' => array(
'buttons' => 'strong,em,del,ul,ol,li,block,close'
),
);
wp_editor( $content, $editor_id, $settings );
I didn't find how to do, can you help me ?
Here is my implemented code Follow the step
Paste the code in your theme functions.php
add_action( 'init', 'wptuts_buttons' );
function wptuts_buttons() {
add_filter( "mce_external_plugins", "wptuts_add_buttons" );
add_filter( 'mce_buttons', 'wptuts_register_buttons' );
}
function wptuts_add_buttons( $plugin_array ) {
$plugin_array['wptuts'] = get_template_directory_uri() . '/wptuts-editor-buttons/wptuts-plugin.js';
return $plugin_array;
}
function wptuts_register_buttons( $buttons ) {
array_push( $buttons, 'dropcap', 'showrecent' ); // dropcap', 'recentposts
return $buttons;
}
require( 'wptuts-editor-buttons/wptuts.php' );
Create a folder in your theme root file named wptuts-editor-buttons
Then create a file in wptuts-editor-buttons named wptuts.php and paste the code
<?php
add_shortcode( 'recent-posts', 'wptuts_recent_posts' );
function wptuts_recent_posts( $atts ) {
extract( shortcode_atts( array(
'numbers' => '5',
), $atts ) );
$rposts = new WP_Query( array( 'posts_per_page' => $numbers, 'orderby' => 'date' ) );
if ( $rposts->have_posts() ) {
$html = '<h3>Recent Posts</h3><ul class="recent-posts">';
while( $rposts->have_posts() ) {
$rposts->the_post();
$html .= sprintf(
'<li>%s</li>',
get_permalink($rposts->post->ID),
get_the_title(),
get_the_title()
);
}
$html .= '</ul>';
}
wp_reset_query();
return $html;
}
Also, You need to create a js file in wptuts-editor-buttons > wptuts-plugin.js and paste the code
(function() {
tinymce.create('tinymce.plugins.Wptuts', {
init : function(ed, url) {
ed.addButton('dropcap', {
title : 'DropCap',
cmd : 'dropcap',
image : url + '/dropcap.jpg'
});
ed.addButton('showrecent', {
title : 'Add recent posts shortcode',
cmd : 'showrecent',
image : url + '/images.jpg'
});
ed.addCommand('dropcap', function() {
var selected_text = ed.selection.getContent();
var return_text = '';
return_text = '<span class="dropcap">' + selected_text + '</span>';
ed.execCommand('mceInsertContent', 0, return_text);
});
ed.addCommand('showrecent', function() {
var number = prompt("How many posts you want to show ? "),
shortcode;
if (number !== null) {
number = parseInt(number);
if (number > 0 && number <= 20) {
shortcode = '[recent-post number="' + number + '"/]';
ed.execCommand('mceInsertContent', 0, shortcode);
}
else {
alert("The number value is invalid. It should be from 0 to 20.");
}
}
});
},
// ... Hidden code
});
// Register plugin
tinymce.PluginManager.add( 'wptuts', tinymce.plugins.Wptuts );
})();
Whole the Solution I followed the article
https://code.tutsplus.com/tutorials/guide-to-creating-your-own-wordpress-editor-buttons--wp-30182
When placing a shortcode on a custom WordPress page the output is always displayed at the top of my page content.
I found out that the problem can be fixed by either using return instead of echo, or by using output buffering: (ob_start() / ob_get_contents())
Unfortunately my coding skills are not what I would like them to be.. And I don't know exactly where to implement these fixes.
Can someone help me out please? The plugin developer is not responding to my mails and I need to get this to work a.s.a.p.
I assume this needs to be implemented in the faulty plugin's functions file so I added it below.
<?php
/**
* Woocommerce Category Accordion Functions
*
* #author TechieResource
* #category Shortcode
* #package woocommerce-category-accordion/inc
* #version 1.2.1
*/
/**
/* Clean variables
*
* #param string $var
* #return string
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
} // Exit if accessed directly
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
class trwca_wc_category_accordion{
/**
* Constructor
*/
private $shortcode_tag = "WC-Category-Accordion";
public function __construct() {
add_action( 'woocommerce_category_accordion', array( $this, 'woocommerce_category_accordion_func' ), 10, 2 );
add_shortcode( $this->shortcode_tag, array( $this, 'wc_category_accordion_sc' ) );
if ( is_admin() ){
add_action('admin_head', array( $this, 'admin_head') );
add_action( 'admin_enqueue_scripts', array($this , 'admin_enqueue_scripts' ) );
}
}
/**
* Display the Woocommerce Category Accordion.
* #since 1.2.1
* #param array $instance Arguments.
* #param bool $echo Whether to display or return the output.
* #return string
*/
public function woocommerce_category_accordion_func( $instance, $echo = true ) {
extract( $instance, EXTR_SKIP );
global $wp_query;
global $post, $product;
$exclude_tree = esc_attr($exclude_tree );
$hide_empty = esc_attr($hide_empty );
$show_count = esc_attr($show_count );
$open_cat = esc_attr($open_cat );
$ac_speed = esc_attr($ac_speed );
$ac_type = esc_attr($ac_type );
$event_type = esc_attr($event_type );
$ac_icon = esc_attr($ac_icon );
$sortby = esc_attr($sortby );
$ac_theme = esc_attr($ac_theme );
$order = esc_attr($order );
$level = esc_attr($level );
$cats_id = esc_attr($ac_opencat);
$disable_parent = esc_attr($disable_parent);
$disable_aclink = esc_attr($disable_aclink);
if(!empty($instance['id'])){
$widgetid= $instance['id'];
}
else{
if($sh_id!=""){
$widgetid= "wc_category_accordion-".$sh_id;
}
else{
$widgetid= "wc_category_accordion-".$this->trwca_generate_random_code(3);
}
}
$instance_categories = get_terms( 'product_cat', '&parent=0&exclude='.$exclude_tree.'');
if (is_array($instance_categories)) {
foreach($instance_categories as $categories) {
$term_id[] = $categories->term_id;
$term_name = $categories->name;
}
}
if(!empty($post->ID)){
$terms =get_the_terms( $post->ID, 'product_cat' );
}
else {
$terms="";
}
if (is_array($terms )) {
foreach ( $terms as $term) {
$_cat=$term->term_id;
break;
}
}
/* For current category highlight */
if(is_product()){
$current_cat= array();
$cat = $wp_query->get_queried_object();
if (!empty($cat->term_id))
{
$current_cat = $cat->term_id;
}
else{
$_cat_id="1";
if (isset($term->term_id))
{
$_cat=$term->term_id;
$_cat_id = !empty($_cat) ? $_cat_id=$_cat : $_cat_id=1 ;
}
if (is_shop())
{
$_cat_id="1";
}
if (!is_shop()){
if (is_array($terms )) {
foreach($terms as $term){
$myterms[]= $term->term_id;
}
$cats_id=end($myterms);
?>
<script type="text/javascript">
var cats_id= <?php return end($myterms); ?>;
</script>
<style type="text/css">
<?php foreach((get_the_terms($post->ID, 'product_cat')) as $term) {
$myterms= $term->term_id;
return 'ul.'.$widgetid.' li.cat-item-'.$myterms.' > a{font-weight:bold;}';
}
}
}
?>
</style>
<?php
}
}
$cat = $wp_query->get_queried_object();
if (!empty($cat->term_id) && !is_product() ){
$cats_id = $cat->term_id;
return '<script type="text/javascript">
var cats_id= '.$cats_id.';
</script>';
}
else if(!is_product_category() && !is_product()){
$cats_id=$ac_opencat;
}
$ac_type = $ac_type=="toggle" ? $ac_type= "true" : $ac_type= "false";
$open_cat = $open_cat== true || $open_cat =='on' ? $open_cat=true : $open_cat=false;
/* Icon Selection */
switch ($ac_icon) {
case 'angle' :
$open_icon="angle-down";
$close_icon="angle-right";
break;
case 'doubleangle' :
$open_icon="angle-double-down";
$close_icon="angle-double-right";
break;
case 'arrow-circle1' :
$open_icon="arrow-circle-down";
$close_icon="arrow-circle-right";
break;
case 'arrow-circle2' :
$open_icon="arrow-circle-o-down";
$close_icon="arrow-circle-o-right";
break;
case 'arrow-right' :
$open_icon="arrow-down";
$close_icon="arrow-right";
break;
case 'caret' :
$open_icon="caret-down";
$close_icon="caret-right";
break;
case 'caret-square' :
$open_icon="caret-square-o-down";
$close_icon="caret-square-o-right";
break;
case 'chevron' :
$open_icon="chevron-down";
$close_icon="chevron-right";
break;
case 'chevron-circle' :
$open_icon="chevron-circle-down";
$close_icon="chevron-circle-right";
break;
case 'hand' :
$open_icon="hand-o-down";
$close_icon="hand-o-right";
break;
case 'plus' :
$open_icon="minus";
$close_icon="plus";
break;
case 'plus-circle' :
$open_icon="minus-circle";
$close_icon="plus-circle";
break;
case 'plus-square1' :
$open_icon="minus-square";
$close_icon="plus-square";
break;
case 'plus-square2' :
$open_icon="minus-square-o";
$close_icon="plus-square-o";
break;
}
if($disable_aclink==true){
$disable_aclink='true';
}
else if($disable_aclink==""){
$disable_aclink= 'false';
}
if($disable_parent==true){
$disable_parent='true';
}
else if($disable_parent==""){
$disable_parent='false';
}
$cats_id= empty($cats_id) ? 1 : $cats_id;
?>
<script type="text/javascript">
var $=jQuery.noConflict();
$(document).ready(function($){
$('.<?php echo $widgetid; ?>').trwcAccordion({
classParent : 'trwca-parent',
classActive : 'active',
classArrow : 'trwca-icon',
classCount : 'trwca-count',
classExpand : 'trwca-current-parent',
eventType : '<?php echo $event_type; ?>',
hoverDelay : 100,
menuClose : true,
cats_id: <?php echo $cats_id; ?>,
ac_type : <?php echo $ac_type; ?>,
autoExpand : true,
speed : '<?php echo $ac_speed ?>',
saveState : '<?php echo $open_cat; ?>',
disableLink : <?php echo $disable_aclink; ?>,
disableparentLink : <?php echo $disable_parent; ?>,
auto_open: 1,
showCount : true,
widget_id : "<?php echo $widgetid; ?>",
openIcon : '<?php echo $open_icon; ?>',
closeIcon : '<?php echo $close_icon; ?>',
});
});
</script>
<div class="block-content trwca-actheme <?php echo $ac_theme; ?>">
<div class="trwca-loader"></div>
<ul class="<?php echo $widgetid; ?> accordion" id="outer_ul">
<?php
$subcat_args = array(
'taxonomy' => 'product_cat',
'title_li' => '',
'orderby' => $sortby,
'order' => $order,
'depth' => $level,
'show_count' => $show_count,
'hide_empty' => $hide_empty,
'use_desc_for_title' => 1,
'echo' => false,
'exclude' => $exclude_tree,
'hierarchical' => true ,
'show_option_none' => __('No Categories Found','trwca'),
'link_after' => '',
'walker'=> new trwca_walker
);
?>
<?php $subcategories = wp_list_categories( $subcat_args );
$subcategories=preg_replace_callback(
'/<\/a> \(([0-9]+)\)/',
function ($matches) {
return ' <span class="count">('.($matches[1]).')</span></a>';
},$subcategories
);
?>
<?php if ( $subcategories ) {
echo $subcategories;
}
?>
</ul>
</div>
<?php
}
public function trwca_generate_random_code($length=3) {
$string = '';
$characters = "123456789";
for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(0, strlen($characters)-1)];
}
return $string;
}
/**
* admin_head
* calls your functions into the correct filters
* #return void
*/
function admin_head() {
// check user permissions
if ( !current_user_can( 'edit_posts' ) && !current_user_can( 'edit_pages' ) ) {
return;
}
// check if WYSIWYG is enabled
if ( 'true' == get_user_option( 'rich_editing' ) ) {
add_filter( 'mce_external_plugins', array( $this ,'mce_external_plugins' ) );
add_filter( 'mce_buttons', array($this, 'mce_buttons' ) );
}
}
/**
* mce_external_plugins
* Adds our tinymce plugin
* #param array $plugin_array
* #return array
*/
function mce_external_plugins( $plugin_array ) {
$plugin_array['WC_Category_Accordion'] = plugins_url( 'admin/js/mce-button.js' , __FILE__ );
return $plugin_array;
}
/**
* mce_buttons
* Adds our tinymce button
* #param array $buttons
* #return array
*/
function mce_buttons( $buttons ) {
array_push( $buttons, 'WC_Category_Accordion' );
return $buttons;
}
/**
* admin_enqueue_scripts
* Used to enqueue custom styles
* #return void
*/
function admin_enqueue_scripts(){
wp_enqueue_style('WC-Category-Accordion-sh', plugins_url( 'admin/css/mce-button.css' , __FILE__ ) );
}
public function wc_category_accordion_sc( $atts, $content = null ) {
$defaults = array(
'show_count' => 0,
'ac_speed' => 'fast',
'exclude_tree' =>'',
'hide_empty' => 0,
'sortby' =>'name',
'order' =>'ASC',
'level' => 0,
'event_type' => 'click',
'ac_type' => 'toggle',
'open_cat' => 0,
'ac_opencat' => 1,
'ac_icon' =>'plus',
'disable_parent' => 0,
'disable_aclink' => 0,
'ac_theme' => '',
'sh_id'=> '' );
$settings = shortcode_atts( $defaults, $atts );
return $this->woocommerce_category_accordion_func( $settings, false );
}
}
new trwca_wc_category_accordion();
function trwca_clean( $var ) {
return sanitize_text_field( $var );
}
}
?>
Thank you guys!
function your_shortcode_function(){
ob_start(); ?>
<div>
// all your stuffs here
</div>
<?php
$contents=ob_get_contents();
ob_end_clean();
return $contents;
}
add_shortcode('your_shortcode', 'your_shortcode_function');
You need ob_start and ob_end_clean() as said as above OUTPUT BUFFERING
You'll want to use ob_start() and return ob_get_clean() inside the shortcode function.
Likeso:
<?php
function my_shortcode(){ // The function that is our shortode output.
ob_start();?>
<div class="my-shortcode-output">
<em>I'm <strong>the best</strong></em>
</div>
<?php
return $ob_get_clean();
}
add_shortcode( 'my-shortcode', 'my_shortcode' );
I'd also consider not echoing js from your php, using wp_enque_script and wp_localize_script is much nicer.
This should work.
<?php
/**
* Woocommerce Category Accordion Functions
*
* #author TechieResource
* #category Shortcode
* #package woocommerce-category-accordion/inc
* #version 1.2.1
*/
/**
/* Clean variables
*
* #param string $var
* #return string
*/
if (!defined('ABSPATH')) {
exit;
} // Exit if accessed directly
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
class trwca_wc_category_accordion
{
/**
* Constructor
*/
private $shortcode_tag = "WC-Category-Accordion";
public function __construct()
{
add_action('woocommerce_category_accordion', array(
$this,
'woocommerce_category_accordion_func'
), 10, 2);
add_shortcode($this->shortcode_tag, array(
$this,
'wc_category_accordion_sc'
));
if (is_admin()) {
add_action('admin_head', array(
$this,
'admin_head'
));
add_action('admin_enqueue_scripts', array(
$this,
'admin_enqueue_scripts'
));
}
}
/**
* Display the Woocommerce Category Accordion.
* #since 1.2.1
* #param array $instance Arguments.
* #param bool $echo Whether to display or return the output.
* #return string
*/
public function woocommerce_category_accordion_func($instance, $echo = true)
{
ob_start();
extract($instance, EXTR_SKIP);
global $wp_query;
global $post, $product;
$exclude_tree = esc_attr($exclude_tree);
$hide_empty = esc_attr($hide_empty);
$show_count = esc_attr($show_count);
$open_cat = esc_attr($open_cat);
$ac_speed = esc_attr($ac_speed);
$ac_type = esc_attr($ac_type);
$event_type = esc_attr($event_type);
$ac_icon = esc_attr($ac_icon);
$sortby = esc_attr($sortby);
$ac_theme = esc_attr($ac_theme);
$order = esc_attr($order);
$level = esc_attr($level);
$cats_id = esc_attr($ac_opencat);
$disable_parent = esc_attr($disable_parent);
$disable_aclink = esc_attr($disable_aclink);
if (!empty($instance['id'])) {
$widgetid = $instance['id'];
} else {
if ($sh_id != "") {
$widgetid = "wc_category_accordion-" . $sh_id;
} else {
$widgetid = "wc_category_accordion-" . $this->trwca_generate_random_code(3);
}
}
$instance_categories = get_terms('product_cat', '&parent=0&exclude=' . $exclude_tree . '');
if (is_array($instance_categories)) {
foreach ($instance_categories as $categories) {
$term_id[] = $categories->term_id;
$term_name = $categories->name;
}
}
if (!empty($post->ID)) {
$terms = get_the_terms($post->ID, 'product_cat');
} else {
$terms = "";
}
if (is_array($terms)) {
foreach ($terms as $term) {
$_cat = $term->term_id;
break;
}
}
/* For current category highlight */
if (is_product()) {
$current_cat = array();
$cat = $wp_query->get_queried_object();
if (!empty($cat->term_id)) {
$current_cat = $cat->term_id;
} else {
$_cat_id = "1";
if (isset($term->term_id)) {
$_cat = $term->term_id;
$_cat_id = !empty($_cat) ? $_cat_id = $_cat : $_cat_id = 1;
}
if (is_shop()) {
$_cat_id = "1";
}
if (!is_shop()) {
if (is_array($terms)) {
foreach ($terms as $term) {
$myterms[] = $term->term_id;
}
$cats_id = end($myterms);
?>
<script type="text/javascript">
var cats_id= <?php
return end($myterms);
?>;
</script>
<style type="text/css">
<?php
foreach ((get_the_terms($post->ID, 'product_cat')) as $term) {
$myterms = $term->term_id;
return 'ul.' . $widgetid . ' li.cat-item-' . $myterms . ' > a{font-weight:bold;}';
}
}
}
?>
</style>
<?php
}
}
$cat = $wp_query->get_queried_object();
if (!empty($cat->term_id) && !is_product()) {
$cats_id = $cat->term_id;
return '<script type="text/javascript">
var cats_id= ' . $cats_id . ';
</script>';
} else if (!is_product_category() && !is_product()) {
$cats_id = $ac_opencat;
}
$ac_type = $ac_type == "toggle" ? $ac_type = "true" : $ac_type = "false";
$open_cat = $open_cat == true || $open_cat == 'on' ? $open_cat = true : $open_cat = false;
/* Icon Selection */
switch ($ac_icon) {
case 'angle':
$open_icon = "angle-down";
$close_icon = "angle-right";
break;
case 'doubleangle':
$open_icon = "angle-double-down";
$close_icon = "angle-double-right";
break;
case 'arrow-circle1':
$open_icon = "arrow-circle-down";
$close_icon = "arrow-circle-right";
break;
case 'arrow-circle2':
$open_icon = "arrow-circle-o-down";
$close_icon = "arrow-circle-o-right";
break;
case 'arrow-right':
$open_icon = "arrow-down";
$close_icon = "arrow-right";
break;
case 'caret':
$open_icon = "caret-down";
$close_icon = "caret-right";
break;
case 'caret-square':
$open_icon = "caret-square-o-down";
$close_icon = "caret-square-o-right";
break;
case 'chevron':
$open_icon = "chevron-down";
$close_icon = "chevron-right";
break;
case 'chevron-circle':
$open_icon = "chevron-circle-down";
$close_icon = "chevron-circle-right";
break;
case 'hand':
$open_icon = "hand-o-down";
$close_icon = "hand-o-right";
break;
case 'plus':
$open_icon = "minus";
$close_icon = "plus";
break;
case 'plus-circle':
$open_icon = "minus-circle";
$close_icon = "plus-circle";
break;
case 'plus-square1':
$open_icon = "minus-square";
$close_icon = "plus-square";
break;
case 'plus-square2':
$open_icon = "minus-square-o";
$close_icon = "plus-square-o";
break;
}
if ($disable_aclink == true) {
$disable_aclink = 'true';
} else if ($disable_aclink == "") {
$disable_aclink = 'false';
}
if ($disable_parent == true) {
$disable_parent = 'true';
} else if ($disable_parent == "") {
$disable_parent = 'false';
}
$cats_id = empty($cats_id) ? 1 : $cats_id;
?>
<script type="text/javascript">
var $=jQuery.noConflict();
$(document).ready(function($){
$('.<?php
echo $widgetid;
?>').trwcAccordion({
classParent : 'trwca-parent',
classActive : 'active',
classArrow : 'trwca-icon',
classCount : 'trwca-count',
classExpand : 'trwca-current-parent',
eventType : '<?php
echo $event_type;
?>',
hoverDelay : 100,
menuClose : true,
cats_id: <?php
echo $cats_id;
?>,
ac_type : <?php
echo $ac_type;
?>,
autoExpand : true,
speed : '<?php
echo $ac_speed;
?>',
saveState : '<?php
echo $open_cat;
?>',
disableLink : <?php
echo $disable_aclink;
?>,
disableparentLink : <?php
echo $disable_parent;
?>,
auto_open: 1,
showCount : true,
widget_id : "<?php
echo $widgetid;
?>",
openIcon : '<?php
echo $open_icon;
?>',
closeIcon : '<?php
echo $close_icon;
?>',
});
});
</script>
<div class="block-content trwca-actheme <?php
echo $ac_theme;
?>">
<div class="trwca-loader"></div>
<ul class="<?php
echo $widgetid;
?> accordion" id="outer_ul">
<?php
$subcat_args = array(
'taxonomy' => 'product_cat',
'title_li' => '',
'orderby' => $sortby,
'order' => $order,
'depth' => $level,
'show_count' => $show_count,
'hide_empty' => $hide_empty,
'use_desc_for_title' => 1,
'echo' => false,
'exclude' => $exclude_tree,
'hierarchical' => true,
'show_option_none' => __('No Categories Found', 'trwca'),
'link_after' => '',
'walker' => new trwca_walker
);
$subcategories = wp_list_categories($subcat_args);
$subcategories = preg_replace_callback('/<\/a> \(([0-9]+)\)/', function($matches)
{
return ' <span class="count">(' . ($matches[1]) . ')</span></a>';
}, $subcategories);
if ($subcategories) {
echo $subcategories;
}
?>
</ul>
</div>
<?php
$contents=ob_get_contents();
ob_end_clean();
return $contents;
}
public function trwca_generate_random_code($length = 3)
{
$string = '';
$characters = "123456789";
for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(0, strlen($characters) - 1)];
}
return $string;
}
/**
* admin_head
* calls your functions into the correct filters
* #return void
*/
function admin_head()
{
// check user permissions
if (!current_user_can('edit_posts') && !current_user_can('edit_pages')) {
return;
}
// check if WYSIWYG is enabled
if ('true' == get_user_option('rich_editing')) {
add_filter('mce_external_plugins', array(
$this,
'mce_external_plugins'
));
add_filter('mce_buttons', array(
$this,
'mce_buttons'
));
}
}
/**
* mce_external_plugins
* Adds our tinymce plugin
* #param array $plugin_array
* #return array
*/
function mce_external_plugins($plugin_array)
{
$plugin_array['WC_Category_Accordion'] = plugins_url('admin/js/mce-button.js', __FILE__);
return $plugin_array;
}
/**
* mce_buttons
* Adds our tinymce button
* #param array $buttons
* #return array
*/
function mce_buttons($buttons)
{
array_push($buttons, 'WC_Category_Accordion');
return $buttons;
}
/**
* admin_enqueue_scripts
* Used to enqueue custom styles
* #return void
*/
function admin_enqueue_scripts()
{
wp_enqueue_style('WC-Category-Accordion-sh', plugins_url('admin/css/mce-button.css', __FILE__));
}
public function wc_category_accordion_sc($atts, $content = null)
{
$defaults = array(
'show_count' => 0,
'ac_speed' => 'fast',
'exclude_tree' => '',
'hide_empty' => 0,
'sortby' => 'name',
'order' => 'ASC',
'level' => 0,
'event_type' => 'click',
'ac_type' => 'toggle',
'open_cat' => 0,
'ac_opencat' => 1,
'ac_icon' => 'plus',
'disable_parent' => 0,
'disable_aclink' => 0,
'ac_theme' => '',
'sh_id' => ''
);
$settings = shortcode_atts($defaults, $atts);
return $this->woocommerce_category_accordion_func($settings, false);
}
}
new trwca_wc_category_accordion();
function trwca_clean($var)
{
return sanitize_text_field($var);
}
}
?>
is it possible within WooCommerce to change the variations dropdown into radio buttons without having to work with a plugin? I would like to have the following setup on the variations section:
1 liter (10€)
2 liter (20€)
3 Liter (25€)
The price at the bottom should be automatically changed when you select an option.
Thank you
EDIT: added variation_check() and JS variation checking thanks to #ThomasB!
EDIT2: make sure variation_check() also checks for backorder status to allow selection when a product can be backordered.
The best way I managed to get this working is to add radio button markup directly after the select dropdowns and then hide the select dropdowns using CSS. You'll also need some custom JS to trigger the hidden select value changes so that your price will change according to the radio button you select.
Here's how I added the markup:
function variation_radio_buttons($html, $args) {
$args = wp_parse_args(apply_filters('woocommerce_dropdown_variation_attribute_options_args', $args), array(
'options' => false,
'attribute' => false,
'product' => false,
'selected' => false,
'name' => '',
'id' => '',
'class' => '',
'show_option_none' => __('Choose an option', 'woocommerce'),
));
if(false === $args['selected'] && $args['attribute'] && $args['product'] instanceof WC_Product) {
$selected_key = 'attribute_'.sanitize_title($args['attribute']);
$args['selected'] = isset($_REQUEST[$selected_key]) ? wc_clean(wp_unslash($_REQUEST[$selected_key])) : $args['product']->get_variation_default_attribute($args['attribute']);
}
$options = $args['options'];
$product = $args['product'];
$attribute = $args['attribute'];
$name = $args['name'] ? $args['name'] : 'attribute_'.sanitize_title($attribute);
$id = $args['id'] ? $args['id'] : sanitize_title($attribute);
$class = $args['class'];
$show_option_none = (bool)$args['show_option_none'];
$show_option_none_text = $args['show_option_none'] ? $args['show_option_none'] : __('Choose an option', 'woocommerce');
if(empty($options) && !empty($product) && !empty($attribute)) {
$attributes = $product->get_variation_attributes();
$options = $attributes[$attribute];
}
$radios = '<div class="variation-radios">';
if(!empty($options)) {
if($product && taxonomy_exists($attribute)) {
$terms = wc_get_product_terms($product->get_id(), $attribute, array(
'fields' => 'all',
));
foreach($terms as $term) {
if(in_array($term->slug, $options, true)) {
$id = $name.'-'.$term->slug;
$radios .= '<input type="radio" id="'.esc_attr($id).'" name="'.esc_attr($name).'" value="'.esc_attr($term->slug).'" '.checked(sanitize_title($args['selected']), $term->slug, false).'><label for="'.esc_attr($id).'">'.esc_html(apply_filters('woocommerce_variation_option_name', $term->name)).'</label>';
}
}
} else {
foreach($options as $option) {
$id = $name.'-'.$option;
$checked = sanitize_title($args['selected']) === $args['selected'] ? checked($args['selected'], sanitize_title($option), false) : checked($args['selected'], $option, false);
$radios .= '<input type="radio" id="'.esc_attr($id).'" name="'.esc_attr($name).'" value="'.esc_attr($option).'" id="'.sanitize_title($option).'" '.$checked.'><label for="'.esc_attr($id).'">'.esc_html(apply_filters('woocommerce_variation_option_name', $option)).'</label>';
}
}
}
$radios .= '</div>';
return $html.$radios;
}
add_filter('woocommerce_dropdown_variation_attribute_options_html', 'variation_radio_buttons', 20, 2);
function variation_check($active, $variation) {
if(!$variation->is_in_stock() && !$variation->backorders_allowed()) {
return false;
}
return $active;
}
add_filter('woocommerce_variation_is_active', 'variation_check', 10, 2);
And here's the JS I used:
$(document).on('change', '.variation-radios input', function() {
$('.variation-radios input:checked').each(function(index, element) {
var $el = $(element);
var thisName = $el.attr('name');
var thisVal = $el.attr('value');
$('select[name="'+thisName+'"]').val(thisVal).trigger('change');
});
});
$(document).on('woocommerce_update_variation_values', function() {
$('.variation-radios input').each(function(index, element) {
var $el = $(element);
var thisName = $el.attr('name');
var thisVal = $el.attr('value');
$el.removeAttr('disabled');
if($('select[name="'+thisName+'"] option[value="'+thisVal+'"]').is(':disabled')) {
$el.prop('disabled', true);
}
});
});
I don't know how to do that without a plugin, but I suggest you drop that requirement, and use the Woocommerce Radio Buttons plugin. This does exactly what you want:
You can use Variation Swatches for WooCommerce plugin. It worked for me.
I extended further the JavaScript part of cfx' answer to include cases of multiple variations. The idea is to hide and show available variations (radio buttons) based on the select inputs.
<script>
jQuery(document).on('change', '.variation-radios input', function() {
jQuery('.variation-radios input:checked').each(function(index, element) {
let el = jQuery(element);
jQuery('select[name="' + el.attr('name') + '"]').val(el.attr('value')).trigger('change');
recreateRadioInputs();
});
});
jQuery(document).on('woocommerce_update_variation_values', function() {
jQuery('.variation-radios input').each(function(index, element) {
let el = jQuery(element);
el.removeAttr('disabled');
if(jQuery('select[name="' + el.attr('name') + '"] option[value="' + el.attr('value') + '"]').is(':disabled')) {
$el.prop('disabled', true);
}
});
});
// recreate readio inputs based on the select inputs
function recreateRadioInputs() {
jQuery('.variation-radios input, .variation-radios label').hide();
jQuery('.variations select').each(function() {
let inputName = jQuery(this).attr('name');
jQuery(this).find('option').each(function() {
let inputVal = jQuery(this).val();
let radioInput = jQuery('.variation-radios input[value="' + inputVal + '"]');
jQuery('.variation-radios label[for="' + radioInput.attr('id') + '"]').show();
radioInput.show();
});
});
}
</script>