June, 2009

jQuery WYSIWYG Editors - jwysiwyg is my pony

Posted 14 Years Ago

FCKEditor, You're so Big

For the last year or two I've been using FCKEditor for my custom content management systems.  It does what it needs to do and does it better than any other WYSIWYG editor I've seen.  For newbies out there, a WYSIWYG Editor is a 'What You See Is What You Get' editor.  It allows users to create HTML content without having to know any HTML.  In fact, this blog post right now is being written with the use of the FCKEditor WYSIWYG.

Anyway, there are a few things I don't like about FCKEditor.

  • Speed - It takes a rather long time to load on the page.
  • Installation - It's really easy to install it after you've done it once or twice, but uploading the thousands of files you need is a bit cumbersome.
  • Plugins - To be fair I havne't tried very hard to create a plugin for it, but it seems like there's a bit of a learning curve for writing the plugins.
  • Touchy - The Unorder List I'm typing here is giving me all sorts of trouble.  I can deal with it, most clients get driven crazy by it.

Typing this article on (a slimmed down) FCKEDitor

The jQuery Alternatives

So, the other day I looked around for something better, specifically a jQuery WYSIWYG because that's my soup d'jour.  I discovered there are basically two editors out there:

1. WYMeditor - Doesn't advertise itself as jQuery, but I'm pretty sure it is.  However, it confuses me.  I don't get why it shows me 'p' tags, etc.

2. jWSIWYG Editor - Apparently based off the WYMEditor, but much better in my opinion.  Super small size, efficient, pretty, does basic things very well.  However, it's not very robust and the documentation is non-existant.

...oh, wait, just found a third:

3. HTMLBox- Only just found this.  Looks like it's more robust than the others, but kind of ugly.  I'll have to play around with it more.


So far I'm putting my money on jWYSIWYG. It's already a staple of my code base and I'm very happy with it.  It's perfect for basic editing (forum posts, comments, about me, etc.) and at only 4KB it's the smallest WYSIWYG editor I've ever seen.  Plus, it seems to do things so much better.  It responds quickly to your actions and does what you want it to do. 

Of course, the reason it's does things so nicely right now is because it doesn't do much.  Here's a full list of features:

  • Bold
  • Italic
  • Strike Through
  • Underline
  • Jstify Left
  • Justify Center
  • Justify Right
  • Justify Full
  • Indent
  • Outdent
  • Subscript
  • Superscript
  • Undo
  • Redo
  • Insert Ordered List
  • Insert Unordered List
  • Insert Horizontal Rule
  • H1
  • H2
  • H3
  • H4
  • H5
  • H6
  • Cut
  • Copy
  • Paste
  • Increase Font Size
  • Decrease Font Size
  • Create Link -

    Dialog box pops up with field for the link URL

  • Insert Image -

    Dialog box pops up with a field for the Image URL

  • Html -

    A view of the HTML Source code for the WYSIWYG Editor

  • Remove Format

Looking at it now, it's a pretty good list and--as I said--it works perfectly well for most small text formatting.  Indeed, as developers we often want to restrict what users have the ability to do.  But, there are some key things missing; some things which are required if it's ever going to be capable of being integrated into a Content Management System

  • Image Uploading
  • Tables
  • Flash 
  • Text Color
  • Font Family
  • CSS Styles

Alright, well that's all I can think of at the moment, but I'm sure there's more things it needs.  Anyway, the point is I'm going to be playing around with it in the next few weeks, starting with the 'Image Uploading' capability.  I'll let you know what I come up with.

MySQL Bits - Large MySQL Database Backup

Posted 14 Years Ago

The Problem

One of the sites I own (http://www.writerscafe.org/) has managed to attrace a good number of users and user created content.  This, of course, is a grand old thing and what we all strive for.  But when you're site starts getting large new and more complex problems arise which don't have such easy solutions. 

One such problem I faced was backing up a large database (almost 9GB).  I tried the basic methods first (MySQL Dump, GUI MySQL Backup Programs, MySQL Hot Backup, etc.), but none of them did exactly what I wanted.  What's more, all of them inevitably locked up important MySQL tables for an unacceptable period of time.  For example, the table which stored all the private messages has almost 4 million rows and weighs in at a good 5.8 GB. 

The Solution

The solution I came up with was to write a script which loops through the database, backing up rows in chunks, then saving them to a file, and looping through again.  This meant that instead SELECTing all 4 million rows at once, I was only grabbing 10,000, which is a much shorter query to run. 

It may also breaks the backup into several files.  After playing around with the script a little, I discovered that you could not create a backup file that's over 2GB.  The reason is that PHP's fopen function can't handle more than 2GB (unless you do some server stuff which isn't worth the trouble).  So the script will also (in theory) break up the backup into files of 2GB (or whatever size you set) if the database exceeds that size.

Then, when it's done creating the backup up, it creates nice little .gz files so it's easier to download.

I've named this little script MySQL Bits because it backs up the database in bits (I was going to go with 'Chunks' but the name didn't sound quite so appealing).  Below is a link to the backup.php file which handles the backup:

MySQL Bits - Large MySQL Database Backup

Example of Script Output

Basic Configuration

The script should be all ready to go.  The only thing you HAVE to edit is the MySQL database connection and the folder you'd like to save the backup(s) to.  Here's what that code looks like:

// MySQL Variables
define('MY_S','localhost'); // Server (usually 'localhost')
define('MY_D','charles_website'); // Database Name
define('MY_U','database_username'); // Username
define('MY_P','database_password'); // Password

// Relative Folder to Save To
$path = "backups/";

Should be simple enough (I 'defined' my MySQL variables because it makes them easier to use in functions).  The $path variale is a relative path to the backup script.  In the example script I simply created a backups/ folder and saved the backups there.  Note: you must change the permissons on this folder to 0777.

Advanced Configuration

Of course, I know we all like to have control over our scripts so there are a few other options you can play around with:


Rows Per Loop
This is the number of rows each loop with select from the database before updating the .sql file.  If a table has less than the $pp value it will continue onto the next table until is reaches $pp.  If a table has more than the $pp value, it will select that many rows, add it to the .sql file, then continue on where it left off.

Default = 10000
 $max_file_size Max File Size (in bytes)
As I mentioned, PHP's fopen function can't handle more than 2GB so I've set the default (2000000000 bytes) to slightly below 2GB (2147483647 bytes).  You can change this if you want to be able to download smaller backup files.

Default = 2000000000
 $name File Name
The fomat of the Backup's filename.  I recommend using some sort of date format.  You should NOT include .sql in the file name.
Note: the filename is appended with _x.sql to accomodate backups which are split into multiple files.

Default = MM-DD-YYYY_Timestamp
 $life Backup Life (in days)
This is the number of days you want to keep this backup on your server.  The backup will be deleted after this many days.  The default is 30 so, if you we're running a weekly backup you'd have approximately 4 backups on your server at all times.

Default = 30
max_execution_time / mysql.connect_timeout / set_time_limit PHP Timeout (in seconds)
We don't want our script running out before it's completed (my backups can take a couple of hours) so we up the server's timeout settings.  Note: these may not work on all servers because of your permissions.

Default = 7200 (2 days)

The Limitations

There are a few problems I've encountered with the script.  I'm going to keep working on it, and feel free to offer advice.

2GB Limit
The multi-file part of the script works, I've tested it with a max_file_size of 50000000 (about 47 MB) and it works fine.  However, whenever it's backed up about 2GB worth of data (into one or many files) it craps out.  This is because the fopen() function can't handle more than 2 GB. 

I've worked around it by setting up a cron to run daily.  On Sunday it starts to backup (storing the progress in the db) and each day after that it picks up where it crapped out the day before. 

SELECTing End of Large Tables
When selecting the ends of a large table (SELECT * FROM .... ORDER BY LIMIT 10000000,10000) it runs rather slowly.  The script uses the Primary Key to SELECT rows where it can, but that's also slow (SELECT * FROM .... WHERE primary_key > 10000000 AND primary_key <= 10010000 ORDER BY primary_key ASC).

I think this is more of a MySQL / Server bottleneck issue and I haven't found anyone who has a possible solution except tweaking the server's my.cnf file.


Well, that's about it.  I'm sure there's some bugs so you'll have to let me know if you find any.  Also, let me know if you have any suggestions.