Related
I'm creating a custom block inside a plugin. It's a drop down selector of categories for posts. I'm simply trying to update the query of a query loop block on the same page. However I'm not sure how to access the query of the query loop block.
I've tried the above however getting the blockId of the block doesn't seem to be possible on the front end. Does anyone know how i can reference the query loop block from a front end js file?
plugin.php
function tapacode_selector_ajax_callback() {
$nonce = $_POST['nonce'];
if ( ! wp_verify_nonce( $nonce, 'wp-tapacode-nonce' ) ) {
die ( 'Busted!' );
}
$category = intval( $_POST['category']);
$query_args = array(
'cat' => $category
);
$query = new WP_Query( $query_args );
wp_send_json( $query->posts );
wp_die();
}
add_action( 'wp_ajax_tapacode_selector', 'tapacode_selector_ajax_callback' );
add_action( 'wp_ajax_nopriv_tapacode_selector', 'tapacode_selector_ajax_callback' );
add_action( 'wp_enqueue_scripts', 'my_enqueue' );
function my_enqueue() {
wp_register_script( 'ajax-selector-script', plugins_url( '/selector.js', __FILE__ ), array( 'wp-blocks', 'wp-editor', 'wp-element', 'jquery' ), '1.0', true );
wp_enqueue_script( 'ajax-selector-script' );
// in JavaScript, object properties are accessed as ajax_object.ajax_url, ajax_object.we_value
wp_localize_script( 'ajax-selector-script', 'ajax_object',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'wp-tapacode-nonce' )
) );
}
another plugin.php file
<p <?php echo get_block_wrapper_attributes(); ?>>
<?php wp_dropdown_categories(); ?>
</p>
selector.js
document.addEventListener('DOMContentLoaded', setupCategorySelector, false);
function setupCategorySelector() {
document.getElementById('cat').onchange = function () {
// if value is category id
if (this.value !== '-1') {
if (typeof wp !== 'undefined' && wp.data) {
const blockId = document.querySelector('.wp-block-tapacode-category-selector').getAttribute('data-block-id');
const queryBlock = wp.data.select('core/block-editor').getBlock(blockId);
queryBlock.setAttributes({ categories: this.value });
queryBlock.update();
}
I am currently using the Wordpress REST API to read and write posts.
I have created a custom post type called property:
register_post_type( 'property', array(
'labels' => array(
'name' => 'Properties',
'singular_name' => 'Property',
),
'description' => '',
'show_in_rest' => true,
'public' => true,
'menu_position' => 20,
'supports' => array( 'title', 'editor')
));
add_action( 'init', 'property_cpt' );
And I have added a custom metabox called property_name so the it will appear in the edit post admin page:
function add_property_metaboxes(){
add_meta_box(
'property_name', // id
'Name', // title
'property_name_callback', // callback
'property', // page
'normal', // context
'default' // priority
);
}
function property_name_callback() {
global $post;
wp_nonce_field( basename( __FILE__ ), 'property_fields' );
$value = get_post_meta( $post->ID, 'property_name', true );
echo '<input name="property_name" type="text" value="' . $value . '" />';
}
add_action( 'add_meta_boxes', 'add_property_metaboxes' );
I am handling the save function for this post type:
function property_save_meta( $post_id, $post ) {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
if ( !isset( $_POST['property_name'] ) ||
!wp_verify_nonce( $_POST['property_fields'], basename(__FILE__) ) ) {
return $post_id;
}
$events_meta['property_name'] = esc_textarea( $_POST['property_name'] );
foreach ( $events_meta as $key => $value ) :
if ( 'revision' === $post->post_type ) {
return;
}
if ( get_post_meta( $post_id, $key, false ) ) {
update_post_meta( $post_id, $key, $value );
} else {
add_post_meta( $post_id, $key, $value);
}
if ( ! $value ) {
delete_post_meta( $post_id, $key );
}
endforeach;
}
add_action( 'save_post', 'property_save_meta', 1, 2 );
And finally I have registered property_name as a rest field:
function register_rest_fields() {
register_rest_field('property', 'property_name',
array(
'get_callback' => 'get_post_meta_cb',
'update_callback' => 'update_post_meta_cb',
'schema' => null
)
);
}
function get_post_meta_cb($object, $field_name, $request){
return get_post_meta($object['id'], $field_name, true);
}
function update_post_meta_cb($value, $object, $field_name){
if ( ! $value || ! is_string( $value ) ) {
return;
}
return update_term_meta( $object->ID, $field_name, $value );
}
add_action('rest_api_init', 'register_rest_fields');
On the front-end, I am able to fetch 'property' posts using the API and the property_name field appears correctly in the response.
I am also able to create a new post easily but I am not able to set the property_name meta field value.
Currently I am trying:
request(`${url}/wp-json/wp/v2/property`, {
method: "POST",
body:JSON.stringify({
title: 'Lorem ipsum dolor sit amet',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
status: 'publish',
meta: {
property_name: 'Testing'
}
})
});
(As pointed in my comment,) the problem is here:
function update_post_meta_cb($value, $object, $field_name){
if ( ! $value || ! is_string( $value ) ) {
return;
}
return update_term_meta( $object->ID, $field_name, $value );
}
where you're actually saving a post meta, but then used update_term_meta() which is for saving a term meta. :)
And (I forgot to say that) to fix it, just replace the update_term_meta() with update_post_meta(). ;)
I have a bug with my Custom Post Type Image Uploader i can't get my head around.
My image uploader is working perfectly fine, when i upload my images all at once, but if i need to edit a post then my issue comes. When i press the update button in Wordpress admin, all my images are deleted and only a broken image is left.
The Images is only saved if i have used the media uploader, before pressing update. So if i want to edit a post i have to uploade the images every time, and i need to fix that.
I have two files: image_uploader.php and image_upload.js.
First one image_upload.js and second image_uploader.php
var addButton = document.getElementById( 'image-upload-button');
var deleteButton = document.getElementById( 'image-delete-button');
var img = document.getElementById( 'image-tag');
var hidden = document.getElementById( 'img-hidden-field');
var customUploader = wp.media({
title: 'Choose an image',
button: {
text: "Use this Image"
},
multiple: false
});
addButton.addEventListener( 'click', function() {
if ( customUploader ){
customUploader.open();
}
} );
customUploader.on( 'select', function() {
var attachment = customUploader.state().get('selection').first().toJSON();
img.setAttribute( 'src', attachment.url );
hidden.setAttribute( 'value', JSON.stringify( [{ id: attachment.id, url: attachment.url }]) );
toggleVisibility( 'ADD' );
} );
deleteButton.addEventListener( 'click', function(){
img.removeAttribute( 'src' );
hidden.removeAttribute( 'value' );
toggleVisibility( 'DELETE' );
});
var toggleVisibility = function( action ) {
if ( 'ADD' === action ) {
addButton.style.display = 'none';
deleteButton.style.display = '';
img.setAttribute( 'style', 'width: 100%;' );
}
if ( 'DELETE' === action ) {
addButton.style.display = '';
deleteButton.style.display = 'none';
img.removeAttribute('style');
}
};
window.addEventListener( 'DOMContentLoaded', function() {
if ( "" === customUploads.imageData || 0 === customUploads.imageData.length ) {
toggleVisibility( 'DELETE' );
} else {
img.setAttribute( 'src', customUploads.imageData.src );
hidden.setAttribute( 'value', JSON.stringify([ customUploads.imageData ]) );
toggleVisibility( 'ADD' );
}
} );
// Second Image
var addButton2 = document.getElementById( 'image-upload-button2');
var deleteButton2 = document.getElementById( 'image-delete-button2');
var img2 = document.getElementById( 'image-tag2');
var hidden2 = document.getElementById( 'img-hidden-field2');
var customUploader2 = wp.media({
title: 'Choose an image',
button: {
text: "Use this Image"
},
multiple: false
});
addButton2.addEventListener( 'click', function() {
if ( customUploader2 ){
customUploader2.open();
}
} );
customUploader2.on( 'select', function() {
var attachment2 = customUploader2.state().get('selection').first().toJSON();
img2.setAttribute( 'src', attachment2.url );
hidden2.setAttribute( 'value', JSON.stringify( [{ id: attachment2.id, url: attachment2.url }]) );
toggleVisibility2( 'ADD2' );
} );
deleteButton2.addEventListener( 'click', function(){
img2.removeAttribute( 'src' );
hidden2.removeAttribute( 'value' );
toggleVisibility2( 'DELETE2' );
});
var toggleVisibility2 = function( action ) {
if ( 'ADD2' === action ) {
addButton2.style.display = 'none';
deleteButton2.style.display = '';
img2.setAttribute( 'style', 'width: 100%;' );
}
if ( 'DELETE2' === action ) {
addButton2.style.display = '';
deleteButton2.style.display = 'none';
img2.removeAttribute('style');
}
};
window.addEventListener( 'DOMContentLoaded', function() {
if ( "" === customUploads2.imageData2 || 0 === customUploads2.imageData2.length ) {
toggleVisibility2( 'DELETE2' );
} else {
img2.setAttribute( 'src', customUploads2.imageData2.src );
hidden2.setAttribute( 'value', JSON.stringify([ customUploads2.imageData2 ]) );
toggleVisibility2( 'ADD2' );
}
} );
<?php
// Meta box 1
function register_metaboxes() {
add_meta_box('image_metabox', 'Billeder','image_uploader_callback');
}
add_action( 'add_meta_boxes','register_metaboxes' );
// Meta box 2
function register_metaboxes2() {
add_meta_box('image2_metabox', 'Billeder2','image2_uploader_callback');
}
add_action( 'add_meta_boxes','register_metaboxes2' );
function register_admin_script() {
wp_enqueue_script( 'wp_img_upload', 'image-upload.js', array('jquery', 'media-upload'), true );
wp_localize_script( 'wp_img_upload', 'customUploads', array( 'imageData' => get_post_meta( get_the_ID(), 'custom_image_data', true ) ) );
wp_localize_script( 'wp_img_upload', 'customUploads2', array( 'imageData2' => get_post_meta( get_the_ID(), 'custom_image2_data', true ) ) );
add_action( 'admin_enqueue_scripts', 'register_admin_script' );
function image_uploader_callback( $post_id ) {
wp_nonce_field( basename( __FILE__ ), 'custom_image_nonce' ); ?>
<div id="metabox_wrapper">
<img id="image-tag">
<input type="hidden" id="img-hidden-field" name="custom_image_data">
<input type="button" id="image-upload-button" class="button" value="Add Image">
<input type="button" id="image-delete-button" class="button" value="Delete Image">
</div>
<?php
}
function image2_uploader_callback( $post_id ) {
wp_nonce_field( basename( __FILE__ ), 'custom_image2_nonce' ); ?>
<label>Andet billede</label>
<div id="metabox_wrapper2">
<img id="image-tag2">
<input type="hidden" id="img-hidden-field2" name="custom_image2_data">
<input type="button" id="image-upload-button2" class="button" value="Add Image">
<input type="button" id="image-delete-button2" class="button" value="Delete Image">
</div>
<?php
}
function save_custom_image( $post_id ) {
$is_autosave = wp_is_post_autosave( $post_id );
$is_revision = wp_is_post_revision( $post_id );
$is_valid_nonce = ( isset( $_POST[ 'custom_image_nonce' ] ) && wp_verify_nonce( $_POST[ 'custom_image_nonce' ], basename( __FILE__ ) ) );
$image_data = ['id','src'];
// Exits script depending on save status
if ( $is_autosave || $is_revision || !$is_valid_nonce ) {
return;
}
if ( isset( $_POST[ 'custom_image_data' ] ) ) {
$image_data = json_decode( stripslashes( $_POST[ 'custom_image_data' ] ) );
if ( is_object( $image_data[0] ) ) {
$image_data = array( 'id' => intval( $image_data[0]->id ), 'src' => esc_url_raw( $image_data[0]->url
) );
}
update_post_meta( $post_id, 'custom_image_data', $image_data );
}
}
add_action( 'save_post', 'save_custom_image' );
// Image 2
function save_custom_image2( $post_id ){
$is_autosave2 = wp_is_post_autosave( $post_id );
$is_revision2 = wp_is_post_revision( $post_id );
$is_valid_nonce2 = ( isset( $_POST[ 'custom_image2_nonce' ] ) && wp_verify_nonce( $_POST[ 'custom_image2_nonce' ], basename( __FILE__ ) ) );
// Exits script depending on save status
if ( $is_autosave2 || $is_revision2 || !$is_valid_nonce2 ) {
return;
}
if ( isset( $_POST[ 'custom_image2_data' ] ) ) {
$image_data2 = json_decode( stripslashes( $_POST[ 'custom_image2_data' ] ) );
if ( is_object( $image_data2[0] ) ) {
$image_data2 = array( 'id' => intval( $image_data2[0]->id ), 'src' => esc_url_raw( $image_data2[0]->url
) );
} else {
$image_data2 = [];
}
update_post_meta( $post_id, 'custom_image2_data', $image_data2 );
}
}
add_action( 'save_post', 'save_custom_image2' );
I am not sure what do you try to accomplish there and it's quite hard to debug your code without setting up new installation, but I think there is better way to do that.
Wordpress have very useful extension called ACF https://www.advancedcustomfields.com/ which gives you possibility to add custom meta fields to one or multiple post types. I highly recommend it, even free version is enough for most of the cases.
Outline-
I am running a Wordpress v4 installation and have installed a chatroom plugin: https://github.com/wp-plugins/chat-room (full code below).
I want to be able to highlight specific words that appear in chat when a user posts a message. For example, every time a user posts a message with the word "Dog" in it, it would have background colour so that it can be highlighted to everyone.
As the HTML output from the plugin is plain HTML, the best solution I have found is the following working example: https://jsfiddle.net/4ny8adpg/2/.
The Problem-
When using the script from the jsfiddle above on the page where the chatroom is placed, it seems that the script either cannot find the words or cannot replace them. I do not understand why, as the HTML that is output from the chatroom scripts is plain HTML (exactly as shown in the jsfiddle). It's also worth noting that the script will find and replace words that are written into the HTML source on the same page.
The Code-
Below is the PHP, Javascript and example HTML output for the chat-room plugin. I did not write this plugin and the original author offers very very limited support.
PHP:
Class Chatroom {
function __construct() {
register_activation_hook( __FILE__, array( $this, 'activation_hook' ) );
register_deactivation_hook( __FILE__, array( $this, 'deactivation_hook' ) );
add_action( 'init', array( $this, 'register_post_types' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
add_action( 'save_post', array( $this, 'maybe_create_chatroom_log_file' ), 10, 2 );
add_action( 'wp_head', array( $this, 'define_javascript_variables' ) );
add_action( 'wp_ajax_check_updates', array( $this, 'ajax_check_updates_handler' ) );
add_action( 'wp_ajax_send_message', array( $this, 'ajax_send_message_handler' ) );
add_filter( 'the_content', array( $this, 'the_content_filter' ) );
}
function activation_hook() {
$this->register_post_types();
flush_rewrite_rules();
}
function deactivation_hook() {
flush_rewrite_rules();
}
function register_post_types() {
$labels = array(
'name' => _x( 'Chat Rooms', 'post type general name', 'chatroom' ),
'singular_name' => _x( 'Chat Room', 'post type singular name', 'chatroom' ),
'add_new' => _x( 'Add New', 'book', 'chatroom' ),
'add_new_item' => __( 'Add New Chat Room', 'chatroom' ),
'edit_item' => __( 'Edit Chat Room', 'chatroom' ),
'new_item' => __( 'New Chat Room', 'chatroom' ),
'all_items' => __( 'All Chat Rooms', 'chatroom' ),
'view_item' => __( 'View Chat Room', 'chatroom' ),
'search_items' => __( 'Search Chat Rooms', 'chatroom' ),
'not_found' => __( 'No Chat Rooms found', 'chatroom' ),
'not_found_in_trash' => __( 'No Chat Rooms found in Trash', 'chatroom' ),
'parent_item_colon' => '',
'menu_name' => __( 'Chat Rooms', 'chatroom' )
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => null,
'show_in_nav_menus' => true,
'supports' => array( 'title' )
);
register_post_type( 'chat-room', $args );
}
function enqueue_scripts() {
global $post;
if ( $post->post_type != 'chat-room' )
return;
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'chat-room', plugins_url( 'chat-room.js', __FILE__ ) );
wp_enqueue_style( 'chat-room-styles', plugins_url( 'chat-room.css', __FILE__ ) );
}
function maybe_create_chatroom_log_file( $post_id, $post ) {
if ( empty( $post->post_type ) || $post->post_type != 'chat-room' )
return;
$upload_dir = wp_upload_dir();
$log_filename = $upload_dir['basedir'] . '/chatter/' . $post->post_name . '-' . date( 'm-d-y', time() );
if ( file_exists( $log_filename ) )
return;
wp_mkdir_p( $upload_dir['basedir'] . '/chatter/' );
$handle = fopen( $log_filename, 'w' );
fwrite( $handle, json_encode( array() ) );
// TODO create warnings if the user can't create a file, and suggest putting FTP creds in wp-config
}
function define_javascript_variables() {
global $post;
if ( empty( $post->post_type ) || $post->post_type != 'chat-room' )
return; ?>
<script>
var ajaxurl = '<?php echo admin_url( 'admin-ajax.php' ); ?>';
var chatroom_slug = '<?echo $post->post_name; ?>';
</script>
<?php
}
function ajax_check_updates_handler() {
$upload_dir = wp_upload_dir();
$log_filename = $this->get_log_filename( $_POST['chatroom_slug'] );
$contents = $this->parse_messages_log_file( $log_filename );
$messages = json_decode( $contents );
foreach ( $messages as $key => $message ) {
if ( $message->id <= $_POST['last_update_id'] )
unset( $messages[$key] );
}
$messages = array_values( $messages );
echo json_encode( $messages );
die;
}
/**
* AJAX server-side handler for sending a message.
*
* Stores the message in a recent messages file.
*
* Clears out cache of any messages older than 10 seconds.
*/
function ajax_send_message_handler() {
$current_user = wp_get_current_user();
$this->save_message( $_POST['chatroom_slug'], $current_user->id, $_POST['message'] );
die;
}
function save_message( $chatroom_slug, $user_id, $content ) {
$user = get_userdata( $user_id );
if ( ! $user_text_color = get_user_meta( $user_id, 'user_color', true ) ) {
// Set random color for each user
$red = rand( 0, 16 );
$green = 16 - $red;
$blue = rand( 0, 16 );
$user_text_color = '#' . dechex( $red^2 ) . dechex( $green^2 ) . dechex( $blue^2 );
update_user_meta( $user_id, 'user_color', $user_text_color );
}
$content = esc_attr( $content );
// Save the message in recent messages file
$log_filename = $this->get_log_filename( $chatroom_slug );
$contents = $this->parse_messages_log_file( $log_filename );
$messages = json_decode( $contents );
$last_message_id = 0; // Helps determine the new message's ID
foreach ( $messages as $key => $message ) {
if ( time() - $message->time > 10 ) {
$last_message_id = $message->id;
unset( $messages[$key] );
}
else {
break;
}
}
$messages = array_values( $messages );
if ( ! empty( $messages ) )
$last_message_id = end( $messages )->id;
$new_message_id = $last_message_id + 1;
$messages[] = array(
'id' => $new_message_id,
'time' => time(),
'sender' => $user_id,
'contents' => $content,
'html' => '<div class="chat-message-' . $new_message_id . '"><strong style="color: ' . $user_text_color . ';">' . $user->user_login . '</strong>: ' . $content . '</div>',
);
$this->write_log_file( $log_filename, json_encode( $messages ) );
// Save the message in the daily log
$log_filename = $this->get_log_filename( $chatroom_slug, date( 'm-d-y', time() ) );
$contents = $this->parse_messages_log_file( $log_filename );
$messages = json_decode( $contents );
$messages[] = array(
'id' => $new_message_id,
'time' => time(),
'sender' => $user_id,
'contents' => $content,
'html' => '<div class="chat-message-' . $new_message_id .'"><strong style="color: ' . $user_text_color . ';">' . $user->user_login . '</strong>: ' . $content . '</div>',
);
$this->write_log_file( $log_filename, json_encode( $messages ) );
}
function write_log_file( $log_filename, $content ) {
$handle = fopen( $log_filename, 'w' );
fwrite( $handle, $content );
}
function get_log_filename( $chatroom_slug, $date = 'recent' ) {
$upload_dir = wp_upload_dir();
$log_filename = $upload_dir['basedir'] . '/chatter/' . $chatroom_slug . '-' . $date;
return $log_filename;
}
function parse_messages_log_file( $log_filename ) {
$upload_dir = wp_upload_dir();
$handle = fopen( $log_filename, 'r' );
$contents = fread( $handle, filesize( $log_filename ) );
fclose( $handle );
return $contents;
}
function the_content_filter( $content ) {
global $post;
if ( $post->post_type != 'chat-room' )
return $content;
if ( ! is_user_logged_in() ) {
?>You need to be logged in to participate in the chatroom.<?php
return;
}
?>
<div class="chat-container">
</div>
<textarea class="chat-text-entry"></textarea>
<?php
return '';
}
}
$chatroom = new Chatroom();
Javascript:
var last_update_received = 0;
function chatroom_check_updates() {
jQuery.post(
ajaxurl,
{
action: 'check_updates',
chatroom_slug: chatroom_slug,
last_update_id: last_update_id
},
function (response) {
chats = jQuery.parseJSON( response );
if ( chats !== null ) {
for ( i = 0; i < chats.length; i++ ) {
if ( jQuery('div.chat-container div.chat-message-'+chats[i].id).length )
continue;
jQuery('div.chat-container').html( jQuery('div.chat-container').html() + chatroom_strip_slashes(chats[i].html) );
last_update_id = chats[i].id;
jQuery('div.chat-container').animate({ scrollTop: jQuery('div.chat-container')[0].scrollHeight - jQuery('div.chat-container').height() }, 100);
}
}
}
);
setTimeout( "chatroom_check_updates()", 1000 );
}
function chatroom_strip_slashes(str) {
return (str + '').replace(/\\(.?)/g, function (s, n1) {
switch (n1) {
case '\\':
return '\\';
case '0':
return '\u0000';
case '':
return '';
default:
return n1;
}
});
}
jQuery(document).ready( function() {
last_update_id = 0;
chatroom_check_updates();
jQuery( 'textarea.chat-text-entry' ).keypress( function( event ) {
if ( event.charCode == 13 || event.keyCode == 13 ) {
chatroom_send_message();
return false;
}
});
});
function chatroom_send_message() {
message = jQuery( 'textarea.chat-text-entry' ).val();
jQuery( 'textarea.chat-text-entry' ).val('');
jQuery.post(
ajaxurl,
{
action: 'send_message',
chatroom_slug: chatroom_slug,
message: message
},
function (response) {
}
);
}
HTML Output:
<div class="chat-container">
<div class="chat chat-message-111"><strong style="color: #840;">User 1</strong>: What is your favourite animal?</div>
<div class="chat chat-message-112"><strong style="color: #840;">User 2</strong>: I vote for #dog. </div>
<div class="chat chat-message-113"><strong style="color: #840;">User 3</strong>: I have a #cat!</div>
</div>
My question really is, am I missing something obvious? Any help towards a solution will be greatly appreciated!
EDIT: To provide better explanation.
EDIT 2: Added script output as requested
Var. Chats in chatroom_check_updates() Output:
[{"id":129,"time":1428340673,"sender":1,"contents":"What is your favourite animal?","html":"<div class=\"chat chat-message-129\"><strong style=\"color: #840;\">User 1<\/strong>: What is your favourite animal?<\/div>"},
{"id":130,"time":1428351683,"sender":2,"contents":"I vote for #dog.","html":"<div class=\"chat chat-message-130\"><strong style=\"color: #840;\">User 2<\/strong>: I vote for #dog.<\/div>"},
{"id":131,"time":1428352376,"sender":3,"contents":"I have a #cat!","html":"<div class=\"chat chat-message-131\"><strong style=\"color: #840;\">User 3<\/strong>: I have a #cat!<\/div>"}]
So this is a question following on from the awesome work #Drakes has done on this question previously: Highlighting words with Javascript, what am I missing?.
The solution is to highlight words by finding "#cat" or "#dog" and replacing them with
<span class='cat'>#CAT</span>
or
<span class='dog'>#DOG</span>
Then we can control the background colour of the span tag with CSS.
This works perfectly, however the background colour only remains for a brief moment before disappearing. Upon a closer look, it seems the span tags are applied correctly and then removed again suddenly.
Here is the actual working example for you to have a look at, plus log in details to run any tests and to view the chat.
[Removed, no longer exists]
Below is the updated code from the previous question that is currently running on the working example.
Once again, any further help is hugely appreciated. Please let me know if you require any additional information!
Javascript:
// NOTE: I needed to define these variables to make the demo work
var ajaxurl = "http://ip.jsontest.com/";
var chatroom_slug = "1";
var last_update_id = "1";
var last_update_received = 0;
function chatroom_check_updates() {
jQuery.post(
ajaxurl,
{
action: 'check_updates',
chatroom_slug: chatroom_slug,
last_update_id: last_update_id
},
function (response) {
// NOTE: the response is bad, an exception will be thrown, not NULL
chats = null;
try {
chats = jQuery.parseJSON( response );
} catch(e) {}
// NOTE: In this test, I don't know your URL, so I just commented out the bit below
if (1 || chats !== null ) {
for ( i = 0; i < chats.length; i++ ) {
if ( jQuery('div.chat-container div.chat-message-'+chats[i].id).length )
continue;
jQuery('div.chat-container').html( jQuery('div.chat-container').html() + chatroom_strip_slashes(chats[i].html) );
last_update_id = chats[i].id;
jQuery('div.chat-container').animate({ scrollTop: jQuery('div.chat-container')[0].scrollHeight - jQuery('div.chat-container').height() }, 100);
}
jQuery('.chat').each(function(){
var hashtag = jQuery(this).text()
.replace(/#dog/g, "<span class='dog'>#DOG</span>")
.replace(/#cat/g, "<span class='cat'>#CAT</span>");
jQuery(this).html(hashtag);
});
}
}
)
.error(function(xhr, status, error){
alert(xhr.responseText);
});
// I commented this out just for testing.
setTimeout( chatroom_check_updates, 1000 );
}
function chatroom_strip_slashes(str) {
return (str + '').replace(/\\(.?)/g, function (s, n1) {
switch (n1) {
case '\\':
return '\\';
case '0':
return '\u0000';
case '':
return '';
default:
return n1;
}
});
}
jQuery(document).ready( function() {
last_update_id = 0;
chatroom_check_updates();
jQuery( 'textarea.chat-text-entry' ).keypress( function( event ) {
if ( event.charCode == 13 || event.keyCode == 13 ) {
chatroom_send_message();
return false;
}
});
});
function chatroom_send_message() {
message = jQuery( 'textarea.chat-text-entry' ).val();
jQuery( 'textarea.chat-text-entry' ).val('');
jQuery.post(
ajaxurl,
{
action: 'send_message',
chatroom_slug: chatroom_slug,
message: message
},
function (response) {
}
);
}
PHP:
<?php
/*
Plugin Name: Chat Room
Plugin URI: http://webdevstudios.com/support/wordpress-plugins/
Description: Chat Room for WordPress
Author: WebDevStudios.com
Version: 0.1.2
Author URI: http://webdevstudios.com/
License: GPLv2 or later
*/
Class Chatroom {
function __construct() {
register_activation_hook( __FILE__, array( $this, 'activation_hook' ) );
register_deactivation_hook( __FILE__, array( $this, 'deactivation_hook' ) );
add_action( 'init', array( $this, 'register_post_types' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
add_action( 'save_post', array( $this, 'maybe_create_chatroom_log_file' ), 10, 2 );
add_action( 'wp_head', array( $this, 'define_javascript_variables' ) );
add_action( 'wp_ajax_check_updates', array( $this, 'ajax_check_updates_handler' ) );
add_action( 'wp_ajax_send_message', array( $this, 'ajax_send_message_handler' ) );
add_filter( 'the_content', array( $this, 'the_content_filter' ) );
}
function activation_hook() {
$this->register_post_types();
flush_rewrite_rules();
}
function deactivation_hook() {
flush_rewrite_rules();
}
function register_post_types() {
$labels = array(
'name' => _x( 'Chat Rooms', 'post type general name', 'chatroom' ),
'singular_name' => _x( 'Chat Room', 'post type singular name', 'chatroom' ),
'add_new' => _x( 'Add New', 'book', 'chatroom' ),
'add_new_item' => __( 'Add New Chat Room', 'chatroom' ),
'edit_item' => __( 'Edit Chat Room', 'chatroom' ),
'new_item' => __( 'New Chat Room', 'chatroom' ),
'all_items' => __( 'All Chat Rooms', 'chatroom' ),
'view_item' => __( 'View Chat Room', 'chatroom' ),
'search_items' => __( 'Search Chat Rooms', 'chatroom' ),
'not_found' => __( 'No Chat Rooms found', 'chatroom' ),
'not_found_in_trash' => __( 'No Chat Rooms found in Trash', 'chatroom' ),
'parent_item_colon' => '',
'menu_name' => __( 'Chat Rooms', 'chatroom' )
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => null,
'show_in_nav_menus' => true,
'supports' => array( 'title' )
);
register_post_type( 'chat-room', $args );
}
function enqueue_scripts() {
global $post;
if ( $post->post_type != 'chat-room' )
return;
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'chat-room', plugins_url( 'chat-room.js', __FILE__ ) );
wp_enqueue_style( 'chat-room-styles', plugins_url( 'chat-room.css', __FILE__ ) );
}
function maybe_create_chatroom_log_file( $post_id, $post ) {
if ( empty( $post->post_type ) || $post->post_type != 'chat-room' )
return;
$upload_dir = wp_upload_dir();
$log_filename = $upload_dir['basedir'] . '/chatter/' . $post->post_name . '-' . date( 'm-d-y', time() );
if ( file_exists( $log_filename ) )
return;
wp_mkdir_p( $upload_dir['basedir'] . '/chatter/' );
$handle = fopen( $log_filename, 'w' );
fwrite( $handle, json_encode( array() ) );
// TODO create warnings if the user can't create a file, and suggest putting FTP creds in wp-config
}
function define_javascript_variables() {
global $post;
if ( empty( $post->post_type ) || $post->post_type != 'chat-room' )
return; ?>
<script>
var ajaxurl = '<?php echo admin_url( 'admin-ajax.php' ); ?>';
var chatroom_slug = '<?echo $post->post_name; ?>';
</script>
<?php
}
function ajax_check_updates_handler() {
$upload_dir = wp_upload_dir();
$log_filename = $this->get_log_filename( $_POST['chatroom_slug'] );
$contents = $this->parse_messages_log_file( $log_filename );
$messages = json_decode( $contents );
foreach ( $messages as $key => $message ) {
if ( $message->id <= $_POST['last_update_id'] )
unset( $messages[$key] );
}
$messages = array_values( $messages );
echo json_encode( $messages );
die;
}
/**
* AJAX server-side handler for sending a message.
*
* Stores the message in a recent messages file.
*
* Clears out cache of any messages older than 10 seconds.
*/
function ajax_send_message_handler() {
$current_user = wp_get_current_user();
$this->save_message( $_POST['chatroom_slug'], $current_user->id, $_POST['message'] );
die;
}
function save_message( $chatroom_slug, $user_id, $content ) {
$user = get_userdata( $user_id );
if ( ! $user_text_color = get_user_meta( $user_id, 'user_color', true ) ) {
// Set random color for each user
$red = rand( 0, 16 );
$green = 16 - $red;
$blue = rand( 0, 16 );
$user_text_color = '#' . dechex( $red^2 ) . dechex( $green^2 ) . dechex( $blue^2 );
update_user_meta( $user_id, 'user_color', $user_text_color );
}
$content = esc_attr( $content );
// Save the message in recent messages file
$log_filename = $this->get_log_filename( $chatroom_slug );
$contents = $this->parse_messages_log_file( $log_filename );
$messages = json_decode( $contents );
$last_message_id = 0; // Helps determine the new message's ID
foreach ( $messages as $key => $message ) {
if ( time() - $message->time > 100 ) {
$last_message_id = $message->id;
unset( $messages[$key] );
}
else {
break;
}
}
$messages = array_values( $messages );
if ( ! empty( $messages ) )
$last_message_id = end( $messages )->id;
$new_message_id = $last_message_id + 1;
$messages[] = array(
'id' => $new_message_id,
'time' => time(),
'sender' => $user_id,
'contents' => $content,
'html' => '<div class="chat chat-message-' . $new_message_id . '"><strong style="color: ' . $user_text_color . ';">' . $user->user_login . '</strong>: ' . $content . '</div>',
);
$this->write_log_file( $log_filename, json_encode( $messages ) );
// Save the message in the daily log
$log_filename = $this->get_log_filename( $chatroom_slug, date( 'm-d-y', time() ) );
$contents = $this->parse_messages_log_file( $log_filename );
$messages = json_decode( $contents );
$messages[] = array(
'id' => $new_message_id,
'time' => time(),
'sender' => $user_id,
'contents' => $content,
'html' => '<div class="chat chat-message-' . $new_message_id .'"><strong style="color: ' . $user_text_color . ';">' . $user->user_login . '</strong>: ' . $content . '</div>',
);
$this->write_log_file( $log_filename, json_encode( $messages ) );
}
function write_log_file( $log_filename, $content ) {
$handle = fopen( $log_filename, 'w' );
fwrite( $handle, $content );
}
function get_log_filename( $chatroom_slug, $date = 'recent' ) {
$upload_dir = wp_upload_dir();
$log_filename = $upload_dir['basedir'] . '/chatter/' . $chatroom_slug . '-' . $date;
return $log_filename;
}
function parse_messages_log_file( $log_filename ) {
$upload_dir = wp_upload_dir();
$handle = fopen( $log_filename, 'r' );
$contents = fread( $handle, filesize( $log_filename ) );
fclose( $handle );
return $contents;
}
function the_content_filter( $content ) {
global $post;
if ( $post->post_type != 'chat-room' )
return $content;
if ( ! is_user_logged_in() ) {
?>You need to be logged in to participate in the chatroom.<?php
return;
}
?>
<div class="chat-container">
</div>
<textarea class="chat-text-entry"></textarea>
<?php
return '';
}
}
$chatroom = new Chatroom();
Example HTML output:
<div class="chat-container">
<div class="chat chat-message-111"><strong style="color: #840;">User 1</strong>: What is your favourite animal?</div>
<div class="chat chat-message-112"><strong style="color: #840;">User 2</strong>: I vote for #dog. </div>
<div class="chat chat-message-113"><strong style="color: #840;">User 3</strong>: I have a #cat!</div>
</div>
Because you are replacing all the text even if there is not a match. So .text() strips the HTML and than it does not find dog or cat and just puts the text in.
var hashtag = jQuery(this).text()
.replace(/#dog/g, "<span class='dog'>#DOG</span>")
.replace(/#cat/g, "<span class='cat'>#CAT</span>");
jQuery(this).html(hashtag);
since you replace #dog with #DOG it will not match since the search is not case insensitive
either make it case insensitive
/#dog/gi
or only replace the text if there is a change made.
var orgText = jQuery(this).text();
var hashtag = orgText
.replace(/#dog/g, "<span class='dog'>#DOG</span>")
.replace(/#cat/g, "<span class='cat'>#CAT</span>");
if(orgText!==hashtag) {
jQuery(this).html(hashtag);
}
Note: the way you have it currently written, you are going to blow away the User formatting since you are reading the text.