How to Develop a Plugin for The FOJ
Developing a plugin for The FOJ is quite easy. Below is the directory structure of a simple plugin:
The directories are:
plugins > my_plugin >
- classes
- css
- includes
- js
The
my_plugin
directory is the name of your plugin and the main directory that contains the other directories. Put the my_plugin
directory inside the plugins
directory of The FOJ like so plugins/my_plugin
so that you can easily test your plugin in the FOJ.
Not all the directories may be neccessary in your plugin. Also the names of the directories of your plugin don't have to be the same as listed above. You can change them except the
inlcudes
directory which must remain the same name.
Example Plugin
Let us develop a simple plugin for The FOJ.
Plugin Name
The name of the plugin I want to develop is called my_plugin
so I create a directory called my_plugin
. This directory will contain any other directory of the plugin.
Plugin Code
I choose to write the plugin code in a class. So I create a PHP file called My_Plugin.php
. Next, I want to save the My_Plugin.php
in a directory. To make it easy for me to remember, I create a directory named classes
inside the my_plugin
directory. Then I save the My_Plugin.php
in the classes
directory inside the my_plugin
directory like so: plugins/my_plugin/classes/My_Plugin.php
Now, example code of the My_Plugin.php
class will be like so:
Editing plugins/my_plugin/classes/My_Plugin.php
<?php
class My_Plugin{
static function write_a_paragraph(){
echo '<p>This is a paragraph</p>';
}
}
?>
The code above is a simple plugin for The FOJ. Now we want to call the method which we wrote in the class. The class' name is My_Plugin
and the method's name is write_a_paragraph
. Where should this method be called? The method can be called in different parts of your website. The method can be called:
- Inside a page or a Post
- As a private page or logged-in user account page
- As admin page
- Inside ajax.php file
- Inside cron.php jon file
- As a widget
Calling a method or function of your plugin inside a page or a post
A page or a post is like this page where you are reading this content. If you want your method or function to be called in a page or a post, put your method or function in a shortcode like this:
[sc]class|class_name|method_name|arguent_1,argument_2,argument_3 ...[/sc]
Or if the function was written without a class, then the shortcode would be like this:
[sc]function_name|argumen_1,argument_2,argument_3,[/sc]
Then when you are writing the page or post in admin, put the shortcode in the text editor where you want the content of the method or function to appear. In our example, the class' name is
My_Plugin
and the method's name is write_a_paragraph
so our shortcode will be like this: [sc]class|My_Plugin|write_a_paragraph[/sc]
If the method had for example 3 arguments namely: arg_1, arg_2, arg_3, then the arguments would be added to the shortcode like this:
[sc]class|My_Plugin|write_a_paragraph|arg_1,arg_2,arg_3[/sc]
Suppose that the function was written without a class, then the shortcode would simply be like this :
[sc]write_a_paragraph[/sc]
Suppose that the function written without a class had 3 arguments namely arg_1, arg_2 and arg_3, then the shortcode would be like this:
[sc]write_a_paragraph|arg_1,arg_2,arg_3[/sc]
NOTE: Methods that will be called via shortcodes must be static method because the method will be called statically.
NOTE: There should be no spaces in the shortcode
Including the Class or the functions' file in the website
Before your shortcode will work, you must include the class or the file of the functions in the website. This is simple to do. In the includes
directory, create a file named includes.php
like so plugins/my_plugin/includes/includes.php
. Inside the includes.php
, write the comment and the path of the class or functions' file as in the example below:
Editing plugins/my_plugin/includes/includes.php
<?php
/**
* @Author : Kyei Osei Yaw
* @Company : Nationton Information Technology
* @Website : https://thefoj.net
* @Email : info@thefoj.net
* @Copyright : Your copyright notice,
* @Version : 1.0
* @Year : 2023
*/
//This will include My_Plugin.php on the top of pages and posts
$aPageTop_[] = 'plugins/my_plugin/classes/My_Plugin.php';
?>
Once you have put the multi-line comment and path of your class or functions' file in the
plugins/my_plugin/includes/includes.php
includes.php like in the example above, the shortcode will work. However, you must have the plugin activated. Zip the plugins/my_plugin/includes/includes.php
my_plugin directory and upload and activate it in the admin. The multi-line comment in the plugins/my_plugin/includes/includes.php
includes.php must have @Author, @Company, @Website, @Email, @Copyright, @Version and @Year in the parttern as in the example above. Congratulations. You have created your first plugin for The FOJ
Allowing Users to Insert the Shortcode in the Page or Post
Sometimes, you want the users of your plugin to be able to insert the shortcode into the page or the post. But writing the shortcode could be complex for your users so you may want your users to click on a button to insert the shortcode. To do that you must add your shortcode to the editor widgets. See the image below:
From the image above, some of the editor widgets are Login Form, Registration Form, The FOJ Gallery, Post Display. If for example, the user clicks on "Login Form", a shortcode will be inserted into the editor. To add an editor widget, do the following:
-
In the
includes
directory, create a file namedadmin_menu.php
so that the path of the file is likeplugins/my_plugin/includes/admin_menu.php
. -
In the
admin_menu.php
, write the code for your editor widget like so:
Editingplugins/my_plugin/includes/admin_menu.php
<?php $aAdminEditorWidgets[] = [ [ 'name' => 'A Paragraph', 'icon' => '', 'desc' => 'Add a paragraph', 'css_id' => 'add-a-paragraph', 'css_class' => 'add-a-paragraph' ] ]; ?>
-
When you have done this, the new widget you have written will be added to the existing editor widgets in the admin and will be seen when you are creating or editing a page or post in the admin like so:
- Here is a description of the
$aAdminEditorWidgets array
:
$aAdminEditorWidgets:
$aAdminEditorWidgets
is a variable and must remain the same.
name: The name that a user will see on the editor widget
icon: Path to a small image that can be used as an icon of your widget, e.g "../uploads/2023/04/icon.jpg"
desc: A small description of your editor widget
css_id: HTML id for your widget
css_class: HTML class for your widget - Now let's add some JavaScript to handle inserting the shortcode into the editor when editor widget is clicked.
-
In the
js
directory, create a JavaScript file with any name you want. For the purpose of this example, the name of the JavaScript File isparagraph.js
. Theparagraph.js
will be in your directory like soplugins/my_plugin/js/paragraph.js
-
In the
paragraph.js
, write the code for the editor widget like so:
Editingplugins/my_plugin/js/paragraph.js
$(function(){ $('#add-a-paragraph').click(function(){ $('.summernote').summernote('editor.saveRange'); $('.summernote').summernote('editor.restoreRange'); $('.summernote').summernote('editor.focus'); //Paste the shortcode into the editor $('.summernote').summernote('editor.pasteHTML', '[sc]class|My_Plugin|write_a_paragraph[/sc]'); $(this).html('Shortcode has been inserted into the editor'); }); });
-
The id
add-a-paragraph
in the first line of the code is thecss_id
which you give your editor widget in theadmin_menu.php
. -
The following line pastes the shortcode into the editor. Change the shortcode to fit your plugin.
$('.summernote').summernote('editor.pasteHTML', '[sc]class|My_Plugin|write_a_paragraph[/sc]')
-
The next step is to include the
paragraph.js
file inside the body of the admin part of the website. You can include it in the head of the website but inlcuding it in the body is often recommended. -
To include it in the body, create a PHP file. Name it
admin_add_in_footer.php
. You can name it anything you want but for the purpose of this example, name itadmin_add_in_footer.php
. Put this file in theincludes
directory like so:plugins/my_plugin/includes/admin_add_in_footer.php
. Inside theadmin_add_in_footer.php
write the HTML code to include theparagraph.js
file like so:
Editingplugins/my_plugin/includes/admin_add_in_footer.php
<?php ?> <script src="../plugins/my_plugin/js/paragraph.js"></script>
-
Next, create another file called
admin_includes.php
. The name of this file must remainadmin_includes.php
. Put this file in theincludes
directory like so:plugins/my_plugin/includes/admin_includes.php
. In theadmin_includes.php
file, write a code to include theadmin_add_in_footer.php
file like so:
Editingplugins/my_plugin/includes/admin_includes.php
<?php //Include the admin_add_in_footer.php file in the body just before the </body> tag $aInsideFooter_[] = '../plugins/my_plugin/includes/admin_add_in_footer.php'; ?>
-
Once you have completed the step above, the
paragraph.js
file has been included in the body of the admin part of the website. Now when you click on the editor widget for the paragraph, the shortcode will be inserted into the editor.
Calling a method or function of your plugin as a private page or as a logged-in user account page
When a user logs into the site with password and username or email address, the user is redirected to account.php
, a protected page accessible to only those who have logged in. If you want your plugin to have one or more of such protected pages, this is what you will to:
-
Write the method or function that should be called on the protected page. We are going to write an example method. From our example plugin called
my_plugin
, there is a class file namedMy_Plugin.php
with the pathplugins/my_plugin/classes/My_Plugin.php
. We are going to edit this class and add another example method like so:
Editingplugins/my_plugin/classes/My_Plugin.php
<?php class My_Plugin{ //To be called inside a page or post satic function write_a_paragraph(){ echo '<p>This is a paragraph</p>'; } //Protected page function protected_page(){ if(isset($_GET['ipage']) && $_GET['ipage'] === 'protected-page'){ //get user id $iUserId = thefoj_get('user_id'); //check if user id is available if(!empty($iUserId)){ ?> <div class = "col-12 section-col"> <h1 class = "fsize-28">This is a Protected Page </h1> <p> Hello <?php echo thefoj_user('user_full_name');?>, welcome to a protected page. </p> </div> <?php } } } } ?>
-
A typical link to a protected page consists of a slug and a user id as in the example link below:
https://example.com/account.php?ipage=protected-page&u=12
-
The
protected-page
part of the URL is the slug and the12
is the user id. Theprotected-page
is an example slug and it changes with any different link. Likewise the12
is an example user id and it changes when the link changes.
-
The following code of the
protected_page()
method checks to see ifprotected-page
is present in the link.<?php if(isset($_GET['ipage']) && $_GET['ipage'] === 'protected-page'){ //... } ?>
-
The index
ipage
can be changed in the code to be any valid string if it is changed in the URL accordingly.
-
Supposing the URL below is entered into the browser,
https://example.com/account.php?ipage=protected-page&u=12
then the code below gets the user id which is12
<?php //get user id $iUserId = thefoj_get('user_id'); ?>
-
If user id is avalable as being checked by the code below, then, the protected page is written
<?php //check if user id is available if(!empty($iUserId)){ ?> <div class = "col-12 section-col"> <h1 class = "fsize-28">This is a Protected Page </h1> <p> Hello <?php echo thefoj_user('user_full_name');?>, welcome to a protected page. </p> </div> <?php } ?>
-
Bootstrap is massively used in The FOJ so in the HMTL part of the code, we encourage you to use the bootstrap class which is
col-12
. The column size depends on you. The HTML class,section-col
is neccessary if you are using any of the default themes of The FOJ. It makes the page's height long as the theme wants.
-
The following part of the code will output the full name of the user whose user id is in the URL.
<?php echo thefoj_user('user_full_name'); ?>
-
To call the
protected_page()
method as the private page (protected page) or logged-in user account page, create PHP file namedcall_methods_in_private_page.php
. You can name this file with any name you want but for the sake of this example, let it becall_methods_in_private_page.php
. Put this file in theincludes
directory of the plugin like so:plugins/my_plugin/includes/call_methods_in_private_page.php
. In thecall_methods_in_private_page.php
, call theprivate_page()
method as follows:<?php //require or include the My_Plugin.php require_once('plugins/my_plugin/classes/My_Plugin.php'); //Call the protected_page() method $oMyPlugin = new My_Plugin(); $oMyPlugin->protected_page(); //Here, you can call any method that is in My_Plugin() class. ?>
-
Next, go to the
includes.php
inplugins/my_plugin/includes/includes.php
. Edit theincludes.php
and make a reference to theMy_Plugin.php
class like so:
Editingplugins/my_plugin/includes/includes.php
<?php /** * @Author : Kyei Osei Yaw * @Company : Nationton Information Technology * @Website : https://thefoj.net * @Email : info@thefoj.net * @Copyright : Your copyright notice, * @Version : 1.0 * @Year : 2023 */ //This will include My_Plugin.php on the top of pages and posts $aPageTop_[] = 'plugins/my_plugin/classes/My_Plugin.php'; //This will include the call_methods_in_private_page.php in the middle of private page. $aPrivatePageMiddle_[] = 'plugins/my_plugin/includes/call_methods_in_private_page.php'; ?>
-
Once you have done this, ensure that you have logged into The FOJ website with your email or username and password. Then visit this link
https://example.com/accout.php?ipage=protected-page&u=12
. Make sure that the12
inu=12
is the user id of the person who has logged in.
The page will look like this:
Calling a method or function of a plugin as admin page
There are many pages in the admin part of The FOJ site. To make your plugin have a page in the admin or to call a method or function as admin page, write the method or the function. In this example, we will write the method in the My_Plugin.php
. In the plugins/my_plugin/classes/My_Plugin.php
, we already have 2 methods namely: write_a_paragraph()
and protected_page()
. We will add a method named admin_page()
to it for the admin page. Write the method for the admin page as follows:
Editing plugins/my_plugin/classes/My_Plugin.php
<?php
class My_Plugin{
//To be called inside a page or post
satic function write_a_paragraph(){
echo '<p>This is a paragraph</p>';
}
//Protected page
function protected_page(){
if(isset($_GET['ipage']) && $_GET['ipage'] === 'protected-page'){
//get user id
$iUserId = thefoj_get('user_id');
//check if user id is available
if(!empty($iUserId)){
?>
<div class = "col-12 section-col">
<h1 class = "fsize-28">This is a Protected Page </h1>
<p>
Hello <?php echo thefoj_user('user_full_name');?>, welcome to a protected page.
</p>
</div>
<?php
}
}
}
//Admin page
function admin_page(){
if(isset($_GET['apage']) && $_GET['apage'] === 'admin-page'){
?>
<div class = "col-12 section-col">
<h1 class = "fsize-28">This is an Admin Page </h1>
<p>
Hello, welcome to a new admin page
</p>
</div>
<?php
}
}
}
?>
Bootstrap is massively used in The FOJ so in the HMTL part of the code, we encourage you to use the bootstrap class which is
col-12
. The column size depends on you. The HTML class, section-col
is also neccessary. The HTML class fsize-28
makes the heading have font size of 28px. It is from fsize-8
to fsize-72
To call the
admin_page()
method, create a PHP file named call_admin_method.php
. You can name the file any name you want but for the sake of this example, name the file as call_admin_method.php
. Put the file in the includes
directory like so: plugins/my_plugin/includes/call_admin_method.php
In the
call_admin_method.php
, include the My_Plugin.php
file and call the admin_method()
method as follows: Editing
plugins/my_plugin/includes/call_admin_method.php
<?php
//require or include the My_Plugin.php
require_once('../plugins/my_plugin/classes/My_Plugin.php');
//Call the admin_page() method
$oMyPlugin = new My_Plugin();
$oMyPlugin->admin_page();
//Here, you can call any method that is in My_Plugin() class.
?>
Next, in the
admin_includes.php
, make reference to the call_admin_method.php
as follows Editing
plugins/my_plugin/includes/admin_includes.php
<?php
//Include the admin_add_in_footer.php file in the body just before the </body> tag
$aInsideFooter_[] = '../plugins/my_plugin/includes/admin_add_in_footer.php';
//Include the call_admin_method.php file in the middle of admin/account.php
$aPrivatePageMiddle_[] = '../plugins/my_plugin/includes/call_admin_method.php';
?>
In the above code,
$aInsideFooter_[]
was already in the admin_includes.php
. The new reference we have added is the $aPrivatePageMiddle_[]
which corresponds to calling the admin method. Once we have completed the step above, log into the admin part of The FOJ site. visit the following URL:
https://example.com/account.php?apage=admin-page
Replace
https://example.com
with the actual URL of your site The admin page will look like this:
Calling a method or function of your plugin inside ajax.php at the public part of The FOJ website
If your plugin makes ajax calls, you may want to call your method or function in a PHP file and then make reference to that file in your JavaScript.
Consider the jQuery ajax call example below:
$.ajax({
url: 'ajax.php',
type: 'POST',
data: {'submit':1, 'country_name':sCountryName}
}).done(function(response){
//
});
In the ajax call above, reference is being made to
ajax.php
. ajax.php
is a file located at the root of The FOJ site in which methods or functions corresponding to ajax calls are being called. To have your ajax related PHP function called in the ajax.php
, do the following: -
Create a PHP file named
ajax_calls.php
. You can name this file any name you want but for the sake of this example, name the fileajax_calls.php
. Put this file in theincludes
directory of your plugin like soplugins/my_plugin/includes/ajax_calls.php
-
In the
ajax_calls.php
, call your ajax-related methods or functions. For example, in the fileplugins/my_plugin/classes/My_Plugin.php
, the class name isMy_Plugin
. Suppose that in that class, you have a method namedajax_call()
,then you would callajax_call()
like this:
Editingplugins/my_plugin/includes/ajax_calls.php
<?php //require or include the My_Plugin.php require_once('plugins/my_plugin/classes/My_Plugin.php'); //Call the ajax_call() method like so: $oMyPlugin = new My_Plugin(); $oMyPlugin->ajax_call(); ?>
-
Finally, make reference to the
ajax_calls.php
file in theincludes.php
like this:
Editingplugins/my_plugin/includes/includes.php
<?php /** * @Author : Kyei Osei Yaw * @Company : Nationton Information Technology * @Website : https://thefoj.net * @Email : info@thefoj.net * @Copyright : Your copyright notice, * @Version : 1.0 * @Year : 2023 */ //This will include My_Plugin.php on the top of pages and posts $aPageTop_[] = 'plugins/my_plugin/classes/My_Plugin.php'; //This will include the call_methods_in_private_page.php in the middle of private page. $aPrivatePageMiddle_[] = 'plugins/my_plugin/includes/call_methods_in_private_page.php'; //This will include the ajax_calls.php in the ajax.php $aInAjaxPage_[] = 'plugins/my_plugin/includes/ajax_calls.php'; ?>
That is it. You are done. Your method or function will be called when your JavaScript makes call to the
ajax.php
.
In the above code,the multi-line comment, $aPageTop_[]
and $aPrivatePageMiddle_[]
existed in the includes.php
already from previous tutorial. $aInAjaxPage_[]
is the new variable that was added in reference to the ajax_calls.php
. In the includes.php
, it is important to maintain the multi-line comment. But modify its parameters to suit your plugin. The comment must have @Author, @Company, @Website, @Email, @Copyright, @Version and @Year in the parttern as in the example above.
Calling a method or function of your plugin inside ajax.php in the admin
Making ajax call in the admin part of The FOJ site is similar to making ajax call in the public part of the site.
If your plugin makes ajax calls, you may want to call your method or function in a PHP file and then make reference to that file in your JavaScript.
Consider the jQuery ajax call example below:
$.ajax({
url: 'ajax.php',
type: 'POST',
data: {'submit':1, 'country_name':sCountryName}
}).done(function(response){
//
});
In the ajax call above, reference is being made to
ajax.php
. In the admin part of the site, ajax.php
is a file located at admin/ajax.php
and in it, methods or functions corresponding to admin ajax calls are being called. To have your ajax related PHP method or function called in the ajax.php
, do the following: -
Create a PHP file named
admin_ajax_calls.php
. You can name this file any name you want but for the sake of this example, name the fileadmin_ajax_calls.php
. Put this file in theincludes
directory of your plugin like soplugins/my_plugin/includes/admin_ajax_calls.php
-
In the
admin_ajax_calls.php
, call your ajax-related methods or functions. For example, in the fileplugins/my_plugin/classes/My_Plugin.php
, the class name isMy_Plugin
. Suppose that in that class, you have a method namedadmin_ajax_call()
,then you would calladmin_ajax_call();
like this:
Editingplugins/my_plugin/includes/admin_ajax_calls.php
<?php //require or include the My_Plugin.php require_once('../plugins/my_plugin/classes/My_Plugin.php'); //Call the admin_ajax_call() method like so: $oMyPlugin = new My_Plugin(); $oMyPlugin->admin_ajax_call(); ?>
-
Finally, make reference to the
admin_ajax_calls.php
file in theadmin_includes.php
like this:
Editingplugins/my_plugin/includes/admin_includes.php
<?php //Include the admin_add_in_footer.php file in the body just before the </body> tag $aInsideFooter_[] = '../plugins/my_plugin/includes/admin_add_in_footer.php'; //Include the call_admin_method.php file in the middle of admin/account.php $aPrivatePageMiddle_[] = '../plugins/my_plugin/includes/call_admin_method.php'; //This will include the admin_ajax_calls.php in the admin/ajax.php $aInAjaxPage_[] = '../plugins/my_plugin/includes/admin_ajax_calls.php'; ?>
That is it. You are done. Your method or function will be called when your JavaScript makes call to the
ajax.php
in the admin.
In the above code, $aInsideFooter_[]
and $aPrivatePageMiddle_[]
existed in the admin_includes.php
already from previous tutorial. $aInAjaxPage_[]
is the new variable that was added in reference to the admin_ajax_calls.php
.
Calling a method or function of your plugin inside cron.php
If you have a method or function that must be called when cron job runs, it must be called inside cron.php
. The cron.php
is located at the root of The FOJ website. To call your method or function in the cron.php
file, follow the following steps:
-
Create a PHP file named
call_methods_in_cron.php
. You can name this file any name you want but for the sake of this example, name the filecall_methods_in_cron.php
. Put this file in theincludes
directory of your plugin like soplugins/my_plugin/includes/call_methods_in_cron.php
-
In the
call_methods_in_cron.php
, call your cron job related methods or functions. For example, in the fileplugins/my_plugin/classes/My_Plugin.php
, the class name isMy_Plugin
. Suppose that in that class, you had a method namedcron_job()
,then you would callcron_job();
like this:
Editingplugins/my_plugin/includes/admin_ajax_calls.php
<?php //require or include the My_Plugin.php require_once('plugins/my_plugin/classes/My_Plugin.php'); //Call the cron_job() method like so: $oMyPlugin = new My_Plugin(); $oMyPlugin->cron_job(); ?>
-
Finally, make reference to the
call_methods_in_cron.php
file in theincludes.php
like this:
Editingplugins/my_plugin/includes/includes.php
<?php /** * @Author : Kyei Osei Yaw * @Company : Nationton Information Technology * @Website : https://thefoj.net * @Email : info@thefoj.net * @Copyright : Your copyright notice, * @Version : 1.0 * @Year : 2023 */ //This will include My_Plugin.php on the top of pages and posts $aPageTop_[] = 'plugins/my_plugin/classes/My_Plugin.php'; //This will include the call_methods_in_private_page.php in the middle of private page. $aPrivatePageMiddle_[] = 'plugins/my_plugin/includes/call_methods_in_private_page.php'; //This will include the ajax_calls.php in the ajax.php $aInAjaxPage_[] = 'plugins/my_plugin/includes/ajax_calls.php'; //This will include the call_methods_in_cron.php in cron.php $aInCronPage_[] = 'plugins/my_plugin/includes/call_methods_in_cron.php'; ?>
That is it. You are done. Your method or function will be called when cron job runs.
In the above code,the multi-line comment,
$aPageTop_[]
, $aPrivatePageMiddle_[]
and $aInAjaxPage_[]
existed in the includes.php
already from previous tutorial. $aInCronPage_[]
is the new variable that was added in reference to the call_methods_in_cron.php
. In the includes.php
, it is important to maintain the multi-line comment. But modify its parameters to suit your plugin. The comment must have @Author, @Company, @Website, @Email, @Copyright, @Version and @Year in the parttern as in the example above.
Calling a Method or Function of Your Plugin as a Widget
At the public part of The FOJ website, a widget is an HTML gadget found at the sidebars of the website. Example of a widget is the subscription form (image below).
The above image is an example of a widget. It is a subsription form often located at the sidebar of the website.
Creating a Widget With Your Plugin
To create a widget you must provide a link which your user as an admin will click on in order to create the widget. To provide a link which your user as admin will click on to create the widget, follow the following steps:
-
Edit the
admin_menu.php
which is found inplugins/my_plugin/includes/admin_menu.php
. This file has already been created in the previous tutorial. Add the following code to theadmin_menu.php
Editingplugins/my_plugin/includes/admin_menu.php
<?php //To create a link which admin will click on in order to create a widget $aListToCreateWidgets[] = [ [ 'title' => 'New Widget for My Plugin', 'url' => 'account.php?apage=new-widget-for-my-plugin', 'desc' => 'Create a new example widget for the plugin called "My Plugin"' ] ]; ?>
-
If you have added the code above to
admin_menu.php
, then go to the admin part of your website. On the left side of the admin, find "Appearance and Design". Hover on the Appearance and Design menu and then click on "Create Widget".
-
Look through the various links on the page that opens. You will see a link corresponding to the code you just added as in the image bellow:
-
In the code above, the variable
$aListToCreateWidgets[]
should remain the same. The array indextitle
is the title that the admin user will see to click on. Theurl
is the link that will open when the admin user clicks on the title. Thedesc
is a description under the title to tell the admin user more about the widget that is to be created.
-
Note that the
$aListToCreateWidgets[]
in the code above can hold more than one array. So for example, if you would create different widgets for your plugin, then you could list them in the$aListToCreateWidgets[]
in theadmin_menu.php
like so:
<?php //To create a link which admin will click on in order to create a widget $aListToCreateWidgets[] = [ [ 'title' => 'New Widget for My Plugin', 'url' => 'account.php?apage=new-widget-for-my-plugin', 'desc' => 'Create a new example widget for the plugin called "My Plugin"' ], [ 'title' => 'New Widget 2', 'url' => 'account.php?apage=new-widget-2', 'desc' => 'Create a new widget 2' ], [ 'title' => 'New Widget 3', 'url' => 'account.php?apage=new-widget-3', 'desc' => 'Create a new widget 3' ] //etc ] ?>
Displaying a Form in the Admin for the Admin User to Create a Widget
Regarding the my_plugin
, we have a link to click on in order to create a widget in the admin. However, currently, when that link is clicked, it opens a blank page. The form which the admin will fill in order to create the widget is not available at the moment. So let us learn how to create a form which the admin will fill to create the widget.
-
Create a new PHP file as a new class named
My_Plugin_Widgets.php
. You can name this file any name you want but for the sake of this example, name itMy_Plugin_Widgets.php
. Put this file inside the classes directory of your plugin like soplugins/my_plugin/classes/My_Plugin_Widgets.php
-
So now we have a class named
My_Plugin_Widgets
. Let this class extendTheFOJ_Widgets
class as follows:
Editing fileplugins/my_plugin/classes/My_Plugin_Widgets.php
<?php class My_Plugin_Widgets extends TheFOJ_Widgets{ } ?>
TheTheFOJ_Widgets
is one of the core classes of The FOJ which located atadmin/system/classes/TheFOJ_Admin_Widgets
of The FOJ.
-
In the file
My_Plugin_Widgets.php
, add a method that will output the form for creating the widget. While the name of the method can be any name, for the sake of this example, let the name of the method bewidget_form()
like so:
Editingplugins/my_plugin/classes/My_Plugin_Widgets.php
<?php class My_Plugin_Widgets extends TheFOJ_Widgets{ //Method for outputing the form that will be used for creating the widget function widget_form(){ } } ?>
-
Now, to the method
widget_form()
, add the code for outputing the widget form like so:
Editingplugins/my_plugin/classes/My_Plugin_Widgets.php
<?php class My_Plugin_Widgets extends TheFOJ_Widgets{ //Method for outputing the form that will be used for creating the widget //Also, the form will be populated with values from database if the widget is being edited. function widget_form(){ //Check to see if the string "new-widget-for-my-plugin" is present in the URL if(isset($_GET['apage']) && $_GET['apage'] === 'new-widget-for-my-plugin'){ $sWidgetPostType = 'function'; //Get widget id from $_GET['widget-id'] if it is available $iWidgetId = thefoj_get('widget_id'); //URL for form action attribute $sActionUrl = 'account.php?apage=new-widget-for-my-plugin'; //Data of widget that has been saved in database $aWidgetDataFromDatabase = []; //If widget has an id, then it has been saved in database before if(!empty($iWidgetId)){ //The $this->widget_item_by_id() method retrieves data of widget that has been saved in the database. $aWidgetDataFromDatabase = $this->widget_item_by_id($iWidgetId, $sWidgetPostType); } if(!empty($aWidgetDataFromDatabase)){ //If widget has been saved in database before, then the form action attribute must have a URL that includes the widget id $sActionUrl = 'account.php?apage=new-widget-for-my-plugin&widget-id=' . $iWidgetId; } ?> <!--Bootstrap is massively used in The FOJ so the the bootstrap class which is "col-12" must be used. The column length depends on you. "section-col" gives the page the min-height: 800px; and background: #fff; --> <div class = "col-12 section-col"> <!--the class fsize-28 gives the h1 element font-size of 28px. It is from fsize-8 to fsize-72, that is 8px to 72px --> <h1 class = "fsize-28">Widget Form</h1> <hr /> <?php //This method validates and saves the form inputs in database and gives feedback such as error or success feedback. $this->process_widget_form(); ?> <?php //In case there is error with the Widget post type whose attribute name is widget_post_type echo $this->sWidgetPostTypeErr; ?> <!-- The class "div-500-default" gives the form element max-width of 500px --> <form class = "div-500-default" action = "<?php echo $sActionUrl;?>" method = "POST"> <?php //This will output the core input elements of the form such as the title, widget_title, widget_position, show_widget_title_or_not, widget_style, widget_space_id, widget_status, widget_visi (Show to who?), widget_appears_on_which_page, selected_pages (IDs of selected pages), echo $this->core_widget_creation_inputs($iWidgetId, $sWidgetPostType); ?> <!-- The class "form-group" is a bootstrap class which adds margin-bottom to the div --> <div class = "form-group"> <!-- The value of widget_post_type is always "function" as your plugin will be calling a method or function as a widget --> <input type = "hidden" name = "widget_post_type" value = "function" /> <input type = "submit" name = "submit_widget_form" class = "btn btn-success float-right" value = "Submit" /> </div> </form> </div> <?php } } } ?>
-
The code above has been explained using comments in the code. Please carefully read each of the comments.
-
The method
process_widget_form()
has been called on the form in thewidget_fom()
in the code above. Therefore, we must write this method in theMy_Plugin_Widgets.php
otherwise, there will be error when we call thewidget_form()
method.
-
Write the
process_widget_form()
method in theMy_Plugin_Widgets.php()
as follows:
Editingplugins/my_plugin/classes/My_Plugin_Widgets.php
<?php class My_Plugin_Widgets extends TheFOJ_Widgets{ //The methods processes inputs from widget_form() function process_widget_form(){ } //Method for outputing the form that will be used for creating the widget //Also, the form will be populated with values from data base if the widget is being edited. function widget_form(){ //Check to see if the string "new-widget-for-my-plugin" is present in the URL if(isset($_GET['apage']) && $_GET['apage'] === 'new-widget-for-my-plugin'){ $sWidgetPostType = 'function'; //Get widget id from $_GET['widget-id'] if it is available $iWidgetId = thefoj_get('widget_id'); //URL for form action attribute $sActionUrl = 'account.php?apage=new-widget-for-my-plugin'; //Data of widget that has been saved in database $aWidgetDataFromDatabase = []; //If widget has an id, then it has been saved in database before if(!empty($iWidgetId)){ //The $this->widget_item_by_id() method retrieves data of widget that has been saved in the database. $aWidgetDataFromDatabase = $this->widget_item_by_id($iWidgetId, $sWidgetPostType); } if(!empty($aWidgetDataFromDatabase)){ //If widget has been saved in database before, then the form action attribute must have a URL that includes the widget id $sActionUrl = 'account.php?apage=new-widget-for-my-plugin&widget-id=' . $iWidgetId; } ?> <!--Bootstrap is massively used in The FOJ so the the bootstrap class which is "col-12" must be used. The column length depends on you. "section-col" gives the page the min-height: 800px; and background: #fff; --> <div class = "col-12 section-col"> <!--the class fsize-28 gives the h1 element font-size of 28px. It is from fsize-8 to fsize-72, that is 8px to 72px --> <h1 class = "fsize-28">Widget Form</h1> <hr /> <?php //This method validates and saves the form inputs in database and gives feedback such as error or success feedback. $this->process_widget_form(); ?> <?php //In case there is error with the Widget post type whose attribute name is widget_post_type echo $this->sWidgetPostTypeErr; ?> <!-- The class "div-500-default" gives the form element max-width of 500px --> <form class = "div-500-default" action = "<?php echo $sActionUrl;?>" method = "POST"> <?php //This will output the core input elements of the form such as the title, widget_title, widget_position, show_widget_title_or_not, widget_style, widget_space_id, widget_status, widget_visi (Show to who?), widget_appears_on_which_page, selected_pages (IDs of selected pages), echo $this->core_widget_creation_inputs($iWidgetId, $sWidgetPostType); ?> <!-- The class "form-group" is a bootstrap class which adds margin-bottom to the div --> <div class = "form-group"> <!-- The value of widget_post_type is always "function" as your plugin will be calling a method or function as a widget --> <input type = "hidden" name = "widget_post_type" value = "function" /> <input type = "submit" name = "submit_widget_form" class = "btn btn-success float-right" value = "Submit" /> </div> </form> </div> <?php } } } ?>
widget_fom()
so that we can see the widget form. To call the method widget_fom()
follow the following steps: call_admin_method.php
in the includes
directory of the plugin like so plugins/my_plugin/includes/call_admin_method.php
. Edit the plugins/my_plugin/includes/call_admin_method.php
, include the plugins/my_plugin/classes/My_Plugin_Widgets.php
and call the method widget_form()
like so:
<?php
//require or include the My_Plugin.php
require_once('../plugins/my_plugin/classes/My_Plugin.php');
//Require or include the My_Plugin_Widgets.php
require_once('../plugins/my_plugin/classes/My_Plugin_Widgets.php');
//Call the admin_page() method
$oMyPlugin = new My_Plugin();
$oMyPlugin->admin_page();
//Call the widget_form() method
$oMyPluginWidgets = new My_Plugin_Widgets();
$oMyPluginWidgets->widget_form();
//Here, you can call any method that is in My_Plugin() and My_Plugin_Widgets() classes.
?>
admin_page()
already existed in the call_admin_method.php
and the code for calling the widget_form()
was added. process_widget_form()
in the plugins/my_plugin/classes/TheFOJ_Admin_Widgets.php
. Now let us add the code for processing the form as follows: Editing
plugins/my_plugin/classes/TheFOJ_Admin_Widgets.php
<?php
class My_Plugin_Widgets extends TheFOJ_Widgets{
//The methods processes inputs from widget_form()
function process_widget_form(){
if(isset($_POST['submit_widget_form']) && $_SERVER['REQUEST_METHOD'] === 'POST' ){
$aErrors = [];
//Plugin's directory name
$sPluginAlias = 'my_plugin';
//The validate_core_widget_creation_inputs method validates the core inputs of the form. It returns array of the inputs if there is no error and returns -1 if there is an error
$aCoreValidation = $this->validate_core_widget_creation_inputs(
$_POST['widget_title'], //$sParamWidgetTitle,
$_POST['show_widget_title_or_not'], //$sParamShowWidgetTitleOrNot,
$_POST['widget_style'], //$sParamWidgetStyle,
$_POST['widget_space_id'], //$iParamWidgetSpaceID,
$_POST['widget_status'], //$sParamWidgetStatus,
$_POST['widget_visi'], //$sParamWidgetPrivacy,
$_POST['widget_appears_on_which_page'], //$sParamWidgetAppearsOnWhichPage,
$_POST['selected_pages'], //$sParamIDsOfSelectedPages
$_POST['widget_post_type'], //$sParamWidgetPostType
$_POST['widget_position'] //$sParamWidgetPositionNumber
);
//After processing the form, the page is redirected to this URL.
$sWidgetEditUrl = 'account.php?apage=new-widget-for-my-plugin';
/*
IMPORTANT NOTE:
Which method or function should be called when your widget is
displayed at the public part of the site? In this example, the
method write_a_paragraph() of the class My_Plugin, that is
plugins/my_plugin/classes/My_Plugin.php
shall be called.
For this reason, the shortcode will be class|My_Plugin|write_a_paragraph
If it is a function without a class then the shortcode would be just write_a_paragraph
If the method or function receives arguments say 3
arguments namely arg_1, arg_2, arg_3 then the shortcode would
be class|My_Plugin|write_a_paragraph|arg_1:::arg_2:::arg_3
If the function does not have a class but has arguments say 3
arguments namely arg_1, arg_2, arg_3 then the shortcode would
be write_a_paragraph|arg_1:::arg_2:::arg_3
You can add as many arguments as you like
*/
$aOptions = array(
'function' => 'class|My_Plugin|write_a_paragraph'
);
//If there are no errors in the form, proceed. If there is an error, there will be error notice
if(empty($aErrors) && !empty($aCoreValidation) && $aCoreValidation != -1){
//The date the widget is being created
$sDateCurrent = date('Y-m-d H:i:s');
//Response when the widget is inserted into the database or updated.
$iResponse = null;
//Get widget id from $_GET['widget-id'] if available
$iWidgetID = thefoj_get('widget_id');
if(empty($iWidgetID)){ //Insert or create new widget in the database
//The function insert_widget_item() returns last insert id on success and -1 on failure
$iResponse = insert_widget_item(
$sPluginAlias, //$sWidgetItemPluginAlias,
$aCoreValidation['widget_title'], //$sWidgetItemName,
$sWidgetEditUrl, //$sParamWidgetEditUrl,
$this->nNull, //$sWidgetIDescription,
$aCoreValidation['widget_position'], //$iWidgetItemPosition,
$aCoreValidation['widget_post_type'], //$sWidgetItemPostType,
$aCoreValidation['widget_space_id'], //$iWidgetItemAdSpaceID,
$aCoreValidation['widget_wrapper_css_class'], //$sWidgetItemWrapperCssClass,
$aCoreValidation['widget_wrapper_css_id'], //$sWidgetItemWrapperCssID,
$aCoreValidation['widget_title'], //$sWidgetItemTitle,
$this->nNull, //$sWidgetItemContent,
$aCoreValidation['widget_header_css_class'], //$sWidgetItemHeaderCssClass,
$aCoreValidation['widget_header_css_id'],
$aCoreValidation['show_widget_title_or_not'], //$sWidgetItemShowHeader,
$aCoreValidation['widget_body_css_class'], ///$sWidgetItemBodyCssClass,
$aCoreValidation['widget_body_css_id'], //$sWidgetItemBodyCssID,
$aCoreValidation['widget_status'], //$sWidgetItemStatus,
$aCoreValidation['widget_visi'], //$sWidgetItemVisi,
$aCoreValidation['widget_on_which_page'], //$sWidgetItemPages,
$sDateCurrent, //$sWidgetItemCreated,
serialize($aOptions), //$sWidgetItemOptions,
$this->iZero, //$iWidgetItemAuthor,
$sDateCurrent, //$sWidgetItemPublished,
$this->iZero, //$sWidgetItemPublisher,
$this->nNull //$sWidgetItemModified,
);
if($iResponse >= 1){ //inserting widget into database was successful.
//Feedback to show admin user who is creating the widget that the widget was created successfully
$_SESSION['feedback'] = '<div class = "alert alert-success"> Widget created successfully</div>';
//After processing the form, the page is redirected to this URL.
$sWidgetEditUrl = 'account.php?apage=new-widget-for-my-plugin&widget-id=' . $iResponse;
}
else{
//Feedback that the widget was not created
$_SESSION['feedback'] = '<div class = "alert alert-danger"> Failed to created Widget. Try again</div>';
}
}
else{ //Widget already exists and is being updated
//After processing the form, the page is redirected to this URL
$sWidgetEditUrl = 'account.php?apage=new-widget-for-my-plugin&widget-id=' . $iWidgetID;
//This function update_widget_item() return 1 if update was successful, null if no change was made and -1 if update failed
$iResponse = update_widget_item(
$sPluginAlias, //$sWidgetItemPluginAlias,
$aCoreValidation['widget_title'], //$sWidgetItemName,
$sWidgetEditUrl, //$sParamWidgetEditUrl,
$this->nNull, //$sWidgetIDescription,
$aCoreValidation['widget_position'], //$iWidgetItemPosition,
$aCoreValidation['widget_post_type'], //$sWidgetItemPostType,
$aCoreValidation['widget_space_id'], //$iWidgetItemAdSpaceID,
$aCoreValidation['widget_wrapper_css_class'],
$aCoreValidation['widget_wrapper_css_id'],
$aCoreValidation['widget_title'], //$sWidgetItemTitle,
$this->nNull, //$sWidgetItemContent,
$aCoreValidation['widget_header_css_class'],
$aCoreValidation['widget_header_css_id'],
$aCoreValidation['show_widget_title_or_not'], //$sWidgetItemShowHeader,
$aCoreValidation['widget_body_css_class'],
$aCoreValidation['widget_body_css_id'],
$aCoreValidation['widget_status'], //$sWidgetItemStatus,
$aCoreValidation['widget_visi'], //$sWidgetItemVisi,
$aCoreValidation['widget_on_which_page'], //$sWidgetItemPages,
serialize($aOptions), //$sWidgetItemOptions,
$this->nNull, //$sWidgetItemModified,
$iWidgetID
);
if($iResponse >= 1){ //Update was successful
//Feedback to show admin user that the update was successful
$_SESSION['feedback'] = '<div class = "alert alert-success"> Widget updated successfully</div>';
}
elseif($iResponse == null){
//Feedback to show admin user that no changes was made in the update.
$_SESSION['feedback'] = '<div class = "alert alert-info"> Widget is intact, no changes was made</div>';
}
else{
//Feeback to show admin user that the update failed.
$_SESSION['feedback'] = '<div class = "alert alert-danger"> Failed to update Widget. Try again</div>';
}
}
//Redirect the page to $sWidgetEditUrl
header('location:' . $sWidgetEditUrl);
}
}
}
//Method for outputing the form that will be used for creating the widget
//Also, the form will be populated with values from data base if the widget is being edited.
function widget_form(){
//Check to see if the string "new-widget-for-my-plugin" is present in the URL
if(isset($_GET['apage']) && $_GET['apage'] === 'new-widget-for-my-plugin'){
$sWidgetPostType = 'function';
//Get widget id from $_GET['widget-id'] if it is available
$iWidgetId = thefoj_get('widget_id');
//URL for form action attribute
$sActionUrl = 'account.php?apage=new-widget-for-my-plugin';
//Data of widget that has been saved in database
$aWidgetDataFromDatabase = [];
//If widget has an id, then it has been saved in database before
if(!empty($iWidgetId)){
//The $this->widget_item_by_id() method retrieves data of widget that has been saved in the database.
$aWidgetDataFromDatabase = $this->widget_item_by_id($iWidgetId, $sWidgetPostType);
}
if(!empty($aWidgetDataFromDatabase)){
//If widget has been saved in database before, then the form action attribute must have a URL that includes the widget id
$sActionUrl = 'account.php?apage=new-widget-for-my-plugin&widget-id=' . $iWidgetId;
}
?>
<!--Bootstrap is massively used in The FOJ so the the bootstrap class which is "col-12" must be used. The column length depends on you. "section-col" gives the page the min-height: 800px; and background: #fff; -->
<div class = "col-12 section-col">
<!--the class fsize-28 gives the h1 element font-size of 28px. It is from fsize-8 to fsize-72, that is 8px to 72px -->
<h1 class = "fsize-28">Widget Form</h1>
<hr />
<?php
//This method validates and saves the form inputs in database and gives feedback such as error or success feedback.
$this->process_widget_form();
?>
<?php
//In case there is error with the Widget post type whose attribute name is widget_post_type
echo $this->sWidgetPostTypeErr;
?>
<!-- The class "div-500-default" gives the form element max-width of 500px -->
<form class = "div-500-default" action = "<?php echo $sActionUrl;?>" method = "POST">
<?php
//This will output the core input elements of the form such as the title, widget_title, widget_position, show_widget_title_or_not, widget_style, widget_space_id, widget_status, widget_visi (Show to who?), widget_appears_on_which_page, selected_pages (IDs of selected pages),
echo $this->core_widget_creation_inputs($iWidgetId, $sWidgetPostType);
?>
<!-- The class "form-group" is a bootstrap class which adds margin-bottom to the div -->
<div class = "form-group">
<!-- The value of widget_post_type is always "function" as your plugin will be calling a method or function as a widget -->
<input type = "hidden" name = "widget_post_type" value = "function" />
<input type = "submit" name = "submit_widget_form" class = "btn btn-success float-right" value = "Submit" />
</div>
</form>
</div>
<?php
}
}
}
?>
write_a_paragraph()
of the class My_Plugin
of the file plugins/my_plugin/classes/My_Plugin.php
and it outputs the statement, "This is a paragraph". The widget displays whatever the method outputs.