I'm just getting into plugin development in Wordpress. Right now I have a function that a I pass as a filter to the 'tiny_mce_before_init' with specific variables to change the buttons, add custom styling and other similar things.
I'm in the process of building a an Options Page which I would like to control the variables passed to the tinyMCE function, that way the user can select which buttons to display as well as add a custom stylesheet to the editor.
At this point, my function to edit the tiny mce works great! and the options page is also saving data, checkboxes and everything else I need.
My only issue is I'm not understanding how to pass the variables stored in the "options.php" to the current tinyMCE function. This is the current function in my functions.php file:
function my_format_TinyMCE( $in ) {
//styles for the editor to provide better visual representation.
$in['content_css'] = get_template_directory_uri() . "/build/styles/tiny-mce-editor.css";
$in['block_formats'] = "Paragraph=p; Heading 1=h1; Heading 2=h2";
$in['toolbar1'] = 'formatselect,bold,italic,underline,superscript,bullist,numlist,alignleft,aligncenter,alignright,link,unlink,spellchecker';
$in['toolbar2'] = '';
$in['toolbar3'] = '';
$in['toolbar4'] = '';
return $in;
}
add_filter( 'tiny_mce_before_init', 'my_format_TinyMCE' );
I don't want to convolute the post by adding all the code of my Options Page, but I might need some direction on how to approach on passing variables as the value of the $in[]. As mentioned before, the variables would be created in an Options Page and saved, updating the tiny mce function.
I've researched a lot and I can't find any direct information on this -- as usual, I'm not looking for somebody to do my code but maybe to push me in the right direction.
Thanks!
EDIT NEW CODE
add_action('admin_menu', 'my_cool_plugin_create_menu');
function my_cool_plugin_create_menu() {
add_menu_page('My Cool Plugin Settings', 'Cool Settings', 'administrator', __FILE__, 'my_cool_plugin_settings_page' , plugins_url('/images/icon.png', __FILE__) );
add_action( 'admin_init', 'register_my_cool_plugin_settings' );
}
function register_my_cool_plugin_settings() {
//register our settings
register_setting( 'my-cool-plugin-settings-group', 'new_option_name' );
}
function my_cool_plugin_settings_page() {
?>
<div class="wrap">
<h2>Your Plugin Name</h2>
<form method="post" action="options.php">
<?php settings_fields( 'my-cool-plugin-settings-group' ); ?>
<?php do_settings_sections( 'my-cool-plugin-settings-group' ); ?>
<table class="form-table">
<tr valign="top">
<th scope="row">New Option Name</th>
<td><input type="text" name="new_option_name" value="<?php echo esc_attr( get_option('new_option_name') ); ?>" /></td>
</tr>
<?php submit_button(); ?>
</form>
</div>
<?php }
function my_format_TinyMCE( $in ) {
$toolbar = get_option('new_option_name');
//styles for the editor to provide better visual representation.
$in['content_css'] = get_template_directory_uri() . "/build/styles/tiny-mce-editor.css";
$in['block_formats'] = "Paragraph=p; Heading 1=h1; Heading 2=h2";
$in['toolbar1'] = $toolbar;
$in['toolbar2'] = '';
$in['toolbar3'] = '';
$in['toolbar4'] = '';
return $in;
}
add_filter( 'tiny_mce_before_init', 'my_format_TinyMCE' );
?>
I'm still having difficulty accessing the stored variables and using them in the function. Any ideas?
On your options page, you can save options with update_option. Then, in your my_format_TinyMCE function, you can access them with get_option.
Related
I'm working on my first custom WP plugin and I'm trying to register a setting using the Settings API. I've followed a number of guides, and I've successfully created an admin menu page with the section and field defined in the plugin, but the single setting (in the code its fbm_lockout_updates) will not save, and no table in the database has been created for it.
EDIT: It is in fact in the options table. I was mistaken about that much. However, my options page still cant seem to update it, so I suppose my callback function is bad?
After trying a dozen things, I'm not sure where I'm going wrong. Here is the relevant code edited for brevity:
/* Create Menu */
add_action( 'admin_menu', 'fbm_config_menu' );
function fbm_config_menu() {
$page_title = 'Sample Plugin';
$menu_title = 'Sample Plugin Config';
$capability = 'manage_options';
$menu_slug = 'fbm_config';
$function = 'fbm_config_page';
add_menu_page(
$page_title,
$menu_title,
$capability,
$menu_slug,
$function
);
}
/* Register Settings and Fields */
function fbm_register_settings() {
register_setting( 'fbm_config', 'fbm_lockout_updates');
add_settings_section(
'fbm_restriction_section',
'Development Restrictions',
'fbm_restriction_callback',
'fbm_config'
);
add_settings_field(
'fbm_lockout_updates_field',
'Lockout Updates',
'fbm_lockout_field_callback',
'fbm_config',
'fbm_restriction_section'
);
}
add_action( 'admin_init', 'fbm_register_settings' );
/* Settings Callbacks */
function fbm_restriction_callback() {
?>
<p><?php esc_html_e( 'Description of Setting Section', 'fbm_config' ); ?></p>
<?php
}
function fbm_lockout_field_callback() {
$setting = get_option('fbm_lockout_updates');
?>
<input type="checkbox" name="fbm_lockout_updates" value="0" <?php checked('1', $setting); ?> >
<?php
}
/* Load Admin Page */
function fbm_config_page(){
if ( isset( $_GET['settings-updated'] ) ) {
add_settings_error( 'fbm_con_messages', 'fbm_con_message', __( 'Settings Saved', 'fbm_config' ), 'updated' );
}
settings_errors( 'fbm_con_messages' );
?>
<div class="wrap">
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
<form method="post" action="options.php">
<?php
settings_fields( 'fbm_config' );
do_settings_sections( 'fbm_config' );
submit_button( 'Save Settings' );
?>
</form>
<div>
<?php }
?>
In this case register_setting will save your data in wp-options table, take a look into it.
Recommended if you want your setting to be shown in the wordpress api use both admin and api hook
add_action( 'rest_api_init', 'bm_register_settings' );
add_action( 'admin_init', 'fbm_register_settings' );
I created a WordPress Plugin, with a hook to create links below the overview of posts in the backend(for a custom post type).
The link should redirect to a custom PHP-File. Which is currently solved like this (for Terminierungsverwaltung):
class CustomPlugin
{
function __construct(){
#... more code
/**
* Terminverwaltung
*/
add_filter( 'post_row_actions', array( $this,'termin_add_user_action_button'), 10, 2 );
#... more code
}
#... more code
function termin_add_user_action_button($actions, $post){
global $wpdb;
$post_id = $post->ID; //post ID
$poll_id; //poll ID
$wordpress_polls = $wpdb->get_results("SELECT wordpress_id, poll_id FROM " . self::WORDPRESS_TABLE_NAME . " WHERE wordpress_id = " . $post_id);
$wordpress_polls_rows = $wpdb->num_rows;
foreach($wordpress_polls as $wordpress_poll){
$poll_id = $wordpress_poll->poll_id;
}
if($wordpress_polls_rows === NULL || $wordpress_polls_rows === 0){
return $actions;
} else{
if(get_post_type() === 'workshop'){
$url = add_query_arg(
array(
'post_id' => $post->ID,
'poll_id' => $poll_id,
),
plugins_url( '/attendees.php', __FILE__ )
);
$actions['termin_add_user'] = 'Teilnehmerverwaltung';
}
return $actions;
}
}
#... more code
}
So currently I am pointing directly to the source file attendees.php (which is located inside the plugin directory) and it is not protected.
My aim is to protect the attendees.php with:
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
Obviously, I will need to hook the file somehow to the plugin or WordPress, so ABSPATH is defined. But I am not sure how to do it. Does anyone know how to get this done?
I am new to PHP and WordPress, so sorry if this is a newbie question.
Thanks in advance!
THE-E
In case the attendees.php is of importance, it has currently this structure, and should be displayed independently:
<?php
// if ( ! defined( 'ABSPATH' ) ) {
// exit; // Exit if accessed directly.
// }
require '../../../wp-load.php';
require 'src/attendees_function.php';
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel = "stylesheet"
type = "text/css"
href = "style/attendeesStyle.css" />
<title>Teilnehmerverwaltung: <?php echo get_the_title($_REQUEST['post_id']);?></title>
</head>
<body>
<?php add_user_form(); ?>
<?php delete_attendee(); ?>
<?php upload(); ?>
<H1>Teilnehmerverwaltung</H1>
<H2><?php echo get_the_title($_REQUEST['post_id']);?></H2>
<section>
<div id="add-users-upload">
<form method="POST" enctype="multipart/form-data" id="csv-form">
<input type="file" name="teilnehmer-csv" accept=".csv"><br>
<button type="submit" name="csv-upload" id="top-buttons">Teilnehmer CSV hochladen</button>
</form>
<form method="post">
<label for="kuerzel">Kürzel:</label>
<input type="hidden" name="poll-id" value="<?php $poll_id = $_REQUEST['poll_id']; echo $poll_id; ?>"/>
<input type="hidden" name="table" value="<?php $table = "oc_polls_share"; echo $table; ?>"/>
<input type="text" class="form-control" id="input-kuerzel" name="kuerzel"><br>
<button type="submit" name="add-user-form" id="top-buttons">Teilnehmer anlegen</button>
</form>
</div>
</section>
<div id="table-div">
<table>
</thead>
<tr>
<td id="index">#</td>
<td id="index">Status</td>
<td id="header">Kürzel</td>
<td id="header">E-Mail</td>
<td id="header">Vorname</td>
<td id="header">Nachname</td>
<td id="header">Geburtstag</td>
<td id="header">Token</td>
<td id="header">Löschen</td>
<td id="header">Umfrage-Link</td>
<td id="header">Webseiten-Link</td>
<td id="header">Senden</td>
</tr>
</thead>
<tbody>
<?php
$nextcloud_base_url = "https://example.com";
$nextcloud_attendees_base_url = $nextcloud_base_url . "/apps/polls/s/";
if(isset($_REQUEST['post_id']) && isset($_REQUEST['poll_id'])){
$post_id = $_REQUEST['post_id']; //post ID
$poll_id = $_REQUEST['poll_id']; //poll ID
}
$wordpress_polls_table_name = 'wordpress_polls'; //storage of primary keys of post id and poll id
$polls_share_table_name = 'oc_polls_share'; //attendees table
$wordpress_polls = get_wordpress_polls($wordpress_polls_table_name, $post_id);
$wordpress_polls_rows = get_wordpress_polls($wordpress_polls_table_name, $post_id);
$poll_id = get_poll_id($wordpress_polls);
if($wordpress_polls_rows === NULL || $wordpress_polls_rows === 0){
return;
} else {
$attendees = get_attendees($polls_share_table_name, $poll_id);
$attendees_rows = get_attendees_rows($polls_share_table_name, $poll_id);
create_attendee_rows($attendees, $nextcloud_attendees_base_url);
}
?>
</tbody>
</table>
</div>
<div id="legende">
<p>
Status-Legende:<br>
❌ = Abstimmung nicht erfolgt<br>
✅ = Abstimmung erfolgt
</p>
</div>
</body>
</html>
EDIT:
I am looking into the Custom Endpoints Documentation, but couldn't get it to work for now.
Meanwhile a picture of the content I want to integrate (attendees.php)
There's a bunch of ways to solve this which I'll try to outline. These are not in order of recommendation, just stream on consciousness. I would recommend #2, if it is viable, however.
1 - Manually boot WordPress
This question shows shows how to do this and this answer gives pros and cons for each, but the general idea is to require_once either the wp-load.php or the wp-blog-header.php files from root, and you'd probably want the former. Doing this, however, is usually discouraged and I would only recommend it for cases where you need access to basic WordPress functions. If you do this, WordPress doesn't know what your security requirements are, so it will be up to you to perform access control using things like current_user_can.
Although I posted this first, I would strongly recommended avoiding this, and if you are distributing your plugin, especially in the WordPress.org repo, absolutely don't do this because I'm pretty certain it would be rejected.
2 - Create a true WordPress admin page
If you are willing so sacrifice some pixel space (for the admin toolbars), this is the recommended way. Just register a menu using add_menu_page and you can either echo or include/require your code:
add_action(
'admin_menu',
static function () {
add_menu_page(
'My Plugin',
'My Plugin',
'manage_options',
'my-plugin',
static function () {
// Either echo here or use an include/require
echo '<h1>Hello world</h1>';
}
);
}
);
The URL to this page is based on the fourth parameter to that function, which using the above would be /wp-admin/admin.php?page=my-plugin. Access control is handled automatically with the third parameter which makes certain that the user has the manage_options permission. You can customize that as needed, and optionally create your own permissions, too.
3 - Inject via templates
The template_include function is used to determine which front-end WordPress template to use. Personally, I don't like using this for admin stuff because I like to keep things separate from each other, but that's just me. In this code sample below I'm setting a template in the theme's folder, but it could just as easily be in the plugin's folder.
add_filter(
'template_include',
static function ($template) {
// Pick whatever logic you want here, it could be `_GET` or `_POST` or pretty much anything
if ('my-plugin' === ($_GET['action'] ?? null)) {
$template = get_template_directory() . '/searchform.php';
}
return $template;
}
);
The if logic is where you do whatever you want. I'm just showing a simple _GET check where the URL would be /?action=my-plugin. Security, once again, is up to you, but you have full access to WordPress core functions like current_user_can to do whatever is necessary.
4 - Rewrite endpoints
This is actually a version of #3 because you are just making the URL prettier. I personally think it is over-complicated because it is a multi-step process with a lot of moving parts, but if the URL is important to you it might work. Make sure to flush your permalinks! The key to this is rewrite_rules_array where you register a custom regex for the URL and you can provide whatever logic you need, including querystrings and whatever.
// Register a global variable for the URL so that WordPress is aware that you care about it
add_filter(
'query_vars',
static function ($vars) {
$vars[] = 'my-plugin';
return $vars;
}
);
// Add special regex-like syntax for URLs. You can go wild here, too
add_action(
'rewrite_rules_array',
static function ($rules) {
$newrules = array();
// The true isn't important, it could be anything. The my-plugin is what
// matters. Make sure to flush your permalinks!
$newrules['my-plugin/?$'] = 'index.php?my-plugin=true';
return $newrules + $rules;
}
);
add_action(
'template_include',
static function ($template) {
if (get_query_var('my-plugin')) {
$template = get_template_directory() . '/searchform.php';
}
return $template;
}
);
I am trying to create a text area in WordPress general settings, which allows a disclaimer or other info to show at the bottom of each page of the website template.
It works fine using the input tag, however when I change to textarea it will not store the data on save.
I have been searching online, but haven't found the right solution.
Here is the current code I am using:
<?php
$new_general_setting_disclaimer = new new_general_setting_disclaimer();
class new_general_setting_disclaimer {
function new_general_setting_disclaimer( ) {
add_filter( 'admin_init' , array( &$this , 'register_fields' ) );
}
function register_fields() {
register_setting( 'general', 'disclaimer', 'esc_attr' );
add_settings_field('disclaimer', '<label for="disclaimer">'.__('Website Disclaimer' , 'disclaimer' ).'</label>' , array(&$this, 'fields_html') , 'general' );
}
function fields_html() {
$value = get_option( 'disclaimer' );
echo '<textarea id="disclaimer" name="disclaimer" cols="50" rows="5" value="'. $value .'" /></textarea>';
}
}
?>
Thanks in advance. Please let me know if you need more info.
i got my registered sidebars listing function in functions.php
everything works perfect on post options page (wp-admin/post.php)
i can get all the registered sidebars via my function.
but in the category edit page (wp-admin/edit-tags.php) ,
i can't even access the global variable $wp_registered_sidebars , not mentioning about the function itself.
here is the function
function sidebars_list(){
global $wp_registered_sidebars;
$sidebar = array();
if (!empty($wp_registered_sidebars)):
foreach ($wp_registered_sidebars as $key => $access):
$sidebar[$key] = $access['name'];
endforeach;
endif;
var_dump($sidebar);
return $sidebar;
}
as i said it works perfect on editing post and pages at the backend (frontend as well)
i tried to add_action it , no luck.
can't even access the global variable in category edit page.
global $wp_registered_sidebars;
var_dump($wp_registered_sidebars);
returns empty array.
but when i var_dump inside the function it returns as expected.
what's wrong ?
As you said that the global variable value not found. I assume that your variable got overwritten the value with empty array.
I suggest you to change the variable name and retry with var_dump the variable.
global $wp_registered_sidebars_custom;
var_dump($wp_registered_sidebars_custom);
After wasting a lot of time for searching this and thought out this solution. Accessing through a category page is earlier before sidebar values are loaded. So You can make a work around by placing a placeholder div in that place and load the values in the dropdown or checkbox using Ajax & jQuery after the page is loaded. that would work for you.
Paste the following code in functions.php of your theme
// Call Actio to modify form on Add New Category
add_action( 'category_add_form_fields', 'edit_category_fields');
// Call Action to modify form on Edit Category
add_action( 'category_edit_form_fields', 'edit_category_fields');
function edit_category_fields($tag, $taxonomy)
{
// Get the Current Value if any
$leftsidebar_to_show = get_term_meta( $tag->term_id, 'leftsidebar_to_show', true);
?>
<tr class="form-field">
<th scope="row" valign="top"><label for="leftsidebar_to_show">Select Left Sidebar to Show</label></th>
<td>
<div id="leftsidebar_to_show_wrap">
<select name="leftsidebar_to_show" id="leftsidebar_to_show">
</select>
</div>
<!-- Store the current value as hidden input in order to Get Selected Option in jQuery -->
<input type="hidden" id="leftsidebar_to_show_val" value="<?php echo $leftsidebar_to_show; ?>" />
<!-- Category ID as hidden Input -->
<input type="hidden" name="term_id_val" value="<?php echo $tag->term_id; ?>" />
</td>
</tr>
<?php
}
// Call Actio to Save Values on Add New Category
add_action( 'edited_category', 'save_category', 10, 2);
// Call Action to Save Values on Edit Category
add_action( 'create_category', 'save_category', 10, 2);
function save_category(){
update_term_meta( $_POST['term_id_val'], 'leftsidebar_to_show', $_POST['leftsidebar_to_show']);
}
// Function to enqueue Javascript file in admin
function my_enqueue($hook) {
wp_enqueue_script( 'my_custom_script', get_template_directory_uri() . '/js/sidebars.js' );
}
add_action( 'admin_enqueue_scripts', 'my_enqueue' );
// Action Function to get Sidebars through Ajax Call
function prefix_ajax_get_sidebars() {
$sidebarval = $_REQUEST['sidebarval'];
$sidebarid = $_REQUEST['sidebarid'];
$string = '<select id="'.$sidebarid.'" name="'.$sidebarid.'">';
foreach ( $GLOBALS['wp_registered_sidebars'] as $sidebar ) {
if($sidebarval == $sidebar['id']){
$selected = ' selected';
}else{
$selected = '';
}
$string .= '<option value="'.$sidebar['id'].'"'.$selected.'>'.$sidebar['name'].'</option>';
}
$string .= '</select>';
echo $string;
die();
}
add_action( 'wp_ajax_get_sidebars', 'prefix_ajax_get_sidebars' );
add_action('wp_ajax_nopriv_get_sidebars', 'prefix_ajax_get_sidebars');
Create a file named sidebars.js and Paste the following code
(function ($) {
"use strict";
$(document).ready(function(){
var leftsidebar_to_show_val = $('#leftsidebar_to_show_val').val();
$.post(
ajaxurl,
{
'action': 'get_sidebars',
'sidebarval': leftsidebar_to_show_val,
'sidebarid' : 'leftsidebar_to_show'
},
function(response){
$('#leftsidebar_to_show_wrap').html(response);
});
});
})(jQuery);
And move the above created file to js folder of your theme. Now you can see the sidebars listed as dropdown in the Add & Edit Category Forms.
Hope this is clear.
Thanks!
Insert HTML Input to a themes template file?
My question is this:
Currently with my code, I can have whatever I've set in my custom settings page appear on
the end of every post using, of course, a WordPress filter.
The only thing is, I don't want what I input to go anywhere within a post. What I am trying to
achieve, is to have my input injected into the current themes home.php template file, within a <div></div> tag that's contained within that template file. The <div> in question has an ID attached, which is <div id="category-inner">, so is there any way use it's ID to target it in my plugin?
I've successfully managed to do it, by editing the actual home.php template file and inserting a bit of php directly there to show the user input, but that totally goes against what I'm trying to do, which is to not have to edit the source code of the template file and only have to use my plugin to insert the users inputted text in that specific location (the <div> mentioned above).
My plugin is only ever going to be adding user input in one place on the site, and it will never change. And the place it will always go in, is where I mentioned above.
Below is my plugin code:
<?php
/*/
Plugin Name: Custom Text Adder
Plugin URI: N/A
Description: Demonstrates how rubbish I am at pretty much everything I want to do
Version: 101
Author: JD
Author URI: N/A
/*/
// insert custom plugin settings menu
add_action('admin_menu', 'custom_create_menu');
add_filter('the_content', 'customhead_the_content');
function customhead_the_content($content) {
$output = $content;
$output .= '<div id="category-inner">';
$output .= get_option('post_text');
$output .= '</div>';
return $output;
}
// Add Font-Size to WYSIWYG Editor
function wp_editor_fontsize_filter( $options ) {
array_shift( $options );
array_unshift( $options, 'fontsizeselect');
array_unshift( $options, 'formatselect');
return $options;
}
add_filter('mce_buttons_2', 'wp_editor_fontsize_filter');
// Create Custom Menu
function custom_create_menu() {
//create new top-level menu
add_menu_page('Custom Plugin Settings', 'Custom Settings', 'administrator', __FILE__, 'custom_settings_page',plugins_url('/img/icon.png', __FILE__));
//call register settings function
add_action( 'admin_init', 'register_mysettings' );
}
// Register our settings
function register_mysettings() {
register_setting( 'custom-settings-group', 'new_option_name' );
register_setting( 'custom-settings-group', 'some_other_option' );
register_setting( 'custom-settings-group', 'option_etc' );
register_setting( 'custom-settings-group', 'font_size' );
register_setting( 'custom-settings-group', 'post_text' );
}
function custom_settings_page() {
?>
<!-- Custom Settings Page Container -->
<div class="wrap">
<h2>Custom Text</h2>
<form method="post" action="options.php">
<?php settings_fields( 'custom-settings-group' ); ?>
<table class="form-table">
<?php /* Bring the editor onto the page */
wp_editor( '', 'post_text', $settings = array() );
// 4.
// Custom buttons for the editor.
// This is a list separated with a comma after each feature
// eg. link, unlink, bold, ...
$settings = array(
'textarea_name' => 'post_text',
'media_buttons' => true,
'tinymce' => array(
'theme_advanced_buttons1' => 'formatselect,|,bold,italic,underline,|,' .
'bullist,blockquote,|,justifyleft,justifycenter' .
',justifyright,justifyfull,|,link,unlink,|' .
',spellchecker,wp_fullscreen,wp_adv'
)
);
submit_button( 'Save everything', 'primary', 'submit' ); ?>
</table>
</form>
</div>
<?php }; ?>
Here is the screenshot which will be able to explain this in the most concise way possible:
http://i.imgur.com/hiEjEsA.jpg
Again, any and all help is hugely appreciated and will hopefully stop my brain from hurting!
You all rock,
Casey. :)
I'm not sure if you want this to be a pure PHP solution, but since you have the ID of the div you could target it with jQuery and insert the text into the div on page load (or form submit) with something like this:
$(document).ready(function() {
var userText = $('#input-id').val();
$('#category-inner').html(userText);
})