TinyMce picture tag wrapper - tinymce

In out CMS we put every image inside "picture" tag like this:
<picture>
<source srcset="image.webp" type="image/webp"> <img class="_img_resp"
src="image.jpe" alt="Image">
</picture>
But tiny wraps every picture tag inside "p"
I see that some tags like: "ul", "div", "h2" are wrappers itself without additional "p"
So, can i made "picture" tag a new custom wrapper?
I dont need deleting root "p" tag from all content
I use tinymcy 5.10

Ok, i solved it with this
custom_elements: 'picture',
valid_children: 'picture[source|img]',
formats: {
'custom_picture': {block: 'picture', selector: 'picture', merge_siblings: true, wrapper: true},
}
Not clear, but it works

Related

Configure the user's default choice on tinyMCE toolbar

I am using v5 of TinyMCE. By default, the style selected is 'Paragraph', as shown in this image :
[tinyMCE toolbar, as the user sees before he mades any format configuration]
But I know my users will all prefer to use 'Div' style. So I would like 'Div' to be selected by default. The toolbar should therefore appear like in this image :
[tinyMCE toolbar, as I want it to be configured by default]
Is it possible ?
I haven't find my answer in tinyMCE documentation.
Same question if you want for instead "bold" button to be selected by default, etc.
Thank you !
To replace the default <p> blocks with <div>, use forced_root_block: https://www.tiny.cloud/docs-3x/reference/Configuration3x/Configuration3x#forced_root_block/
tinymce.init({
// ...
forced_root_block : 'div'
});
To select the bold button by default, you could use execCommand: https://www.tiny.cloud/docs/api/tinymce/tinymce.editor/#execcommand
tinymce.init({
// ...
setup: function(editor) {
editor.on('init', function() {
this.execCommand('Bold');
});
}
});
Example fiddle combining both: https://fiddle.tiny.cloud/YShaab/1

How to add "rel = nofollow" to all "a" tags?

I want to add "rel = nofollow" to all "a" tags.
tinymce.init({
selector: 'textarea',
extended_valid_elements: 'img[!src|alt],a[!href|target|width|height|title|rel=nofollow]',
valid_elements : 'p,br,a,strong,span[style],em,ul,ol,li',
});
Using the code you included above, I get the behavior you are looking for, a rel="nofollow" is added to <a> tags. Here is a Tiny Fiddle demonstration:
http://fiddle.tinymce.com/Wthaab
Do you get different results in that Fiddle?

Dynamically set fancybox 3 iframe size

When dealing with dynamically sizing the iframe in fancybox, I accidentally found that setting data-width and data-height on the [data-fancybox] is helpful after reading this answer.
Exmaple HTML element:
<a data-fancybox data-width="<?= $banner_width; ?>" data-height="<?= $banner_height; ?>" data-src="example.com" href="javascript:;">example.com</a>
and js:
$("[data-fancybox]").fancybox({
afterLoad: function ( instance, slide ) {
$('body').find('.fancybox-content').css({"width": slide.opts.width + "px", "height": slide.opts.height + "px"});
}
});
What I couldn't figure out is that there is no explanation of data-width and data-height usage on HTML element from fancybox documentation (please correct me if I'm wrong).
NOTE: these two code snippets above do work for me, but they have to work together, it wouldn't work if one of them is taken off.
Can anyone explain that a little bit for me please?
Based on fancybox 3 documentation, they do offer a way to set our own custom options by creating data-options attribute. Here is the example from the documentation:
<a data-fancybox
data-options='{"caption" : "My caption", "src : "iframe.html"}' href="javascript:;">
Open external page using iframe
</a>
You can see the value of these options by console.info( slide.opts ) from the callback function like onComplete (slide is one argument in the callback function ).
Not surprisingly, these two snippets are the same:
<a data-fancybox data-width="<?= $banner_width; ?>" data-height="<?= $banner_height; ?>" data-src="example.com" href="javascript:;">example.com</a>
<a data-fancybox data-options='{"width" : "<?= $banner_width; ?>", "height" : data-height="<?= $banner_height; ?>", "src" : "example.com" }' href="javascript:;">example.com</a>
So, in my javascript, I use slide.opts.width to get the value from data-width and slide.opts.heightto get the height from data-height, that is how my width and height value get passed from backend to frontend.
Since these two values are processed in afterLoad callback, so every iframe will be initiated with different width and height.
Properties - data-width and data-height - are used to tell the script real dimension of the image. The script then can calculate position and start zooming thumbnail while real image is still loading.
See documentation - http://fancyapps.com/fancybox/3/docs/#images
These properties are not used anywhere else.
You can use { iframe : { css : { width: '', height : '' } } } to set iframe element width/height, but there is no option to change iframe content.

How to disabled wysihtml5 HTML Clean Up in Editor?

How to disable HTML Clean Up while in the editor mode? I'm in a need of allowing css format & inline html in code. The idea is to disable parser and html clean up action when pasting the code and entering the Editor for editing. Thanks.
You can provide an identity function as the parser attribute upon initializing the wysihtml5 editor. The below script is a coffeescript snippet that disables the cleanup completely.
enableWysiwyg: ->
#$el.find('textarea').wysihtml5
"style": false
"font-styles": false #Font styling, e.g. h1, h2, etc. Default true
"emphasis": true #Italics, bold, etc. Default true
"lists": false #(Un)ordered lists, e.g. Bullets, Numbers. Default true
"html": true #Button which allows you to edit the generated HTML. Default false
"link": false #Button to insert a link. Default true
"image": false #Button to insert an image. Default true,
"color": false #Button to change color of font
parser: (html) -> html
JavaScript version of the above code:
$('textarea').wysihtml5({
"style": false,
"font-styles": false,
"emphasis": true,
"lists": false,
"html": true,
"link": false,
"image": false,
"color": false,
parser: function(html) {
return html;
}
});
Actually, this is what the parser rules are for.
You can attach your custom rules to the included var wysihtml5ParserRules before instantiate the editor object or just create your own rules object and give to the editor's constructor.
For example, to allow the h1 and h3 tag in addition to the tags allowed in the distributed simple example rules, you'd need to set up as follows:
<form>
<div id="toolbar" style="display: none;">
<a data-wysihtml5-command="bold" title="CTRL+B">bold</a> |
<a data-wysihtml5-command="italic" title="CTRL+I">italic</a>
<a data-wysihtml5-action="change_view">switch to html view</a>
</div>
<textarea id="textarea" placeholder="Enter text ..."></textarea>
<br><input type="reset" value="Reset form!">
</form>
<!-- The distributed parser rules -->
<script src="../parser_rules/simple.js"></script>
<script src="../dist/wysihtml5-0.4.0pre.min.js"></script>
<script>
// attach some custom rules
wysihtml5ParserRules.tags.h1 = {remove: 0};
wysihtml5ParserRules.tags.h3 = {remove: 0};
var editor = new wysihtml5.Editor("textarea", {
toolbar: "toolbar",
parserRules: wysihtml5ParserRules,
useLineBreaks: false
});
</script>
Now, when you enter/paste <title>test</title> into the editor, while you're in the editor mode, and then switch to html view, you'll get <title>test</title>. And when you switch back to editor view, you'll get <title>test</title> again.
That was the general part.
Now, in your case, I'm not sure if it's the best idea to work with 121 custom parser rules (the count of HTML tags to handle) or if it wouldn't be better to take the time and dig into the source code to find a more performant solution (doesn't make much sense to tell a parser to actualy just return the input string anyway, right?). Furthermore, you said you want to allow CSS as well. So your custom parser rules will even extend.
Anyway, as a starting point, feel free to use my custom parser rule set from here: https://github.com/eyecatchup/wysihtml5/blob/master/parser_rules/allow-all-html5.js.

tiny mce can't be inited when load js dynamically

i am having trouble with tinyMCE, when i put <script type="text/javascript" src="/scripts/tiny_mce/tiny_mce.js"> to <head>, and put init code before the <textarea class="tinyMceEditor">, it works fine.
the init code is like this:
tinyMCE.init({
mode : "specific_textareas",
editor_selector : "tinyMceEditor",
plugins : "inlinepopups,advlink",
convert_urls : false,
theme : "advanced",
theme_advanced_buttons1 : "link,unlink",
width: "602",
height: "175",
theme_advanced_statusbar_location : "none"});
But now, i want to defer the loading of tiny_mce.js, when user click a button on the first time, the tiny_mce.js will be loaded, and then append the <textarea class="tinyMceEditor"> to <body>, then do the init work with the previous code, but this time, it won't init the tinyMCE editor, it only shows the <textarea class="tinyMceEditor">
googled, but find nothing related to this, anyone has met this problem?
Any suggestion will be appreciated.
i looked into chrome web developer tools and found that if i dynamically load the tinymce.js, other js needed like en.js, editor_template.js, editor_plugin.js etc won't be loaded. even when i add these js files to dynamically loading, the tinymce still can't be inited.
thank you for your help, i watched in firebug, and i do get the tinymce.js loaded before append <textarea to <body>, then i append the <textarea>, and do the tinymce init(), i am using LazyLoad(jQuery plugin) to dynamically load the js files.
here is what i did
if(typeof TinyMCE == "undefined"){
//dynamically load the tinymce.js
LazyLoad(['tinymce.js'],function(){
//callback function, called after tinymce is loaded
$('body').append('<textarea class="TinyMceEditor"/>');
tinyMCE.init({init settings});
});
}
if i don't load tinymce.js dynamically, just put a <script> tag in <head>, the tinyMCE can be inited , but when i load tinymce.js dynamically, it doesn't work. Any idea with this?
after a day's work, finally found the solution, just put
window.tinymce.dom.Event.domLoaded = true;
before
tinymce.init();
then the tinymce can be inited correctly.
I resolved this issue by creating a separate coffee script file. Then I declared below function with window scope to access in views.
window.initialize_tiny_mce = () ->
if (typeof tinymce != 'undefined' && tinymce != null)
tinymce.remove();
tinymce.init
height: '180'
menubar: false
statusbar: false
cleanup: true
selector: '.new-tinymce-printable-html'
plugins: [ 'autolink link image code lists advlist' ]
toolbar: 'styleselect | bold underline italic | bullist numlist outdent indent | link image | code'
browser_spellcheck: true
setup: (editor) ->
editor.on 'keyup', ->
tinymce.triggerSave()
editor.on 'change', ->
console.log editor.getContent()
return
return
Then in view partial, I called this function:
:coffeescript
initialize_tiny_mce()
Now dynamically created element is assigned a tinymce editor.