@sottwell Sounds interesting. Details?
Here we go, I hope this helps someone, and isn't too lengthy.
My aim is to:
- use third party plugins and not have to touch their core in any way, in fact I don't even want to know where their core files are (really!?!)
This helps when I wish to update. I also want these fellows to integrate with MODx (permissions and all).
- achieve something like medium.com's writing pad, but in my opinion not so overly minimalistic, yet clean and powerful.
TinyMCE 4 can be customized in such a way that the code it outputs is exactly what you want. This helps when your users copy and paste from Word or other illogical html spitting software, or when they want to do strange things like putting a DIV in a LINK tag.
I chose TinyMCE over the other wonderful CKEditor because its ease of customization is terrific. CKEditor wins in the area of
magicline though. And I did not go with Markdown, because, let's face it... the thing is Greek to many innocent users.
@BobRay Personally, I've written in straight HTML for so long now that working in a WYSISWYG editor gives me the creeps.
I absolutely agree with you. My first deal with MODx was to install the rich editors, and code editors, played with them, and promptly deleted all of them. They are the best and most cunning destroyers on the planet. That said, for writing in a blog, using fixed patterns of presentation, I think it can work.
Some Key strengths here are: apart from being able to disable just about anything, or easily write a plugin
<script src="/assets/tinymceEditor/tinymce.min.js"></script>
tinymce.init({
selector: "textarea#np-content",
//NewsPublisher already checks the permission of who can create or save or edit what, so TinyMCE has
//nothing to worry about, it just grabs the textarea that NewsPublisher gives it
browser_spellcheck: true,
//no need for useless or expensive spell-checking plugins
valid_elements: "audio[*],-span[!title|!class<shakestip yhighlight],a[!href|target|class|rel|title],strong/b,-div[!class<sonnet],-p[class<text-align-left?text-align-center?text-align-right],br,-h1[class],-h2[class],-h3[class],-img[!src|!alt|!class=round_img],em,-blockquote,-pre[!class=prettyprint linenums],-ol,-ul,-li,-code",
//forbid any element you want, !force some to have this or that attribute, -remove empty tags
valid_children: "-li[ul],-li[ol],-li[div],-strong[*],-em[*],-h1[*],-h2[*],-h3[*],-a[strong|em|h1|h2|h3|p|div],blockquote[p]",
content_css: "prettify.css,/assets/tiny.css",
//custom CSS lets the fonts and CSS in the pad be the same on your site - a kind of preview
contextmenu: "articleProperties | preview | charmap | formats removeformat | link | image responsivefilemanager | searchreplace | code",
//put stuff in the right-click menu
setup: function(ed) {
//allows you to add buttons and menus to the toolbar
ed.addButton("saveAs", {
type: "menubutton",
text: "Save As...",
title: "Ready to publish or not?",
icon: "save",
menu: [ {
text: "1. Article Title",
icon: "newdocument",
onclick: function() {
$.dynamicTitle();
//you may go crazy with this onClick event
//use it to submit or cancel the form, do jQuery stuff, cook your soup
}
}, /
tinyMCE.activeEditor.windowManager.alert("Not applicable here!");
//TinyM has its own sweet alert, modal windows, etc
style_formats: [ {
title: "Sonnet Paragraph",
block: "div",
classes: "sonnet"
}, {
title: "simpleGallery",
selector: "a",
classes: "simpleGallery"
},{
title: "Highlight Verse",
inline: "span",
classes: "shakestip yhighlight
}
]
//custom styles ...allow users to use predefined CSS styles which affect only this or that element.
To save an article as DRAFT create the draft button in TinyMCE, link it to this function onclick : $.drafton()
jQuery.drafton = function() {
// if ($("#pub_date").length > 0) { checks if NewsPublisher shows this field
tinyMCE.activeEditor.windowManager.confirm("Your Article will be marked as Draft, and Unpublished. Sure?", function(s) {
if (s) { //if ok is clicked do below
$("#pub_date").val("2019-09-09");
//chases the pub date into the furture
$("#pub_date_time").val("20:20:20");
//for weird consistency sake
$(".author").prepend('<a href="javascript:$.draftoff();" title="remove draft status" class="draft eta">Marked as Draft (→ unmark)
</a>');
//a link to remove draft status
} else {} //if cancel is clicked do nothing
});
// } else {
tinyMCE.activeEditor.windowManager.alert("Not applicable here");
// }
};
To remove draft status, and get ready to publish
jQuery.draftoff = function() {
var pubDate = new Date();
var y = pubDate.getFullYear();
var m = ("0" + (pubDate.getMonth() + 1)).slice(-2);
//javascript starts January as 0, Feb as 1 - weird I know - so prepend zero, and add 1, but Oct-Dec(10-12) becomes ... oh dear, hence the splice
//I used php date snippet when I had this script within MODx..but not anymore
var d = pubDate.getDate();
tinyMCE.activeEditor.windowManager.confirm("Remove Draft status and get ready to publish?", function(s) {
if (s) { //if okay is clicked, reset pub date field to current field
$("#pub_date").val(y + "-" + m + "-" + d);
$("#pub_date_time").val("00:00");
$(".draft").remove(); //remove draft status notification
} else {} //if cancel is clicked, do nothing
});
};
Responsive Filemanager is a standalone wonder. That means you can use it with your other MODx projects. It so happens that the author made a TinyMCE plugin for it so that you can insert images and other media into your writing. It gives you one
config.php file that you can devour mercilessly.
This Filemanager has some serious edges as options.
Create thumbnails in (thumbs folder) on upload
Max size and max number upload, re-size to meet requirements
Allow/prohibit media file extensions
Ajax multiple upload, drag and drop etc...
And editing your images on the fly through AVIARY, which I think is superb. I am lazy sometimes to pull out GIMP or whatnot.
To MODxize this Add-on I did:
<?php
if (!defined('MODX_CORE_PATH')) {
define('MODX_CORE_PATH', '/ourmodx/core/');
}
if (!defined('MODX_CONFIG_KEY')) {
define('MODX_CONFIG_KEY', 'config');
}
require_once( MODX_CORE_PATH . 'model/modx/modx.class.php');
$modx = new modx();
$modx->initialize('web');
$modxId = $modx->user->get('id');
$myUsername = $modx->user->get('username');
if ($modx->user->isMember('Shakespeare-Writers') ) {
} else {
{header( 'Location: http://www.tobeOrnottobe.com' ) ;}
}
//This config file can be used to protect Responsive Filemanager files and folder and whatnot.
//all members without the status of writer will have to go away
// if ($modxId == 1 || $modxId == 196 || $modxId == 60)
//I want some individuals to share a folder - you can make it a group
if ($modxId == 1)
{$personalFolder = "leo";}
else
{$personalFolder = $modx->user->get('username');}
//I want the qualified user to have his own folder
mb_internal_encoding('UTF-8');
$leoConfig = '../media/config.txt'; //my permissions template
$newConfig = '../media/' . $personalFolder . '/config.php';
if (!file_exists('../media/' . $personalFolder)) {
mkdir('../media/' . $personalFolder, 0755, true);
}
if (!file_exists('../media/' . $personalFolder . '/mp3')) {
mkdir('../media/' . $personalFolder . '/mp3', 0755, true);
}
if (!file_exists('../media/' . $personalFolder . '/pictures')) {
mkdir('../media/' . $personalFolder . '/pictures', 0755, true);
}
if (!file_exists('../media/' . $personalFolder . '/config.php')) {
copy($leoConfig, $newConfig);
}
//it so happens you can further specify what each user can do in Filemanager
//$create_folders=true;
//$delete_files=true;
//$delete_folders=true;
//$upload_files=true;
//$rename_files=true;
//$rename_folders=true;
//$duplicate_files=true;
//So I have a template of these permissions in config.txt
//and I want this copied to each fellow's folder on creation, config.php that is.
//you can have different templates (config.txt) for different MODx user groups
Colorbox has crept into my bosom just recently. I am not sure how the other plugins out there treat inline content, but I say Colorbox does it deliciously.
NewsPublisher wraps all the input and textarea fields in divs thus providing with an ample number of #ids and .class names to mess around with.
AIM: I don't want to use NewsPublisher's Tabs system, nor do I want to see the Page title input, or alias, or anything for that matter, apart from the content textarea which TinyMCE has adopted as its own. You can even create buttons to Pagetitle, intortext etc right in TinyMCE; just link these to the corresponding Colorbox inline id.
npTextAreaTpl
npTextTpl
npDateTpl ...
The chunks that NewsPublisher gives you, in your duplicate, add a few things...np-Colorbox and title (when you are asked, is it legal to add title attribute to DIV, say yes)
<input title="[[+npx.caption]]" class="text np-Colorbox" placeholder="[[+npx.caption]]" title="[[+npx.caption]]"...
<textarea title="[[+npx.caption]]" class="[[+npx.class]] np-Colorbox" placeholder="[[+npx.caption]]" title="[[+npx.caption]]"...
To prevent the Submit and Cancel buttons of NewsPublisher and the parents of all your colorbox elements from showing up, use JavaScript or CSS to hide them. I prefer CSS here, although JavaScript ca be dynamic.
#tagsContainer,#dateContainer,#np-pagetitle-container,#np-alias-container,#np-youtubeID-container,.buttons,#np-introtext-container,.fixed-bar{display:none!important}
var grabColorbox = "<div><div id='colorboxGuidelines'><b>Click or use keyboard left/right arrow keys to cycle through</b>";
//<div><div id='colorboxGuidelines'> we are going to hide the parent soon...
var fileProperties, el, title, href;
// $(".np-Colorbox:not(#np-content, #np-pub_date-container, #np-alias, #np-pagetitle, #np-introtext)")
// $(".np-Colorbox:not(#np-content)")
//dynamically grab all the elements that NewsPublisher has spat out, except the content textarea which now belongs to TinyMCE. Do what you want
$(".np-Colorbox:not(#np-content, #np-alias, #np-pub_date-container)").each(function() {
el = $(this);
title = el.attr("title");
href = "#" + el.attr("id");
fileProperties = "<a class='inline' title='" + title + "' href='" + href + "'>" + title + "</a>";
//I am creating a link to each element for my Colorbox Inline stuff.
grabColorbox += fileProperties;
});
grabColorbox += "</div></div>";
grabColorboxMCE = {
text: title,
icon: "checkbox",
onclick: function() {
$.colorbox({
title: title,
href: href,
rel: "group1"
});
}
}, $("article").append(grabColorbox);
$("#colorboxGuidelines").parent().hide();
//don't want this to show up on the page, Colorbox is concerned with the child not the parent
Okay this post is too long, and it shall to the barbers with my beard if I don't stop here.
Enjoy!
Somebody should come out with a better route.