Leaderboard
Popular Content
Showing content with the highest reputation on 07/27/2019 in all areas
-
That's great news right there. Not sure how things have progressed since then, but the last I checked it seemed there were a lot of perceived problems with version 5, and the answer was always "this will be really difficult because we use this new data model". I'm sure that 5 will become a great editor, but whether it will become a great editor for HTML still remains to be seen ? I'm tempted to draw lines from the CKE5 to another work-in-progress content editor that has been in the headlines lately: Gutenberg. In both cases it appears that the team is pushing an idea they wholeheartedly believe in, while a notable percentage of their existing users are telling them that it's a massive mistake. Interesting times ?6 points
-
In the hot topic of "View source", the CKEditor folks recently commented that they will support version 4 until 2023.5 points
-
@ryan in regard of debug_backtrace(), I ask myself, if something like this, PHP String Hidden Characters: Hide strings to avoid appearing in stack traces, may be useful for us in some parts too? Thinking on names, emails, document_roots, serialnumbers (Promodules), etc., - as people tend to copy&paste their stack traces into (public) forum posts when asking for help.2 points
-
I've spent the last while experimenting with srcset implementation - and PageimageSrcset is the result: PageimageSrcset Provides configurable srcset and sizes properties/methods for Pageimage. Overview The main purpose of this module is to make srcset implementation as simple as possible in your template code. It does not handle images rendered in CKEditor or similar fields. For an introduction to srcset and sizes, please read this Mozilla article about responsive images. Pageimage::srcset() // The property, which uses the set rules in the module configuration $srcset = $image->srcset; // A method call, using a set rules string // Delimiting with a newline (\n) would also work, but not as readable $srcset = $image->srcset("320, 480, 640x480 768w, 1240, 2048 2x"); // The same as above but using an indexed/sequential array $srcset = $image->srcset([ "320", "480", "640x480 768w", "1240", "2048 2x", ]); // The same as above but using an associative array // No rule checking is performed $srcset = $image->srcset([ "320w" => [320], "480w" => [480], "768w" => [640, 480], "1240w" => [1240], "2x" => [2048], ]); // Use the default set rules with portrait images generated for mobile/tablet devices $srcset = $image->srcset(true); // Return the srcset using all arguments $srcset = $image->srcset("320, 480, 640x480 768w, 1240, 2048 2x", [ "portrait" => "320, 640", ]); // The set rules above are a demonstration, not a recommendation! Image variations are only created for set rules which require a smaller image than the Pageimage itself. On large sites this may still result in a lot of images being generated. If you have limited storage, please use this module wisely. Portrait Mode In many situations, the ratio of the image does not need to change at different screen sizes. However, images that cover the entire viewport are an exception to this and are often the ones that benefit most from srcset implementation. The main problem with cover images is that they need to display landscape on desktop devices and portrait when this orientation is used on mobile and tablet devices. You can automatically generate portrait images by enabling portrait mode. It is recommended that you use this in combination with Pageimage::focus() so that the portrait variations retain the correct subject. The generated variations are HiDPI/Retina versions. Their height is determined by the portrait ratio (e.g. 9:16). Variations are always generated, regardless of whether the original image is smaller. Upscaling is disabled though, so you may find that some variations are actually smaller than they say they are in their filename. The sizes attribute should be used when portrait mode is enabled. Pageimage::sizes will return (orientation: portrait) and (max-width: {maxWidth}px) 50vw by default, which handles the use of these images for retina devices. The maximum width used in this rule is the largest set width. Pageimage::sizes() There is no option to configure default sizes because in most cases 100vw is all you need, and you do not need to output this anyway as it is inferred when using the srcset attribute. You can use the method for custom sizes though: // The property $sizes = $image->sizes; // Returns 100vw in most cases // Returns '(orientation: portrait) and (max-width: {maxWidth}px)50vw' if portrait mode enabled // A method call, using a mixture of integer widths and media query rules // Integer widths are treated as a min-width media query rule $sizes = $image->sizes([ 480 => 50, "(orientation: portrait) and (max-width: 640px)" => 100, 960 => 25, ]); // (min-width: 480px) 50vw, (orientation: portrait) and (max-width: 640px) 100vw, (min-width: 960px) 25vw // Determine widths by UIkit 'child-width' classes $sizes = $image->sizes([ "uk-child-width-1-2@s", "uk-child-width-1-3@l", ]); // (min-width: 640px) 50vw, (min-width: 1200px) 33.33vw // Determine widths by UIkit 'width' classes $sizes = $image->sizes([ "uk-width-1-2@m", "uk-width-1-3@xl", ]); // (min-width: 960px) 50vw, (min-width: 1600px) 33.33vw // Return the portrait size rule $sizes = $image->sizes(true); // (orientation: portrait) and (max-width: {maxWidth}px) 50vw // The arguments above are a demonstration, not a recommendation! Pageimage::render() This module extends the options available to this method with: srcset: When the module is installed, this will always be added, unless set to false. Any values in the formats described above can be passed. sizes: Only used if specified. Any values in the formats described above can be passed. uk-img: If passed, as either true or as a valid uk-img value, then this attribute will be added. The srcset attribute will also become data-srcset. Please refer to the API Reference for more information about this method. // Render an image using the default set rules echo $image->render(); // <img src='image.jpg' alt='' srcset='{default set rules}'> // Render an image using custom set rules echo $image->render(["srcset" => "480, 1240x640"]); // <img src='image.jpg' alt='' srcset='image.480x0-srcset.jpg 480w, image.1240x640-srcset.jpg 1240w'> // Render an image using custom set rules and sizes // Also use the `markup` argument echo $image->render("<img class='image' src='{url}' alt='Image'>", [ "srcset" => "480, 1240", "sizes" => [1240 => 50], ]); // <img class='image' src='image.jpg' alt='Image' srcset='image.480x0-srcset.jpg 480w, image.1240x640-srcset.jpg 1240w' sizes='(min-width: 1240px) 50vw'> // Render an image using custom set rules and sizes // Enable uk-img echo $image->render([ "srcset" => "480, 1240", "sizes" => ["uk-child-width-1-2@m"], "uk-img" => true, ]); // <img src='image.jpg' alt='' data-uk-img data-srcset='image.480x0-srcset.jpg 480w, image.1240x640-srcset.jpg 1240w' sizes='(min-width: 960px) 50vw'> // Render an image using portrait mode // Default rule sets used: 320, 640, 768, 1024, 1366, 1600 // Portrait widths used: 320, 640, 768 // Original image is 1000px wide // Not possible to use portrait mode and custom sets or portrait widths in render() // Sizes attribute automatically added echo $image->render(["srcset" => true]); // <img src='image.jpg' alt='' srcset='image.320x569-srcset-hidpi.jpg 320w, image.640x1138-srcset-hidpi.jpg 640w, image.768x1365-srcset-hidpi.jpg 768w, image.jpg 1024w' sizes='(orientation: portrait) and (max-width: 768px) 50vw'> Configuration To configure this module, go to Modules > Configure > PageimageSrcset. Set Rules These are the default set rules that will be used when none are specified, e.g. when calling the property: $image->srcset. Each set rule should be entered on a new line, in the format {width}x{height} {inherentwidth}w|{resolution}x. Not all arguments are required - you will probably find that specifying the width is sufficient for most cases. Here's a few examples of valid set rules and the sets they generate: Set Rule Set Generated Arguments Used 320 image.320x0-srcset.jpg 320w {width} 480x540 image.480x540-srcset.jpg 480w {width}x{height} 640x480 768w image.640x480-srcset.jpg 768w {width}x{height} {inherentwidth}w 2048 2x image.2048x0-srcset.jpg 2x {width} {resolution}x How you configure your rules is dependent on the needs of the site you are developing; there are no prescriptive rules that will meet the needs of most situations. This article gives a good overview of some of the things to consider. When you save your rules, a preview of the sets generated and an equivalent method call will be displayed to the right. Invalid rules will not be used, and you will be notified of this. Portrait Mode Set Widths A comma limited list of widths to create HiDPI/Retina portrait variations for. Crop Ratio The portrait ratio that should be used to crop the image. The default of 9:16 should be fine for most circumstances as this is the standard portrait ratio of most devices. However, you can specify something different if you want. If you add a landscape ratio, it will be switched to portrait when used. Any crops in the set rules ({width}x{height}) are ignored for portrait mode variations as this ratio is used instead. UIkit Widths If your website theme uses UIkit, you can pass an array of UIkit width classes to Pageimage::sizes to be converted to sizes. The values stored here are used to do this. If you have customised the breakpoints on your theme, you should also customise them here. Please note that only 1- widths are evaluated by Pageimage::sizes, e.g. uk-width-2-3 will not work. Remove Variations If checked, the image variations generated by this module are cleared on Submit. On large sites, this may take a while. It makes sense to run this after you have made changes to the set rules. Image Suffix You will see this field when Remove Variations is checked. The value is appended to the name of the images generated by this module and is used to identify variations. You should not encounter any issues with the default suffix, but if you find that it conflicts with any other functionality on your site, you can set a custom suffix instead. Debug Mode When this is enabled, a range of information is logged to pageimage-srcset. PageimageSrcsetDebug.js is also added to the <head> of your HTML pages. This will console.log a range of information about the images and nodes using srcset on your page after a window.onresize event is triggered. This can assist you in debugging your implementation. The browser will always use the highest resolution image it has loaded or has cached. You may need to disable browser caching to determine whether your set rules are working, and it makes sense to work from a small screen size and up. If you do it the other way, the browser is going to continue to use the higher resolution image it loaded first. UIkit Features This module implements some additional features that are tailored towards UIkit being used as the front-end theme framework, but this is not required to use the module. Installation Download the zip file at Github or clone the repo into your site/modules directory. If you downloaded the zip file, extract it in your sites/modules directory. In your admin, go to Modules > Refresh, then Modules > New, then click on the Install button for this module. ProcessWire >= 3.0.123 is required to use this module.1 point
-
ProcessWire 3.0.136 upgrades the version of CKEditor from 4.10.1 to 4.12.1. While that might look like a minor version bump, it’s actually 5 versions ahead and includes quite a lot of new features, changes and fixes. See the CKEditor release notes for more details on all that's been added and changed in the last 5 versions. It was a year or two ago where it seemed like CKEditor was going to be phasing out CKE 4 in favor of CKE 5. But interestingly it now seems like there is a new focus in CKE 4 from the CKEditor folks, so I’m going to have to start watching the version updates more often. Of course, I remain interested in CKE 5 too, but it’s nice to see CKE 4 (my favorite editor for a long time) going so strong and getting new features and attention, which is also a nice benefit for all of us PW users. I’m looking forward to working with some of the new stuff they’ve added in recent versions as well. For instance, the autocomplete feature sounds like it has nice potential for inserting Hanna codes or links to other PW pages, among other things. Also new in 3.0.136 is a new Debug::backtrace() static method in the core. I often use PHP’s debug_backtrace() method when debugging (and it appears in PW’s fatal exceptions), but the reality is it gives me a lot of stuff I just don’t want… all the hook method calls and such that aren’t usually relevant to what I’m trying to find. So the new built in Debug::backtrace() method returns a much simpler array than PHP does, and it also excludes all of the [likely] irrelevant internal hook method calls, and is just generally more focused on what you are likely to need from a backtrace in ProcessWire. It’s very convenient to plug into a ProcessWire $wire->message(Debug::backtrace()), or a Tracy Debugger bd(Debug::backtrace()); or even an echo '<pre>' . print_r(Debug::backtrace(), true); call. Though please consider this new method a work in progress, as it’s just a start at the moment and is likely to get additional updates. At some point, PW’s fatal exceptions will likely use the output from this method as well. Since this is kind of a short post, I’m just posting in the forums rather than creating a new blog post. More core updates on the way next week. Hope you all have a great weekend!1 point
-
1 point
-
Hi @jncs, sorry for taking sometime to reply you, it was a busy week. I just replicated your code in my environment and tested it. I created your two hooks Pages::saveReady and Pages::saved in ready.php and works without any issues. I tested it supplying a constant value to $page->email (my field equivalent). I suspect the issue you are encountering may be somehow related to the modified value storage in the session ($this->session->get("email")) or, as you suggested, it may be affected by cache. If the issue depends from this session variable it should be interesting to trace its contents. I am sure you have good reasons to use session storage, but you may also consider an $email property to your class module (of course the approach is different, but may be useful to validate if the issue depends from session/cache).1 point
-
I get your point, and agree – to a point. When I first came across the idea of render functions (with that specific name it was some bit of code from Ryan I believe), this was exactly what I thought ? Since then I've used render-functions in numerous projects, and while in some cases it still feels a bit "dirty", in real world it can be a tremendously helpful strategy and hasn't really caused me any notable headaches so far – quite the opposite. These days I don't have a major issue with code that generates markup as long as it's clearly separated into its own container, i.e. "siloed" properly. While I don't encourage mixing business logic with presentation, this is one of those cases where the line is a bit blurry. Also, as a minor note I don't think that we should separate logic and presentation based on the language alone. PHP can be used to create "presentational" content, so overall it's more about what you do than how you do it. Something like Twig is supposed to be "purely presentational", but you wouldn't believe the complexity of some of the logic I've seen implemented in/with it. (But this is a topic for another discussion – templating languages vs. using PHP as a templating language, and so on and so forth.) Awesome! As far as I can tell this is actually really close to this rough idea I mentioned earlier – or, more precisely, it would be one possible use case for (or variation of) it: > Another idea I've been toying with would be subcontrollers (or child controllers, or partial controllers, or whatever terminology makes most sense) I'm not entirely sure if it actually needs to be a separate concept ("chunks", or whatever that would be called), but that's not necessarily a bad idea, if it makes the concept easier to grasp. Technically it should already be possible to instantiate a new Controller, provide it with a View file, and then render the output within, say, another Controller. That's what Wireframe itself does for the page, though it all happens automatically. Another thing that might not be obvious yet (I'll have to check the docs relating to this) is that there are two use cases for views: They provide alternative ways to render a Page. For an example the default view might render markup (HTML) for the entire page, and another might render an RSS feed for a list of news items. They can be used to populate View Placeholders: if you request <?= $placeholders->aside ?> in a layout file used for the "home" template and add a view file at views/home/aside.php, Wireframe will automatically populate the "aside" placeholder with the content of current page rendered with that view file. Anyway, I'll definitely dig into this topic a bit more and come back with some sort of solution, hopefully – thanks for linking to the TemplateEngineFactory example ? Thanks – this list was quite helpful. For the record, here's how I've handled these examples in my past projects: For menus I've used MarkupSimpleNavigation, and later MarkupMenu. In the boilerplate profile I do have partials for these, but they just call the render function of a markup module. Breadcrumbs is in my case usually a simple list of parents, thus I've used a "dumb" partial file with a foreach loop. Here's an example. Sidebar, again, tends to be either a single RTE field (something like sidebar, aside, or perhaps right_column or left_column), or sometimes a predefined list of multiple fields. Again a valid use case for so-called dumb partial files, but this is actually exactly the use case for which I originally added the ability to use View files as View Placeholders. Repeating elements covers a wide area of different content, but in my projects these have usually meant one of two things: A news list or something similar, with predefined header, list of items, and often some sort of "footer" area as well. These use cases I've usually solved with render functions. Repeater, RepeaterMatrix, or some other repeatable fieldtype. "Dumb" partials with some foreach rules, or native field rendering (particularly useful for RepeaterMatrix). Note that I'm not saying that your use cases are invalid, or that the list above would be the "correct" way to handle these. It's just that I can see why this hasn't been a notable issue for me – but this also helps me understand the kind of use cases you've run into, and thus figure out how to continue from here on ?1 point
-
Yeah, it's pretty bare-bones at the moment. A form to allow folks to manually submit finds/report classification errors would be neat too.1 point
-
1 point
-
This one's not really new, but I forgot to post about it when I did it, plus there are still some unfinished aspects. I have a minimal personal invoice setup allowing me to have multiple identities for my invoices, to represent the different aspects of what I do (it's not all PW)... The child pages of an identity represent permissible payment methods for that identity... Of course, there are multiple clients under which invoice pages are stored, with highlighted status in the page tree... Invoices use repeater fields to store line-items and expenses. The line subtotal is calculated on save. The whole invoice value is worked out too. Profit and Loss is yet to be finished. And here's the result... I like PW!1 point