Forum Replies Created
-
AuthorPosts
-
September 21, 2020 at 4:28 pm in reply to: TinyMCE showing HTML tags in custom shortcode elements. #1247395
Yes, go ahead and close it out.
As much as I love using the theme, and will continue to use it in the future, I’m still disappointed in the lack of support. This turned out to be an issue with how the data was being prepared before being sent to the editor, and not an issue with the editor, itself.
I feel that this is something that somebody on the team should have taken on as an issue to resolve, rather than claiming it to be a TinyMCE problem and leaving it at that.
Anyway, we’ll still use the plugin, but I do feel that the support isn’t really worth much value.
September 18, 2020 at 9:06 pm in reply to: TinyMCE showing HTML tags in custom shortcode elements. #1246936Ok, I was able to resolve the issue by overriding the set_default_values function in the shortcode class.
I added the function from enfold/config-templatebuilder/avia-template-builder/php/shortcode-template.class.php/** * helper function executed by aviaShortcodeTemplate::popup_editor that extracts the attributes from the shortcode and then merges the values into the options array * * @param array $elements * @return array $elements */ public function set_default_values($elements) { $shortcode = !empty($_POST['params']['shortcode']) ? $_POST['params']['shortcode'] : ''; if($shortcode) { //will extract the shortcode into $_POST['extracted_shortcode'] $this->builder->text_to_interface($shortcode); //the main shortcode (which is always the last array item) will be stored in $extracted_shortcode $extracted_shortcode = end($_POST['extracted_shortcode']); //if the $_POST['extracted_shortcode'] has more than one items we are dealing with nested shortcodes $multi_content = count($_POST['extracted_shortcode']); //proceed if the main shortcode has either arguments or content if(!empty($extracted_shortcode['attr']) || !empty($extracted_shortcode['content'])) { if(empty($extracted_shortcode['attr'])) $extracted_shortcode['attr'] = array(); if(isset($extracted_shortcode['content'])) $extracted_shortcode['attr']['content'] = $extracted_shortcode['content']; //iterate over each array item and check if we already got a value foreach($elements as &$element) { if(isset($element['id']) && isset($extracted_shortcode['attr'][$element['id']])) { //make sure that each element of the popup can access the other values of the shortcode. necessary for hidden elements $element['shortcode_data'] = $extracted_shortcode['attr']; //if the item has subelements the std value has to be an array if(isset($element['subelements'])) { $element['std'] = array(); for ($i = 0; $i < $multi_content - 1; $i++) { $element['std'][$i] = $_POST['extracted_shortcode'][$i]['attr']; $element['std'][$i]['content'] = $_POST['extracted_shortcode'][$i]['content']; } } else { $element['std'] = stripslashes($extracted_shortcode['attr'][$element['id']]); } } else { if($element['type'] == "checkbox") $element['std'] = ''; } } } } return $elements; }
I modified it to be as follows:
/** * helper function executed by aviaShortcodeTemplate::popup_editor that extracts the attributes from the shortcode and then merges the values into the options array * * @param array $elements * @return array $elements */ public function set_default_values($elements) { $shortcode = !empty($_POST['params']['shortcode']) ? $_POST['params']['shortcode'] : ''; if($shortcode) { //will extract the shortcode into $_POST['extracted_shortcode'] $this->builder->text_to_interface($shortcode); //the main shortcode (which is always the last array item) will be stored in $extracted_shortcode $extracted_shortcode = end($_POST['extracted_shortcode']); //if the $_POST['extracted_shortcode'] has more than one items we are dealing with nested shortcodes $multi_content = count($_POST['extracted_shortcode']); //proceed if the main shortcode has either arguments or content if(!empty($extracted_shortcode['attr']) || !empty($extracted_shortcode['content'])) { if(empty($extracted_shortcode['attr'])) $extracted_shortcode['attr'] = array(); if(isset($extracted_shortcode['content'])) $extracted_shortcode['attr']['content'] = $extracted_shortcode['content']; //iterate over each array item and check if we already got a value foreach($elements as &$element) { if(isset($element['id']) && isset($extracted_shortcode['attr'][$element['id']])) { //make sure that each element of the popup can access the other values of the shortcode. necessary for hidden elements $element['shortcode_data'] = $extracted_shortcode['attr']; //if the item has subelements the std value has to be an array if(isset($element['subelements'])) { $element['std'] = array(); for ($i = 0; $i < $multi_content - 1; $i++) { $element['std'][$i] = $_POST['extracted_shortcode'][$i]['attr']; $element['std'][$i]['content'] = $_POST['extracted_shortcode'][$i]['content']; } } else { $element['std'] = html_entity_decode(stripslashes($extracted_shortcode['attr'][$element['id']])); } } else { if($element['type'] == "checkbox") $element['std'] = ''; } } } } return $elements; }
The difference is that I changed this:
$element['std'] = stripslashes($extracted_shortcode['attr'][$element['id']]);
to this:
$element['std'] = html_entity_decode(stripslashes($extracted_shortcode['attr'][$element['id']]));
and included it in my shortcode element, which is finished below:
<?php /** * 2 Column Module * * Builds 2 column modules with image on one side and content on the other. */ if ( ! defined( 'ABSPATH' ) ) { exit; } // Exit if accessed directly if ( ! class_exists( 'avia_sc_two_column_module' ) ) { class avia_sc_two_column_module extends aviaShortcodeTemplate { /** * Create the config array for the shortcode button */ function shortcode_insert_button() { $this->config['version'] = '1.0'; $this->config['self_closing'] = 'yes'; $this->config['name'] = __( '2 Column Modules', 'avia_framework' ); $this->config['tab'] = __( 'Content Elements', 'avia_framework' ); $this->config['icon'] = AviaBuilder::$path['imagesURL'] . 'sc-blog.png'; $this->config['order'] = 40; $this->config['target'] = 'avia-target-insert'; $this->config['shortcode'] = 'av_two_column_module'; $this->config['tooltip'] = __( 'Builds 2 Column Modules ', 'avia_framework' ); $this->config['preview'] = false; $this->config['id_name'] = 'id'; $this->config['id_show'] = 'yes'; $this->config['alb_desc_id'] = 'alb_description'; } function admin_assets() { $ver = AviaBuilder::VERSION; } function extra_assets() { wp_enqueue_style( 'two-column-module', get_stylesheet_directory_uri() . '/shortcodes/assets/twocolumnmodule.css', array( 'avia-layout' ), false ); } /** * helper function executed by aviaShortcodeTemplate::popup_editor that extracts the attributes from the shortcode and then merges the values into the options array * * @param array $elements * @return array $elements */ public function set_default_values($elements) { $shortcode = !empty($_POST['params']['shortcode']) ? $_POST['params']['shortcode'] : ''; if($shortcode) { //will extract the shortcode into $_POST['extracted_shortcode'] $this->builder->text_to_interface($shortcode); //the main shortcode (which is always the last array item) will be stored in $extracted_shortcode $extracted_shortcode = end($_POST['extracted_shortcode']); //if the $_POST['extracted_shortcode'] has more than one items we are dealing with nested shortcodes $multi_content = count($_POST['extracted_shortcode']); //proceed if the main shortcode has either arguments or content if(!empty($extracted_shortcode['attr']) || !empty($extracted_shortcode['content'])) { if(empty($extracted_shortcode['attr'])) $extracted_shortcode['attr'] = array(); if(isset($extracted_shortcode['content'])) $extracted_shortcode['attr']['content'] = $extracted_shortcode['content']; //iterate over each array item and check if we already got a value foreach($elements as &$element) { if(isset($element['id']) && isset($extracted_shortcode['attr'][$element['id']])) { //make sure that each element of the popup can access the other values of the shortcode. necessary for hidden elements $element['shortcode_data'] = $extracted_shortcode['attr']; //if the item has subelements the std value has to be an array if(isset($element['subelements'])) { $element['std'] = array(); for ($i = 0; $i < $multi_content - 1; $i++) { $element['std'][$i] = $_POST['extracted_shortcode'][$i]['attr']; $element['std'][$i]['content'] = $_POST['extracted_shortcode'][$i]['content']; } } else { $element['std'] = html_entity_decode(stripslashes($extracted_shortcode['attr'][$element['id']])); } } else { if($element['type'] == "checkbox") $element['std'] = ''; } } } } return $elements; } /** * Popup Elements * * If this function is defined in a child class the element automatically gets an edit button, that, when pressed * opens a modal window that allows to edit the element properties * * @return void */ function popup_elements() { $this->elements = array( array( 'type' => 'tab_container', 'nodescription' => true ), array( 'type' => 'tab', 'name' => __( 'Content', 'avia_framework' ), 'nodescription' => true ), array( 'type' => 'template', 'template_id' => 'toggle_container', 'templates_include' => array( $this->popup_key( 'selected_project' ) ), 'nodescription' => true ), array( 'type' => 'tab_close', 'nodescription' => true ), array( 'type' => 'tab', 'name' => __( 'Advanced', 'avia_framework' ), 'nodescription' => true ), array( 'type' => 'toggle_container', 'nodescription' => true ), array( 'type' => 'template', 'template_id' => 'screen_options_toggle' ), array( 'type' => 'template', 'template_id' => 'developer_options_toggle', 'args' => array( 'sc' => $this ) ), array( 'type' => 'toggle_container_close', 'nodescription' => true ), array( 'type' => 'tab_close', 'nodescription' => true ), array( 'type' => 'tab_container_close', 'nodescription' => true ) ); } /** * Create and register templates for easier maintainance * * @since 4.6.4 */ protected function register_dynamic_templates() { /** * Content Tab * =========== */ $c = array( array( 'name' => __( 'Module Content', 'avia_framework' ), 'desc' => __( 'What is the content for this module?', 'avia_framework' ), 'id' => 'module_content', 'type' => 'tiny_mce', 'std' => '', ), array( 'name' => __( 'Module Image', 'avia_framework' ), 'desc' => __( 'What is image for this module? (Select Large if available, Full Size if Large is not available.)', 'avia_framework' ), 'id' => 'module_image', 'type' => 'image', 'title' => __( 'Insert Image', 'avia_framework' ), 'button' => __( 'Insert', 'avia_framework' ), 'std' => AviaBuilder::$path['imagesURL'] . 'placeholder.jpg' ), array( 'name' => __( 'Image Side?', 'avia_framework' ), 'desc' => __( 'What side of the module will the image be on?', 'avia_framework' ), 'id' => 'image_side', 'type' => 'select', 'std' => 'left', 'subtype' => array( __( 'Left', 'avia_framework' ) => 'left', __( 'Right', 'avia_framework' ) => 'right' ) ) ); $template = array( array( 'type' => 'template', 'template_id' => 'toggle', 'title' => __( '2 Column Module', 'avia_framework' ), 'content' => $c ), ); AviaPopupTemplates()->register_dynamic_template( $this->popup_key( 'selected_project' ), $template ); } /** * Editor Element - this function defines the visual appearance of an element on the AviaBuilder Canvas * Most common usage is to define some markup in the $params['innerHtml'] which is then inserted into the drag and drop container * Less often used: $params['data'] to add data attributes, $params['class'] to modify the className * * * @param array $params this array holds the default values for $content and $args. * @return $params the return array usually holds an innerHtml key that holds item specific markup. */ function editor_element( $params ) { $params = parent::editor_element( $params ); $params['content'] = null; //remove to allow content elements return $params; } /** * Frontend Shortcode Handler * * @param array $atts array of attributes * @param string $content text within enclosing form of shortcode element * @param string $shortcodename the shortcode found, when == callback name * @return string $output returns the modified html string */ function shortcode_handler( $atts, $content = '', $shortcodename = '', $meta = '' ) { global $avia_config, $more; extract( $atts ); $cards = []; ob_start(); //start buffering the output instead of echoing it $img = wp_get_attachment_image( $attachment, 'large' ); echo $this->render_module(ShortcodeHelper::avia_apply_autop( ShortcodeHelper::avia_remove_autop( $module_content ) ), $image_side, $module_image, $img); $output = ob_get_clean(); avia_set_layout_array(); return $output; } function render_module($content,$image_side,$module_image, $image) { $html = ''; $html .= '<div class="two-column-module '.$image_side.'-side">'; $html .= '<div class="image-container"><div class="module-image" style="background:url(\''.$module_image.'\'); background-repeat: no-repeat; background-position: center '.$image_side.'; background-size: cover"></div></div>'; $html .= '<div class="content-container">'.$content.'</div>'; return $html .= '</div>'; } } }
It also works properly with multiple tiny_mce boxes, too.
Note – this is only a problem when you create a custom shortcode element and give it an id of something other than ‘content’.September 18, 2020 at 8:36 pm in reply to: TinyMCE showing HTML tags in custom shortcode elements. #1246932I was able to fix the issue, although I had to hard-code it into the theme file, which I hate doing.
I added the below code to the enfold/config-templatebuilder/avia-template-builder/php/html-helper-class.php file.
$element['std'] = html_entity_decode($element['std']);
You can put it anywhere within the tiny_mce function.
static public function tiny_mce($element) { //tinymce only allows ids in the range of [a-z] so we need to filter them. $element['id'] = preg_replace('![^a-zA-Z_]!', '', $element['id']); /* monitor this: seems only ajax elements need the replacement */ $user_ID = get_current_user_id(); if(get_user_meta($user_ID, 'rich_editing', true) == "true" && isset($element['ajax'])) { global $wp_version; //replace new lines with brs, otherwise the editor will mess up. this was fixed with wp 4.3 so only do that in old versions if ( version_compare( $wp_version, "4.3", '<' ) ) { $element['std'] = str_replace("\n",'<br>',$element['std']); } } $element['std'] = html_entity_decode($element['std']); ob_start(); wp_editor( $element['std'], $element['id'] , array('editor_class' => 'avia_advanced_textarea avia_tinymce', 'media_buttons' => true ) ); $output = ob_get_clean(); return $output; }
I haven’t yet found a place where I can override what gets passed into this function as the $element argument, in order to avoid hard-coding it into the file.
Since I’ve gotten it this far, would it be possible for somebody on the team to possibly figure out how to finish resolving the issue, without having to hard-code it into the theme file?
September 18, 2020 at 2:58 pm in reply to: TinyMCE showing HTML tags in custom shortcode elements. #1246837Thanks, I’ll look into the valid_elements and see if that might be something that can be used.
It’s strange that the image isn’t working, because it works fine on the site. In fact, everything works fine, except for the issue of the html tags being displayed.
September 16, 2020 at 3:43 pm in reply to: TinyMCE showing HTML tags in custom shortcode elements. #1246359Well, that’s somewhat disappointing, since the theme offers multiple other ways to extend it’s functionality.
What if we removed the problem of having more than one open at a time? Is it still too difficult of an issue to figure out why it displays the html elements instead of working the proper way?
September 15, 2020 at 11:32 pm in reply to: TinyMCE showing HTML tags in custom shortcode elements. #1246128Just checking to see if there is any update for this.
Thanks!
September 7, 2020 at 7:36 pm in reply to: TinyMCE showing HTML tags in custom shortcode elements. #1244087It’s not a plugin conflict. Also, when I tested on the other site, I tested this same module on another site.
Here’s the code that I have for the custom shortcode. If you use it, you should experience the same effect.
<?php /** * 2 Column Full-Width * * Builds 2 column modules with image on one side and content on the other. */ if ( ! defined( 'ABSPATH' ) ) { exit; } // Exit if accessed directly if ( ! class_exists( 'avia_sc_two_column_full_module' ) ) { class avia_sc_two_column_full_module extends aviaShortcodeTemplate { /** * Create the config array for the shortcode button */ function shortcode_insert_button() { $this->config['version'] = '1.0'; $this->config['self_closing'] = 'yes'; $this->config['name'] = __( '2 Column Full-Width Modules', 'avia_framework' ); $this->config['tab'] = __( 'Content Elements', 'avia_framework' ); $this->config['icon'] = AviaBuilder::$path['imagesURL'] . 'sc-blog.png'; $this->config['order'] = 40; $this->config['target'] = 'avia-target-insert'; $this->config['shortcode'] = 'av_two_column_full_module'; $this->config['tooltip'] = __( 'Builds 2 Column Full-Width Modules ', 'avia_framework' ); $this->config['preview'] = false; $this->config['id_name'] = 'id'; $this->config['id_show'] = 'yes'; $this->config['alb_desc_id'] = 'alb_description'; } function admin_assets() { $ver = AviaBuilder::VERSION; } function extra_assets() { $ver = AviaBuilder::VERSION; wp_enqueue_style( 'two-column-full-module', get_stylesheet_directory_uri() . '/shortcodes/assets/twocolumnfullmodule.css', array( 'avia-layout' ), false ); wp_enqueue_script( 'two-column-full-module-js', get_stylesheet_directory_uri() . '/shortcodes/assets/twocolumnfullmodule.js', array( 'jquery' ), $ver, true ); } /** * Popup Elements * * If this function is defined in a child class the element automatically gets an edit button, that, when pressed * opens a modal window that allows to edit the element properties * * @return void */ function popup_elements() { $this->elements = array( array( 'type' => 'tab_container', 'nodescription' => true ), array( 'type' => 'tab', 'name' => __( 'Content', 'avia_framework' ), 'nodescription' => true ), array( 'type' => 'template', 'template_id' => 'toggle_container', 'templates_include' => array( $this->popup_key( 'selected_project' ) ), 'nodescription' => true ), array( 'type' => 'tab_close', 'nodescription' => true ), array( 'type' => 'tab', 'name' => __( 'Advanced', 'avia_framework' ), 'nodescription' => true ), array( 'type' => 'toggle_container', 'nodescription' => true ), array( 'type' => 'template', 'template_id' => 'screen_options_toggle' ), array( 'type' => 'template', 'template_id' => 'developer_options_toggle', 'args' => array( 'sc' => $this ) ), array( 'type' => 'toggle_container_close', 'nodescription' => true ), array( 'type' => 'tab_close', 'nodescription' => true ), array( 'type' => 'tab_container_close', 'nodescription' => true ) ); } /** * Create and register templates for easier maintainance * * @since 4.6.4 */ protected function register_dynamic_templates() { /** * Content Tab * =========== */ $c = array( array( 'name' => __( 'Module Headline Content', 'avia_framework' ), 'desc' => __( 'What is the upper headline content for this module?', 'avia_framework' ), 'id' => 'module_content', 'type' => 'tiny_mce', 'std' => '', ), array( 'name' => __( 'Module Body Content', 'avia_framework' ), 'desc' => __( 'What is the main body content for this module?', 'avia_framework' ), 'id' => 'module_body_content', 'type' => 'tiny_mce', 'std' => '', ), array( 'name' => __( 'Module Image', 'avia_framework' ), 'desc' => __( 'What is image for this module? (Select Large if available, Full Size if Large is not available.)', 'avia_framework' ), 'id' => 'module_image', 'type' => 'image', 'title' => __( 'Insert Image', 'avia_framework' ), 'button' => __( 'Insert', 'avia_framework' ), 'std' => AviaBuilder::$path['imagesURL'] . 'placeholder.jpg' ), array( 'name' => __( 'Show Pathway?', 'avia_framework' ), 'desc' => __( 'Do you want to show the pathway instead of an image?', 'avia_framework' ), 'id' => 'show_pathway', 'type' => 'select', 'std' => 'no', 'subtype' => array( __( 'No', 'avia_framework' ) => 'no', __( 'Yes', 'avia_framework' ) => 'yes' ) ), array( 'name' => __( 'Image Side?', 'avia_framework' ), 'desc' => __( 'What side of the module will the image be on?', 'avia_framework' ), 'id' => 'image_side', 'type' => 'select', 'std' => 'left', 'subtype' => array( __( 'Left', 'avia_framework' ) => 'left', __( 'Right', 'avia_framework' ) => 'right' ) ) ); $template = array( array( 'type' => 'template', 'template_id' => 'toggle', 'title' => __( '2 Column Module', 'avia_framework' ), 'content' => $c ), ); AviaPopupTemplates()->register_dynamic_template( $this->popup_key( 'selected_project' ), $template ); } /** * Editor Element - this function defines the visual appearance of an element on the AviaBuilder Canvas * Most common usage is to define some markup in the $params['innerHtml'] which is then inserted into the drag and drop container * Less often used: $params['data'] to add data attributes, $params['class'] to modify the className * * * @param array $params this array holds the default values for $content and $args. * @return $params the return array usually holds an innerHtml key that holds item specific markup. */ function editor_element( $params ) { $params = parent::editor_element( $params ); $params['content'] = null; //remove to allow content elements return $params; } /** * Frontend Shortcode Handler * * @param array $atts array of attributes * @param string $content text within enclosing form of shortcode element * @param string $shortcodename the shortcode found, when == callback name * @return string $output returns the modified html string */ function shortcode_handler( $atts, $content = '', $shortcodename = '', $meta = '' ) { global $avia_config, $more; extract( $atts ); $cards = []; ob_start(); //start buffering the output instead of echoing it // $img = wp_get_attachment_image( $attachment, 'large' ); echo $this->render_module(ShortcodeHelper::avia_apply_autop( ShortcodeHelper::avia_remove_autop( $module_content ) ), ShortcodeHelper::avia_apply_autop( ShortcodeHelper::avia_remove_autop( $module_body_content ) ), $image_side, $module_image, $show_pathway); $output = ob_get_clean(); avia_set_layout_array(); return $output; } function render_module($content,$body_content,$image_side,$module_image, $show_pathway) { $html = ''; $extra_classes = ''; if ($module_image) { $extra_classes = 'show-image'; } if ($show_pathway == 'yes') { $extra_classes = 'show-pathway'; } $html .= '<div class="two-column-full-width-module '.$image_side.'-side '.$extra_classes.'">'; if ($module_image) { $html .= '<div class="image-container"><div class="image-container-too"><div class="module-image" style="background:url(\''.$module_image.'\'); background-repeat: no-repeat; background-position: center '.$image_side.'; background-size: cover"></div></div></div>'; } if ($show_pathway == 'yes') { $html .= '<div class="image-container"></div>'; } $html .= '<div class="module-container"><div class="content-container"><div class="headline-content">'.$content.'</div><div class="body-content">'.$body_content.'</div></div><p class="read-more"><span class="collapsed">Read More</span><span class="expanded">Read Less</span><i class="chevron"></i></p></div>'; return $html .= '</div>'; } } }
You can see that I used the tiny_mce type twice, and have given it a custom id for each one.
In the default modules, I haven’t found any example where two tiny_mce elements were used in a single module, nor have I found any that used the tiny_mce element with an id of something other than ‘content’.
I believe it should be a fairly simple matter of adding a filter or something, but haven’t yet been able to determine what it should be.August 27, 2020 at 5:38 pm in reply to: TinyMCE showing HTML tags in custom shortcode elements. #1241279To sum it up:
We created custom shortcodes that are available in the visual builder.
This shortcode contains 1 or more tinymce modules.
The id of those modules are different, and are not the default ‘content’. For example, ‘module_content’.
The content is then stored as an attribute of the shortcode, rather than as content of the shortcode.
We can access/use the content on the front-end without issue, but if we edit the module, the html tags appear in the Visual editor.
In order to make any changes, we have to copy/paste from the Visual editor to the Text editor, and then make our updates.This has been tested on another site, so it is not a site-specific issue.
-
This reply was modified 4 years, 8 months ago by
group3solutions.
August 12, 2019 at 2:58 pm in reply to: Object doesn’t support property or method ‘includes’ – IE11 #1126808Thanks, but I’m not able to unzip the file. It throws an error, saying “Operation not permitted”.
Disregard, I got it. Thanks!-
This reply was modified 5 years, 8 months ago by
group3solutions.
August 9, 2019 at 4:19 pm in reply to: Object doesn’t support property or method ‘includes’ – IE11 missing content #1126277We’re having the same problem. Could you please provide the theme to us, too?
Thanks!
-
This reply was modified 4 years, 8 months ago by
-
AuthorPosts