Categories
Code How-To Web Design

Create a Checklist Plugin for TinyMCE

The TinyMCE editor is a very useful and easy to implement add-on to your web app. For the most part it is free to use and develop with and is licensed with the LGPL license, but some plugins for different editor functions are only available under their Premium Features offering.

If you think the premium plugins give you what you want and you are going to make money from your work, it’d probably make you feel good to buy one of their plans.

Anyway, if you do want to have a play around with TinyMCE plugins and create your own, it’s not that hard.

Firstly, you need to have a basic HTML web page created with an element to use as your editor. This can be a <div> or a <textarea>. Here’s an example HTML page with a simple form and a Textarea element we want to target. We have also included our script tag to load the TinyMCE Javascript library.

<!doctype html>
<html lang='en'>
<head></head>
<body>
<form>
<textarea id='myEditor'></textarea>
<input type='submit' name='submitForm' value='Send'>
</form>
</body>
<script type='text/javascript' src="./tinymce/tinymce.min.js"></script>
</html>

If you load that page in a browser you should see your basic web form, but not much else. We need to define the JS code to tell TinyMCE to attach itself to that Textarea element and provide a configuration.

Add the following to the bottom of your HTML (you could also put it in a separate file and include that script again) above the closing </html> tag.

<script type='text/javascript'>
tinymce.init({
    selector: '#myEditor',
    menubar: false,
    statusbar: false,
    toolbar: 'bold italic underline bullist numlist mychecklist link image code',
    plugins: 'mychecklist code link lists advlist image'
});
</script>

This JS code will define the HTML page element (the one with id=’myEditor’) that TinyMCE will use as the editor. It will also disable the menu bar and the status bar and add some buttons to the toolbar. We have plugins defined that match our buttons. Not all plugins need to have buttons, but in this case they do.

For the checklists plugin to work, it actually uses some of the features from the Lists plugin so we need to ensure we have that.

If you load your web page now, you should see it with the Textarea behaving as an editor panel with the buttons showing above it. Something like this.

So far, so good, you have a functional TinyMCE editor. Now we need to create the plugin to be able to use the checklists feature.

Create a new folder and file in the TinyMCE folder structure under <your_folder>/tinymce/plugins/mychecklist/plugin.min.js

Copy and paste the following code into that new file called plugin.min.js. If you have the developer version of TinyMCE you may need to rename that file to plugin.js. By default the behaviour of TinyMCE changes with the dev version loading unminised files and the production version loading the minified versions.

(function () {
    var mychecklist = (function () {
        'use strict';
        tinymce.PluginManager.add("mychecklist", function (editor, url) {

            /**
             * Plugin behaviour for when the Toolbar or Menu item is selected
             *
             * @private
             */
            function _onAction()
            {
                var content = `<ul class="tox-checklist">
                    <li class="tox-checklist--checked">Task</li>
                    </ul>`;

                editor.insertContent(content);
            }

            // Define the Toolbar button
            editor.ui.registry.addButton('mychecklist', {
                icon: 'checklist',
                tooltip: 'Insert check list',
                onAction: _onAction
            });

            editor.on( 'NodeChange', function ( event ) {
                var node = editor.selection.getNode();
                var parent = node.parentElement;
                if (parent.className === "tox-checklist") {
                    if ((node.nodeName === "LI") && (node.className === "tox-checklist--checked")) {
                        node.className = "";
                    } else if ((node.nodeName === "LI") && (node.className === "")) {
                        node.className = "tox-checklist--checked";
                    }
                }
            });

        });
    }());
})();

That’s a lot to take on in one go so lets break it down a bit.

We define a new TinyMCE plugin and give it a name “mychecklist”. We also pass in “editor” which is an object representing the editor component and content in the page.

The function _onAction is what gets called after we click on the toolbar button. In our example code it’s very simple and only creates a small snippet of HTML that defines a list with one item. Both the <ul> and the <li> have custom CSS classes applied and these are the TinyMCE assets that we’re really leveraging here.

We also create define the toolbar button which has a name that matches what we used in our editor definition at the bottom of the HTML file. It links the button to the _onAction function.

Then we have an editor.on() code block which helps us make the checkboxes toggle between empty and ticked. You may have noticed by now that this checkbox display is a bit of TinyMCE and CSS trickery. They aren’t actually HTML checkbox input elements, they’re just styled list items.

The NodeChange event being used is triggered whenever the user moves their input cursor around in the editor panel. It effectively makes the element it lands in the active element and allows this code block to carry out actions. In our case it is trying to identify that we’re active in one of our check list items. We do this by confirming the parent element is an <ul> with class of tox-checklist, then that the <li> is either showing the checked style or it’s empty and then toggles the class to the other value.

If you reload your web page now you should see the checklist icon in the toolbar of the editor and when you click on it, there will be a chunk of new text added into the editor. If you click on the list item check box or the text label the status of the checkbox will toggle.

Excellent we have a new UI item and function in our TinyMCE toolbar that’ll insert a list item that behaves like a checkbox.

If you want to save this editor content to a database, you’ll need to use the following CSS to render it as normal output in elements outside the TinyMCE editor. The check boxes are SVG images.

This CSS and toolbox icon for a checklist are included in the TinyMCE library by default even though it is obviously used in their premium plugin. We use the JS above to toggle that CSS on or off.

.tox-checklist>li:not(.tox-checklist--hidden) {
    list-style: none;
    margin: .25em 0;
}
.tox-checklist>li:not(.tox-checklist--hidden)::before {
    background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-unchecked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2215%22%20height%3D%2215%22%20x%3D%22.5%22%20y%3D%22.5%22%20fill-rule%3D%22nonzero%22%20stroke%3D%22%234C4C4C%22%20rx%3D%222%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A");
    background-size:100%;
    content:'';
    cursor:pointer;
    height:1em;
    margin-left:-1.5em;
    margin-top:.125em;
    position:absolute;
    width:1em;
}
.tox-checklist li:not(.tox-checklist--hidden).tox-checklist--checked::before {
    background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-checked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2216%22%20height%3D%2216%22%20fill%3D%22%234099FF%22%20fill-rule%3D%22nonzero%22%20rx%3D%222%22%2F%3E%3Cpath%20id%3D%22Path%22%20fill%3D%22%23FFF%22%20fill-rule%3D%22nonzero%22%20d%3D%22M11.5703186%2C3.14417309%20C11.8516238%2C2.73724603%2012.4164781%2C2.62829933%2012.83558%2C2.89774797%20C13.260121%2C3.17069355%2013.3759736%2C3.72932262%2013.0909105%2C4.14168582%20L7.7580587%2C11.8560195%20C7.43776896%2C12.3193404%206.76483983%2C12.3852142%206.35607322%2C11.9948725%20L3.02491697%2C8.8138662%20C2.66090143%2C8.46625845%202.65798871%2C7.89594698%203.01850234%2C7.54483354%20C3.373942%2C7.19866177%203.94940006%2C7.19592841%204.30829608%2C7.5386474%20L6.85276923%2C9.9684299%20L11.5703186%2C3.14417309%20Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A")
}

To take this a few steps further there are some tidy up actions needed. Consider these optional extras that I may write up at a later time.

  • Notice when the checklist item is selected, the wrong toolbar item is highlighted in the editor.
  • If you’re displaying the editor content as HTML outside the editor (i.e. you’ve saved it for display), you won’t be able to toggle the checkbox status.
Categories
How-To Web Design

Installing Google Firestore for PHP

Using the NoSQL database Firestore with PHP means you need to install a few tools to make it work. The alternative is to use the JavaScript option but when the Firestore access is put into the more secure mode then the backend option with PHP may be needed.

The Google docs point to installing the gRPC library for PHP via two options, either PECL or with Composer. But as with many technical docs, seem to miss a step or two that leaves the reader a little lost and probably frustrated. Hence I’ll step through what I did here with PECL for Ubuntu 18.04 in WSL on Windows 10. (BTW – I thorough recommend Windows Subsystem for Linux in Windows 10 for web development; it’s a good middle ground of dev tools and productivity experience. Grab the new Windows Terminal app to get that easy terminal access to the WSL instance too.)

First, go and have a read through the docs from Google linked above. It’ll give you the view of what needs doing, and hey, maybe it will work for your environment. Otherwise I’ll describe the steps below that I needed to go through.

NOTE – Where you see a PHP version in a command, make sure you use your current version to get the right framework version.

sudo apt-get update
sudo apt install php7.2-dev autoconf libz-dev php-pear
sudo pecl install grpc

The PECL install step will likely take a few minutes while it goes back to basics and compiles the gRPC module. Lots of information will scroll up the terminal window.

After PECL has completed and successfully created the grpc.so, you’ll need to follow the instructions in the PECL output and update the php.ini config to ensure the module will be loaded.

After you have edited your php.ini file, reload your web server to ensure new processes are loaded. Use of Apache is assumed with the commands below.

sudo nano /etc/php/7.2/apache2/php.ini
sudo service apache2 restart

Now you should have everything compiled and loaded as expected. If you have a test file that’ll dump out your PHP config, load that and search for “grpc”. If you don’t have a file that’ll do that, I’d suggest you create one in a dev environment to help out with the server config. All you need is the following line in a PHP script file in your web server directory.

<?php
echo phpinfo();
?>

Loading that file in your browser should then show us that config section we’re after.

We’re done! Hopefully that worked for you or at least provided some useful information.

Categories
Code Web Apps Web Design

Doc5 Beta Now in Testing

After many years I have got a version of Doc5 up and available to use. It’s a vastly different wiki app than the previous version and most of the changes have been made in the last 9 months. The last version released for download was a different name and appeared before my son was born. He starts school in two weeks.

My 9-5 job takes up enough time that for a couple of years I left this project¬†alone and considered dropping any¬†thoughts of pushing it out. But writing web apps is my hobby, so it’s been good to dig through all the old code and clean it up.

So a list of the major changes:

  • WYSIWYG editing has arrived and the previous wiki engine is gone
  • Permissions have been simplified but also extended to categories
  • Full UI make over, although I have gone with a pretty basic Bootstrap view of things.
  • Better file uploads and management.
  • Templates for email notifications

I think a full release should be available for download in the next two months. Testing on the web will help tune spam catching and there’s some bug fixing to roll out as well as plenty of test cases to run.

Categories
Web Design

All the Web2.0 You Can Handle

Read/Write Web has a list of . . . lists. All containing information about Web2.0 sites springing up like daisies around the internet.

What’s a Web2.0 site you ask? It’s one of those good-looking, fancy acting websites you’ve probably seen around. The developer of these sites use more acronyms than before, like AJAX, JSON, etc that allow users to interact in ways they couldn’t a couple of years ago. Some of these sites are so cool they drop vowels from their names – Flickr and HappyCodr are a couple of examples.

Overall they still need content and community but some of them are just beautiful to look at and fun to play with.

Categories
Code Web Design

Why Aren’t You Using FireBug?

I’ve been using the Firefox browser addon called FireBug for a while now and am amazed at how helpful it is. If you’re a web developer, and especially if you use JavaScript and AJAX methods, you should be using it.

For example, while developing I like to add in timers to PHP based pages to show how long things are taking. This way if a SQL statement needs some fine-tuning or a change slows things down I can see it happen. FireBug extends this to the entire page and the HTTP traffic. Here’s what happens when I load a page that has a few JavaScript calls, small images and a single CSS link in it,

Straight away it’s obvious what’s taking up the bulk of the time – those two library calls. Once I take those out of the equation the load time drops to under a second. And through all this the PHP timer function only shows me how long the server-side work is taking.

With FireBug I know who (in a geeky code way) is doing what and with who and I can act on it. Now that’s helpful.

Categories
Web Design

Securing Apache

Twenty ways to make sure that the 10 year old script kiddie down the street does not mess with your Apache Web Server.

Peter Freitag – 20 ways to Secure your Apache Configuration

Categories
Web Design

The Big Book of CSS Tabs and Navigation

Well OK it’s not a book but have a look at Vitaly Friedman’s CSS Showcase for a whole lot of CSS navigation examples and how to do it right.

Personally I’m a fan of the the usability compliant Mozilla entry and Veerle’s for sheer beauty.

veerle.duoh.com