Can Posted June 5, 2016 Share Posted June 5, 2016 (edited) Hola amigos I wrote a little DOMDocument magic (long time ago) which would automatically link images add classes for Magnific Popup set alt tag wrap the whole thing in a figure insert figcaption if image description available and wrap multiple figures in a container think that's it.. So for our articles we only needed to open pwimage popup in cke, choose desired image, set the size and alignment To caption images we use description input from image field It was a nice starting point, and at some point I changed DOMDocument to SmartDOMDocument wrapped the code into TextformatterBlogImages.module.. But I had ideas to simplify the whole process..and due to a problem with the old implementation which broke design (just realised it a week ago, or that it's linked to my Textformatter) I finally took the time and rewrote the whole thing. Problem was that figure is not a valid child of <p> so at least in chrome I ended up with orphaned text and an empty paragraph so the text style differed from the rest.. I'm posting this as a boilerplate/resource/idea, it's really basic..everything is hardcoded and it's not flexible right now.. So there is the Textformatter module and a hook which is placed in my /site/ready.php right now but might be moved somewhere else.. Maybe it can become a proper module..Maybe I find time to do so..but if someone is interested everyone is welcome to grab the code and extend/modify for their own needs Here's a little animated gif screencast (it's shrinked so the quality is not very beautiful..) So what it does right now: TextformatterBlogImages.module: first it replaces double line breaks like <br><br> or <br /><br /> or any other combination with </p><p> (I had such occurences) parses the article for <p> tags using simple_html_dom finds all containing images it extracts the image name stripping image variations gets the corresponding pageimage from images field the image itself will be replaced by markup used with LazySizes JS plugin (https://github.com/aFarkas/lazysizes) Example: <img src="fullImageUrl" srcset="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-srcset="smallUrl smallWidth, medium mediumWidth, full fullWidth" data-sizes="auto" width="fullImageWidth"> data-sizes="auto" works for now but I might replace it by normal sizes markup, manually deciding how images should be chosen width="fullWidth" I read that images with width attribute render faster but I'm not sure if this is true even if the image is downsized by css? then the new image will be linked to full size image link with markup for js modal (wrote my own, but not ready yet) if image class contains "align_left" or "align_right" it will wrap it in span moving classes from img to span if pageimage got a description it'll insert the descr below the img within span in another span the old image will just be replaced by the new span image so it will be in the same place it image is not aligned (or align_center) it wraps the image in figure moving img classes to figure and description will be wrapped in figcaption and the figure will be stuffed in an own container before the paragraph (original image within p will be removed) The figure gets a class landscape or portrait according to the aspect ratio Uh, I added another hook property called Pageimage::cdn so the images will be served directly from assets subdomain (using domain sharding option from AIOM but saving the extra redirect) Then there is another "round" reparsing the article for newly created figure containers adding additional class containing the number of children and another class indicating how many of the images are landscape/portrait for later styling like 2lx1p for 2 landscape and 1 portrait We add rows of 1 to 4 images, not more so my stylesheet contains rules for all possible cases like 1 landscape 2 portraits, 3 landscapes 1 portrait and so on to resize the images so alls images in a row will have the same height and the row will be always as wide as the main container as seen in the gif above Because the textformatter is doing everything for us I added a little clickable area to each image in the image field and a little javascript which inserts an image into body cke field on click at caret position Only thing to do is manually break the line after 4 images (or less) (NOTE: This javascript code inserting the clickable area requires at least PW 3.0.17 with new image field, as mentioned by Robin S below) For inline images I have to modify, I guess, the javascript a little, or maybe I can add another script which adds 3 links to inserted images, which add alignment classes to the image Here you'll find the files (and code snippes) https://gist.github.com/CanRau/662a559a07d6d7c492159d1cd497944f Any questions, ideas, improvements, concerns and other comments are highly appreciated PS: I'm not using it in production yet, just finished the version, I think I need to review all articles first to ensure proper migration, and maybe I add the inline handling to the javascript as mentioned before PPS: If you're interested in using this you should at least cache the textformatter output using WireCache, or TemplateCache or you can of course use ProCache, but I wouldn't recommend using it without any caching mechanism as it would re-do all the work every time someone requests the page.. Un Saludo Can Edited June 6, 2016 by Can 7 Link to comment Share on other sites More sharing options...
Can Posted June 5, 2016 Author Share Posted June 5, 2016 (edited) Fixed (at least half of the "problem") the inline image issue by extending CKEditor's contextmenu. So I added 3 menu items "alignLeft", "alignRight", "removeAlignment" First step, and it's working good. As a second step I wanted to add some preset sizes to the contextmenu like "small", "medium", "large" which would set the img size attribute But it's not yet working, no errors but no changes.. var editor = CKEDITOR.instances.Inputfield_body; editor.on( 'instanceReady', function(e) { if ( editor.contextMenu ) { editor.addCommand('alignLeft', { exec: function (editor) { var element = editor.getSelection().getStartElement(); element.removeClass('align_right'); element.addClass('align_left'); } }); editor.addCommand('alignRight', { exec: function (editor) { var element = editor.getSelection().getStartElement(); element.removeClass('align_left'); element.addClass('align_right'); } }); editor.addCommand('removeAlignment', { exec: function (editor) { var element = editor.getSelection().getStartElement(); element.removeClass('align_left'); element.removeClass('align_right'); } }); editor.addCommand('small', { exec: function (editor) { var element = editor.getSelection().getStartElement().$; console.log(element); element.attributes.width = 100; } }); editor.addMenuGroup( 'HappyImages' ); editor.addMenuItems({ alignLeft : { label : 'Rechts umfließen', command : 'alignLeft', group : 'HappyImages', order : 1 }, alignRight : { label : 'Links umfließen', command : 'alignRight', group : 'HappyImages', order : 2 }, removeAlignment : { label : 'Nicht umfließen', command : 'removeAlignment', group : 'HappyImages', order : 3 }, small : { label : 'klein', command : 'small', group : 'HappyImages', order : 4 } }); } editor.contextMenu.addListener( function( element ) { if ( element.getAscendant( 'img', true ) ) { return { alignLeft: CKEDITOR.TRISTATE_OFF, alignRight: CKEDITOR.TRISTATE_OFF, removeAlignment: CKEDITOR.TRISTATE_OFF, small: CKEDITOR.TRISTATE_OFF }; } }); }); Maybe someone knows why the small command is not working? Other ideas, improvements and any feedback is always welcome Edited June 6, 2016 by Can 2 Link to comment Share on other sites More sharing options...
Robin S Posted June 6, 2016 Share Posted June 6, 2016 That JS for inserting images into the CKEditor field is really cool! For setting the width with the "small" command, try: element.setAttribute('width', 100); For anyone trying out Can's code, note that the JS that adds the HappyImageSelector is for PW3.x image field markup. Not hard to adapt to PW2.x though. 2 Link to comment Share on other sites More sharing options...
Can Posted June 6, 2016 Author Share Posted June 6, 2016 (edited) Awesome, thank you Robin! It just works! And good note about PW3, I'll add it above and in the gist, too! JS in updated gist contains now two presets "small" (200), "medium" (350) and menu item to remove with entirely I think I'll add a default width to inserted images in the next update.. Edited June 6, 2016 by Can 1 Link to comment Share on other sites More sharing options...
Juergen Posted November 18, 2016 Share Posted November 18, 2016 Hello Can, I have tried to install your module in the latest PW version, but unfortunately I always see the code of the module in my backend. Maybe I have done something wrong: I have added the content of the ready.php file to my ready.php file. I have uploaded the Blogimage.module without the ready.php and the CSS file to the module directory. Have you tested it with the latest PW version. EDIT: OK I have found out that the opening php tag was missing. Link to comment Share on other sites More sharing options...
Juergen Posted November 18, 2016 Share Posted November 18, 2016 Doesnt work at all, There are a lot of error messages reported by TracyDebugger Link to comment Share on other sites More sharing options...
Can Posted November 18, 2016 Author Share Posted November 18, 2016 Oh, I'm sorry about the missing opening tags, added them to the gist The ready.php part was more thought to be added to an probably existing file rather then being a file, that's why I wrote "it's placed in my ready.php" and it's more like a boilerplate and not a proper module, so the post was mostly to see if people like it ;-) I'm currently using it with PW 3.0.39 and everything works fine what errors are you getting? maybe we can figure out the cause.. Hopefully I'll find some time to stuff all of it in a module or similar and make a proper repository and readme soon.. The cke additions are already in a custom cke plugin because the above code wouldn't work with TextareaLanguage, the plugin takes care of applying the contextmenu extensions to all cke instances of every language and handles insertion properly.. and actually I need to ensure it's working with single language cke, because right now the js selector are based on the language ids/classes okay I've just initiated a local repo, but I need to test things further and play around with a single language pw install to have it support both because selectors seem to differ and I still need to figure how to make it as easy to install as possible which dictates the structure and readme of the repo ;-) 1 Link to comment Share on other sites More sharing options...
Juergen Posted November 19, 2016 Share Posted November 19, 2016 Hello Can, I am using TextareaLanguage field as my body field. Therefore I got fe an error message at "$value->getLanguageValue($user->language)" - this could not be used with a string. Anyway, I have written my own image markup manipulation module using simplehtmldom. I am using UIKit as my framework and I have to include the UIKIT CSS classes and markup for images inserted with CKEditor. I have used your module as starting point for mine. Best regards 1 Link to comment Share on other sites More sharing options...
Can Posted November 19, 2016 Author Share Posted November 19, 2016 hmm not sure about the error right now but I'll look into it. I'm fine tuning the cke plugin at the moment and planning to make as much customizable as possible so class names will be changeable, too. Great that you could use the module as a starting point 1 Link to comment Share on other sites More sharing options...
Rajiv Posted December 3, 2016 Share Posted December 3, 2016 Hi Can, i'm new to processwire... but i think what you've done is really interesting... will make things a lot easier for me... maybe i dont get it... but i need some installation instructions/steps to apply this.... running the latest processwire 3.0.39. 1 Link to comment Share on other sites More sharing options...
Can Posted December 3, 2016 Author Share Posted December 3, 2016 Hi @Rajiv I'm glad you like it I'm refactoring the code to have it more customizable and pluggable, so installation should be easier, too. Don't know when I can post the new version, though. Hopefully within the next days, as I need it anyway for a new project, too ;-) 2 Link to comment Share on other sites More sharing options...
Rajiv Posted December 3, 2016 Share Posted December 3, 2016 will be waiting impatiently Link to comment Share on other sites More sharing options...
Slav Posted June 26, 2017 Share Posted June 26, 2017 @Can Hi is there anywhere a guide how to use this module (installation etc.)? Thanks! Link to comment Share on other sites More sharing options...
Can Posted June 26, 2017 Author Share Posted June 26, 2017 @Slav only this gist https://gist.github.com/CanRau/662a559a07d6d7c492159d1cd497944f 1 Link to comment Share on other sites More sharing options...
Juergen Posted June 28, 2017 Share Posted June 28, 2017 Hello @Can this line of code in your module code leads to an error message $value->getLanguageValue($user->language) Call to a member function getLanguageValue() on string Best regards Link to comment Share on other sites More sharing options...
Can Posted June 28, 2017 Author Share Posted June 28, 2017 haven't tested it but you should be able to replace this $value->getLanguageValue($user->language) with this $value Link to comment Share on other sites More sharing options...
Ralf Posted April 9, 2019 Share Posted April 9, 2019 On 12/3/2016 at 12:08 PM, Can said: I'm refactoring the code to have it more customizable and pluggable, so installation should be easier, too. Don't know when I can post the new version, though. Hopefully within the next days, as I need it anyway for a new project, too ? Hello Can, I know the whole thing is a little older... but did you get any further back then? Have you been able to develop the whole thing into a module? Many thanks and many greetings to Peru Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now