Leaderboard
Popular Content
Showing content with the highest reputation on 11/11/2021 in all areas
-
https://right-to-know.org/ Website to check your local area's stressors e.g. air, noise and light pollution etc. Available for postcodes in the UK. I did quiet a bit of database stuff to host postcode lookup on the site and caches any API results for teh stressors on site for fast second query. We also choice against any tracking on the site (google analytics etc) and only track the number of total queries and number of requests to each specific postcode.3 points
-
Hi all, Added link to the Google Form in the first post. Please let me know if there are any glaring mistakes/ambiguities, thanks ?.2 points
-
I think there's no way around this issue except for the developers to adapt their code a bit, have their page working without javascript, or a full page reload. I tried to check if there was a way to somehow "reset" the javascript but it seems there's none. What I like about this is how it's somehow reminiscent of front-end editing's method D. Maybe it could be something to rely on for the live preview as well ?2 points
-
@kongondo Thanks, great ideas! Your SSE examples are eye opening. I think I understand a lot of this but not yet all of it, since I'm not deep in htmx yet, so I'll have to return to this once I do. But part of what you covered was the external interface to it that the web developer implements, and I think that's a good place to start, so I'll focus just on that. I understand the benefits of a separate config file, but am not sure how many would go to the effort of maintaining it for live preview. Maybe if PW auto-generates it somehow with functional defaults, it might help. Pros/cons aside, when we need something outside of the defaults, personally I'd rather declare this with markup classes or attributes in a manner similar to how we do for Markup Regions. Maybe I'm lazy, but it's already easy and familiar, and not much new to remember. Like with Markup Regions, ProcessWire can remove the attributes when they aren't needed, so no need for any output downsides. But if I had to declare it separately from the markup, I'd at least like to be able to do it in Setup > Fields > field rather than having to edit a .json file (and maybe this is a good fallback either way). I agree that it's good if the default behavior is to swap the entire <body> / refresh the window. But when we want to declare what gets updated with a live preview, here's an example of one way we could do it. If I wanted a particular section of markup to update automatically when the field "images" changed, I'd like if I could just do something simple like this, where div#gallery is an existing bit of markup a already there, like this: <div id='gallery'> // markup for an image gallery </div> …and I just add a class to that existing markup tag... <div id='gallery' class='pw-field-images'> // markup for an image gallery </div> ...or maybe a custom attribute instead: <div id='gallery' pw-field='images'> <!-- markup for images gallery --> </div> I'm not suggesting to add additional markup, but just an additional class or attribute to existing markup. If that same images field was also used elsewhere in the page, then I could just use that class (or attribute) again, and it would update too: <div id='sidebar-photos' class='pw-field-images'> <!-- markup for the sidebar photos --> </div> One thing I noticed in coding ProDrafts live preview is that field-level granularity often makes little difference in the end result. Replacing larger blocks of markup often is just as effective and visually identical. So I'd want to be able to say "if any of these fields change, update this…": <div id='content' pw-field='title,body,images,sidebar'> ... </div> For fields that already contain markup (like CKEditor), or fields that get rendered from their own /site/templates/fields/* template file, ProcessWire could automatically add the appropriate class by wrapping the value with it (this is similar to what ProDrafts and PageFrontEdit do): <div class='pw-field-body'> <!-- value of $page->body, div wrapper added automatically when live preview --> </div> This enables it to work automatically, without the developer doing anything at all. The only minor downside is that occasionally that can interfere with a CSS/JS selector, like if you are trying to target h1 + p:first-child, where the <p> is part of the CKEditor output but the <h1> isn't. Live preview still works, but the CSS/JS selector no longer matches when live preview is on. It's simple to work around though, and of course only affects output when someone is live previewing. Whether using a separate config file or not, if we use htmx, I think it should be a silent player and the developer wouldn't even need to know anything about how to use it. I'd like to avoid an external config file where I'm having to add 'htmx-attributes' arrays. I don't think we need the level of granularity or features in live preview that would demand the user know this kind of stuff. (Though fine for advanced users if/when needed). The more automatic it is, the more likely one is to use it. I think we'd also like the flexibility of not being dependent upon any particular library in case we ever decide to replace it with something custom. Side note, but one issue I also noticed in coding ProDrafts live preview is that when you update an element that has JS events on it that were added in document.ready, then they no longer work. For instance, an images gallery might have events that make thumbnails open in a lightbox or something. When the images gallery live updates, the lightbox no longer works unless the events were added to the whole document. Does htmx have some magic for this kind of situation?2 points
-
In preparation for testing of the initial (alpha/early beta) release of Padloper 2, I would like to gather expressions of interest. In the past, some of you expressed a willingness to help with testing. It has been many days since and your position might have changed. In addition, I would like to do this in an organised manner so we cover as much ground as possible. The grounds I’d like to cover are usability and technical aspects with a bias towards the latter. Please also note that there are a number of planned features that will follow the initial release. Hence, we shouldn’t focus much on those. These and similar thoughts will be added to a planned features list (more on this below). The main focus of this testing is to make Padloper 2 production-ready. In order to properly organise this testing, I will need to gather some information from you. I will be doing this via Google Forms. The most important detail will be your email address. I will need this in order to inform you how to access Padloper 2 as well as for other necessary communication. I will not use your email address for any other purposes nor pass it to any third-party ?. Other information to be captured in the form would be what areas of testing you will you want to be involved in and your preference for planned features (since I will need to prioritise them). Forms are better than plain emails in this respect. Please note the following if you wish to be involved in the testing programme: Pricing and subscription will follow the model I have previously stated (similar to ProcessWire Pro Modules). However, for the testing programme, your subscription period will NOT start counting down until after the production-ready release. You will still also have VIP support (please note the nature and location of this may change). To be fair to other testers, anyone joining the programme needs to actually spend time testing the product. If you won’t have time to do this, please wait for the production release. This initial release is NOT a production release. Although it may work for some in that regard, it will not be tagged as production-ready (hence the alpha tag). Licences will be the usual three: (i) Basic/Single Site Licence, (ii) Developer Licence and (iii) Agency Licence. I can explain the different between these three if anyone needs clarity. The initial release will have the introductory prices of €150, €300, €900 for single, developer and agency licences respectively. Cooling period will be 14 days (within which a full refund can be requested, no questions asked). Please note that this time period may change for the production release. Here is the link to the Google Form to express your interest in the testing programme. The form will close in 10 days. Many thanks for your patience. Hope to see you soon in the testing programme. I trust you will enjoy Padloper 2 as much as I have had the pleasure (and honour) of developing it ?.1 point
-
Forgot to add. I'll leave the form up for about 10 days, just to give everyone a chance to register.1 point
-
Thanks, very cool idea. The str_replace() isn't even necessary, if you use basename($ext = false). // Create $image->alt method wire()->addHookProperty('Pageimage::alt', function(HookEvent $event) { /* @var $image Pageimage */ $image = $event->object; $event->return = $image->description ?: $image->basename($ext = false); }); https://processwire.com/api/ref/pagefile/basename/1 point
-
1 point
-
1 point
-
1 point
-
1 point
-
I'm interested - getting more requests for ecommerce now and would prefer to be using ProcessWire.1 point
-
I believe the heat levels are an average or max... not sure you're have to read the info. I was provided the data but Centric Lab will know the ins-and-outs of how its was derived.1 point
-
1 point
-
And on that basis you can signpost people too. So before you allow free type they might have to indicate an initial route by clicking a button - e.g. Do you want a) Report a problem b) Pay a bill etc etc.... "Now tell us which service you want to pay a bill for"...(free type and match). Might help limit the terms they throw at it.1 point
-
The thing I'm thinking of is that a lot of people don't do this (often me included). Like if we've got a button with id="my-button" that we want to add a click event to, then we add it to $("#my-button").on('click', ...); and that no longer works if the button gets swapped with something from live preview. Of course, it's just a matter of coding the JS in a different way. But before telling people to code things a certain way I like to see if I can find a way to make things work no matter how they've put together their front-end code. For this case (live preview) it's probably not that important though.1 point
-
1 point
-
New module: OneTimeOnlyCode https://github.com/benbyford/OneTimeOnlyCode Use this module to create codes with urls (or any of string data) and later check a code and its data e.g. to get one time access to content. I built this to send out specific "exclusive" users codes at the end of URLs to new articles where noramlly they would have to log in -> now they can see the content only once and then have to login if they navigate away. I made it only to show the content not any user profile infomation etc when using the code, be warned not to use it to show user information unless you know what you're doing! Codes can have an expiry and uses lazy-cron to cull codes out of day at a set interval (both in checking and elapsed interval for the codes). Check it out!1 point
-
I have had a play and some of the implementation is literally, trivial ?. SSE SSE is so simple it is unbelievable at first. You only need two things: in our case PHP and a modern browser...batteries included! Example adapted from w3schools. More examples at MDN. server-side <?php namespace ProcessWire; header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); $time = date('r'); echo "data: The server time is: {$time}\n\n"; flush(); client if(typeof(EventSource) !== "undefined") { var source = new EventSource("/some-processwire/url/"); source.onmessage = function(event) { document.getElementById("result").innerHTML += event.data + "<br>"; }; } else { document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events..."; } I tested it and it works fine but was getting errors about wrong mime type if I set the headers later, but that is to be expected. Live Preview Refresh - Partial and Full - ajax - htmx I have this working nicely (will try post the demo later today). The premise is: A change happens. The editor client sends the data to the server to save the change (autosave - was just mimicking this part). Server saves and sends back a response including the name of the field that has been saved and the page ID back to the editor client. The editor client communicates with the preview client (a separate window). It sets the page ID and the name of the changed field name in its message to the preview window. The preview window client (htmx) receives the page id and the name of the field that has changed and sends a request to the server to fetch the rendered contents of that field for that page. The server sends back the html for htmx to swap in the DOM. In this simple communication, we have the field name match the html id of the element we are swapping. E.g. <h2 id='headline'>My Headline</h2> This is simple and straightforward and easily achieves partial refresh. However, it will be difficult to handle the more complex cases I mentioned in my previous post. It will also be somewhat dictating how the developer should name their html attributes. In addition, it still leaves the developer's templates with htmx attributes that will not be needed in production. This got me thinking. Live Preview Wrapper - idea #1 In this case, the live preview window would add a wrapper html element around the rendered template file markup. The wrapper html element would have the htmx attributes instead of the template file markup. This idea didn't go very far. It would inevitably lead to broken / incorrect markup in the preview window as the outermost markup of the template file would be <html> tags. In addition, while it solves the problem of unrequired htmx attributes in production, it doesn't solve the problem of selective rendering. It still wouldn't' know what parts of the markup in the preview window to swap. Live Preview Config - idea #2 What if instead of live preview / ProcessWire suggesting things like naming of elements, standard markup, etc. that are needed in a template file in order to get selective markup rendering, we implemented it the other way round? What if the developer instead, via config file(s), passed properties to live preview to implement the htmx attributes needed for a template file / page? The default would be full page refreshes. However, if live preview detected that a partial refresh config was available, it would implement those. This would offer the granularity needed for partial refreshes. If live preview did not receive / detect any configs, the default would kick in. Live preview would remain as agnostic as possible. It could be something like this (assumes use of htmx): A developer places their live preview partial refresh configs in /site/templates/live-previews/basic-page-live-preview.php (or basic-page-live-preview.json). ProcessWire detects that the template file basic-page has a partial refresh config in .../live-previews/basic-page-live-preview.php When ProcessWire loads the preview window, it injects the htmx attributes for each named element in the live preview configs in the corresponding elements in the preview window DOM. Injection is done by a ProcessWire live preview near-agnostic JavaScript script that only runs in the preview window. When the autosave happens in the editor window and the preview window gets informed, htmx kicks in, responding to an event and fires htmx.trigger(elem, event). The element in the markup with the corresponding event listener (hx-trigger='this-element-event-fired') will pick up the event fired by htmx.trigger() and query the server for the changed markup. The attributes set in #3 will ensure only the markup that has a change will fire. Server sends the response back and the element's hx-swap (or even hx-oob) picks it up and swaps the DOM. #6 is still not straightforward though. What will live preview / ProcessWire send back? Here too the config at #1 can help. E.g. it can tell ProcessWire to send <p>My Field Value</p> or just send the value of the field back, i.e. 'My Field Value'. The former is still complicated. Instead of telling ProcessWire I want <p>My Field Value</p>, how about tell it, via the configs at #1 that if requested field is field A, send me back the raw value (e.g. a plain text) but if the request is for field B, use this defined function in basic-page-live-preview.php to send me the rendered partial markup for field B? All ProcessWire would do is pass the value of field B to the said function. This value could be a Pageimages object. The function would iterate the images and send back the 'gallery' markup back to htmx to swap. example live preview config <?php namespace ProcessWire; $livePreviewConfigs = [ [ 'field' => 'headline', 'element_id' => 'my_headline_element_id', 'htmx-attributes' => ['hx-swap' => 'outerHTML', 'hx-trigger' => 'headlineevent'] ], [ 'field' => 'images', 'element_id' => 'gallery', 'handler' => 'renderGallery','htmx-attributes' => ['hx-swap' => 'innerHTML', 'hx-trigger' => 'galleryevent'] ], ]; function renderGallery(Pageimages $images) { // we only need the <li> since we are using innerHTML swap // the target element is <ul id='gallery'></ul> // -------------- $out = ""; foreach ($images as $image) { $thumb = $image->size(200, 200); $out .= "<li><img src='{$thumb->url}' alt='{$image->url}'></li>"; } // --------- // sent back to htmx to swap return $out; } When the preview window loads, ProcessWire sends $livePreviewConfigs to the browser, e.g. ProcessWire.config.LivePreview. The preview window JavaScript would consume it like this: client set htmx attributes @note: JavaScript written in the browser, not tested, could have errors. // get live preview configs const elementsConfigs = ProcessWire.config.LivePreview // loop through configs, find the corresponding element and set their htmx attributes for (const elementConfig of elementsConfigs) { const element = document.getElementById(elementConfig.element_id) if (element) { const htmxAttributes = elementConfig['htmx-attributes'] for (const [prop, value] of Object.entries(htmxAttributes)) { element.setAttribute(prop,value); } } } htmx-ready DOM changes via live preview injection (runtime only in live preview window): <h2 id="my_headline_element_id" hx-swap='outerHTML' hx-trigger='headlineevent' hx-vals='{"field":"headline"}'>My Headline</h2> <!-- gallery --> <ul id="gallery" hx-swap='innerHTML' hx-trigger='galleryevent' hx-vals='{"field":"images"}'> <li><img src='image-1-src' alt='image-1-alt'></li> <li><img src='image-2-src' alt='image-2-alt'></li> </ul> I have partly implement the above (just hard-coded configs for now) and it works nicely. Takeaways ProcessWire's live preview remains as agnostic as possible. Developer give instructions to live preview (via configs) and not the other way round. Live preview ships with minimal defaults, including full page refresh. It seems like a lot of work on the developer's part if they want partial refresh. However, this partly matches the complexity of their template files. Besides, some of the functionality (e.g. renderGallery()) could be something they already use in their template, hence reusable. Developer does not need to have additional markup in their template files in order to see live previews when editing. This means no cleaning up afterwards. Their templates remain clean. Live preview only alters the DOM (of the rendered template) at runtime. Developer can name their markup attributes as they wish. Developer can decide what needs live preview and what doesn't, even on the same page (e.g. hx-select). ProcessWire stays out of the developer's way, as usual.1 point
-
Thanks, @ryan! This year's end seems to be even more interesting than its beginning) If that is required for the live preview it should be in the core, IMHO) If I understand it right, the core of what we need to build is something listening to a page save event and refreshing the preview page when it happens. Now we have an autosave to generate the events. The other part is reacting to that autosave. I can see 2 ways of doing that: ajax polling and sse (we probably do not need WebSockets as the preview doesn't need to send anything to the server... yet?). The latter (sse) seems to be a better fit, as it should use less server resources, but might be harder to implement (maybe not). Anyway, htmx supports sse (and even ws to an extent), which makes it a better fit than unpoly that doesn't (at least it didn't not so long ago when I checked). Actually, we could go without htmx, just taking inspiration from the principle it is based on. Though taking the ready-made library could be easier. The other part where htmx (or unpoly, or turbo or...) could help, is refreshing not the whole preview page, but only a part of it. Regenerating the whole page markup could be a long process (those 2 seconds in the OP are way too optimistic for many of the sites I have seen). For example, we could regenerate only one PM block markup and sent it to the preview for htmx to swap. But that would require either some standardization of the frontend or some hookable architecture for a developer to implement. The former would break the core PW principle of leaving frontent to the developer. The latter should be possible and would work nicely when rendering RM based content builders the standard way or with a Wireframe. Unpoly is complete framework, which could be used to upgrade PW admin as a whole, but would probably require to do everything its way. For a one place thing or for a more-work-more-customization htmx is a better suit, as it is lower level, as both of you @Craigand @kongondoagreed. If we bring in unpoly, we need to be ready to slowly redo all the admin area with it (which might be a nice thing in the long term). But for one task htmx is lighter solution. And we could even go without it only getting inspiration from it.1 point
-
@Ivan Gretsky Hooks have already been added for this, and I think they were present in the dev version I posted in the ProFields board a few months back? I don't remember for sure, but I'm trying to make everything hookable so that people can modify the output as needed, and will keep looking for additional opportunities for that as I build in more related features. @teppo Yes there's a renderAddMatrixItemLink() hookable method for this, and it renders a link for one matrix item type, and gets called for each of them. So you could change the output to be anything you want. This is already present, but with the changes being made, chances are another hookable method will be added related to this. @Pete If I understand correctly, this is already there. See the "Matrix types to allow for adding new items" on the "Input" tab when editing your matrix field. This can be configured in template context which enables you to specify some types for one template and other types for another, etc. @mlfct Thanks, I was able to reproduce that here too and have pushed a fix on the dev branch.1 point
-
Thx RobinS for the idea about the getExtraMarkup hook! I slightly changed your version: $this->addHookBefore('AdminTheme::getExtraMarkup', function (HookEvent $event) { $config = $this->wire->config; $url = $config->urls($this); $config->scripts->add($url."lib/moment.min.js"); $config->scripts->add($url."tabulator/js/tabulator.min.js"); $config->scripts->add($url."Grid.js"); $config->scripts->add($url."RockGrid2.js"); $config->styles->add($url."tabulator/css/tabulator.min.css"); }); using the "before" hook makes it possible to use the config->scripts|styles->add syntax ? I'd love to get a $config->scripts->addAfter("/my/script.js", "/my/other/script.js") feature - but acutually I've always found a way to get the correct order by using proper hooks...1 point
-
@neophron Always using this method may cause headache for you. What about add this method as property for each image field and use it like $imageField->alt. We need to add a hook method. Add hook method to existing /site/ready.php or create new /site/ready.php, copy below code and paste it in to /site/ready.php : /site/ready.php <?php namespace ProcessWire; wire()->addHookProperty('Pageimage::alt', function(HookEvent $event) { /* @var $image Pageimage */ $image = $event->object; $event->return = $image->description ?: str_replace('.' . $image->ext, '', $image->basename); }); Usage ($imageField->alt) : <?php foreach($page->images_slider as $image) { $slide = $image->size(0,700); echo "<li class='uk-width-3-4'>"; echo "<img class='photo' src='{$slide->url}' alt='{$image->alt}' width='{$slide->width}' height='{$slide->height}' />"; echo "</li>"; } ?>1 point
-
Managed to solve my issue, documenting what I done here for others and future reference. So basically I never actually figured out the specifics of what was causing the fatal error, however as mentioned previously it did seem related to the custom module that was setting up numerous webhooks. After trying numerous things, I ended up deleting the contents of the cache table within the database, which got rid of my inital fatal error and let me render pages. Now that I could see pages, albeit with some errors I was able to then log into the backend. Wherein I refreshed the module cache which appears to have resolved the issue. Hopefully the above will be of use to someone in future... more than likely myself as I have a habit of running into the same odd errors. ?1 point
-
Hello, I fixed my problem. The solution was easier than its research Just needed to truncate cache table in MySQL.1 point