-
Posts
431 -
Joined
-
Last visited
-
Days Won
12
Everything posted by BrendonKoz
-
Recent issues with ProcessWire sites hosted on a Dreamhost VPS
BrendonKoz replied to FireWire's topic in Dev Talk
This might be of use to you. https://processwire.com/talk/topic/25268-unable-to-save-an-image-or-file-pw-websites-hosted-on-dreamhost-solved/ -
Updating this for further future reference for Dreamhost customers. Their support team mentioned that they had added a specific rule to their custom ModSecurity handling for the /processwire/ admin URL path. If you change the administrative path for security-by-obscurity, then their ModSecurity rules will kick in and all of the things that used to get blocked, get blocked again. You'd need to contact their support and have the settings applied per-site, per custom URI path. Their support team is great in working with their customers, at least. ?
-
A tricky selector based on a parent page's checkbox
BrendonKoz replied to heldercervantes's topic in General Support
I can't find any documentation at this moment that shows this working, and I don't have any sites that come to mind where I could test this, but I think it works... If your search is only searching pages that have a template of 'product' (or whatever your product template is), I believe you can use this: sort=-parent.archived This assumes that the value of archived is 1, if it is indeed archived. -
Once you have a PageImage object, you can use the getDebugInfo method and parse the return value to identify the mimetype. ? https://processwire.com/api/ref/pageimage/get-debug-info/
- 1 reply
-
- 2
-
-
The problem here is (potentially) three-fold, depending on (others') needs: If it's supported in a Pageimage field, it's likely expected to also be supported in a Pageimages field (WireArray) which adds some awkward complexity, because... We can have multiple image fields per template - we'd have to determine focus prior to pasting for this to work properly, whether a button is clicked (and it just attempts to pull from the clipboard) or a some sort of area gains focus, and then we paste... As flydev mentions, we're limited in the filetype that we can save as - and simultaneously if there's a developer preference should it be predetermined, or do we just go with whatever the OS provided as default? What you might be thinking about is this forum's ability to paste an image as a file attachment, but it is essentially using CKE to handle that; otherwise, I only really remember Robin's module as a way to paste URLs of a file (and not just a data: URL, though it might be able to be modified to handle that). I've handled clipboard image pasting before, but I've never handled multiple images (files) within a single clipboard instance. That's outside your described scenario, to a degree, but drag-and-drop supports multiple files, so should copying multiple existing files and pasting also similarly work in this example?
-
I'd wanted this for quite awhile but the thought never crossed my mind to create a module for it. An excellent quality-of-life improvement via this module - thank you!
-
Hi @teppo! I had a warning pop up today due to my indexing of a repeater that contains a combo field. The lib/Processor.php attempted to run `implode()` on its values, but its values were that of a multidimensional array, so PHP threw an error (Warning: Array to String conversion). I solved it by flattening the multidimensional array prior to the call to implode. I'd have submitted a pull request via Github, but I thought that in this instance there might be other places this type of solution would be warranted? Value prior to flattening: Value after flattening: Adjusted method (the two lines after "// Flatten any multidimensional [...]" comment): <?php public function processIndex(array $index, array $args = []): string { $processed_index = ''; $index = array_filter($index); if (!empty($index)) { $args = array_merge([ 'withMeta' => true, 'withTags' => false, ], $args); $meta_index = $args['withMeta'] ? $this->getMetaIndex($index) : null; $processed_index = array_filter($index, function($index_key) { return strpos($index_key, Indexer::META_PREFIX) !== 0; }, ARRAY_FILTER_USE_KEY); // Flatten any multidimensional arrays to a single dimension, then convert to string for indexing $processed_index = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($processed_index)); $processed_index = iterator_to_array($processed_index, false); $processed_index = implode(' ... ', $processed_index); $processed_index = str_replace('<', ' <', $processed_index); if (!$args['withTags']) { $processed_index = strip_tags($processed_index); } // Note: "u" flag fixes a potential macOS PCRE UTF-8 issue, https://github.com/silverstripe/silverstripe-framework/issues/7132 $processed_index = preg_replace('/\s+/u', ' ', $processed_index); if ($args['withMeta']) { $processed_index .= "\n" . (empty($meta_index) ? '{}' : json_encode($meta_index, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); } } return $processed_index; } I also wasn't sure if this was the best solution to a problem that, I believe, is not explicitly supported by the module. ?
-
My confusion was from the comment in the code example within the documentation that discusses the use of the $expire parameter using get() (the one with a value of 3600 being passed). But, overall, properly defining its meaning is far more beneficial overall. I tend to agree with @artfulrobot that there are times when knowing when a cache was created (ex: to clear an improperly stored value in a recently created cache) could be more useful than knowing when it expires, though both could potentially be useful in certain circumstances. It seems we only have the one option, as far as I can tell. I'm not well-versed in PW's caching (yet).
-
As far as I can tell, you're correct. Based on the way the documentation example is written, and how the methods process a numeric expire value in the get request, it doesn't: get cache only if it’s less than or equal to 1 hour old (3600 seconds) Instead, it... get cache only if it expires within the next 1 hour (3600 seconds) As for how best to report/request a change like this we might need to understand how the method was intended... In this case I'm not entirely sure if @ryan intended it to function the way the documentation is written, or if the code example in the documentation is incorrect...
-
I had the desire to do this too, but also ran into this issue. For me, my current field templates are primarily for fields that are used in every template, so I've instead just included the JS by default, even if the fields aren't rendered (thankfully there's not a lot of JavaScript). As a workaround you could, in the page templates that take advantage of these fields, test whether the fields are in use, and if so then determine whether to render the JS via your region (from the page template itself, instead of the field template). It's a bit of extra work, but should be doable this way instead.
-
Simple page selector doesn't work - leads to MySQL timeout
BrendonKoz replied to Gadgetto's topic in API & Templates
If you know you're going to loop through a structure anyway, even if it might look a little bit cleaner by storing things in a variable first, the descriptive nature of ProcessWire's methods (API) usually provide more than enough context-via-code to not really warrant setting up variables first. I just checked my own navigation structure and although I (ironically, because I had forgotten) created nearly the exact same code as above (get homepage, then get children of homepage, then prepend homepage to children variable), I didn't use it. Homepage is always page ID #1, or (nearly always) "/". We can test numChildren, and if so loop through the children, then as we get to the children we can also test each of their numChildren and if > 0 then loop through their children, and so on. ProcessWire's structure essentially already is hierarchical (array-like). Trying to recreate it in variables might end up duplicating the order of magnitude by 2 (loop via the API behind the scenes to create an array for a variable, then loop through the variable --- or just use the API to loop right in our code). Example: <?php // We assign $homepage to a variable since we refer to it more than once $homepage = $pages->get('/'); if ($homepage->numChildren(true)) { # code goes here to create link structure foreach ($homepage->children() as $main_link) { # code goes here to create link structure if ($main_link->numChildren(true)) { # code goes here to create link structure foreach ($main_link->children() as $secondary_link) { // If we go deeper than this, a recursive function // is likely better, so this example will stop here # code goes here to create link structure } } } } I used foreach here, but ProcessWire also has an each() method that you could substitute in, if you'd prefer. NOTE: I don't remember why I tested if there were numChildren first; I might get an error in PHP v8+ without it, I can't remember. I think the ProcessWire each() option would circumvent the need for that check, unless you need to do something in an else block. -
Simple page selector doesn't work - leads to MySQL timeout
BrendonKoz replied to Gadgetto's topic in API & Templates
I don't see anything wrong with the logic used, so there might be some underlying issue with how you're using it in this context. If you definitely want a full WireArray class object to hold this particular structure, would this work for your use-case instead? <?php $homePage = $pages->get('/'); $sectionPages = $homePage->children(); $sectionPages->prepend($homePage); This takes advantage of the WireArray method "prepend" instead of the WireData method of "and". If you're looking to generate a breadcrumb (edit: $page->parents for breadcrumbs) or navigation menu, or sitemap, the example code from the sitemap.php template in one of the default profiles might come in handy (included below in its entirety): <?php /** * Site map template * */ include("./head.inc"); function sitemapListPage($page) { echo "<li><a href='{$page->url}'>{$page->title}</a> "; if($page->numChildren) { echo "<ul>"; foreach($page->children as $child) sitemapListPage($child); echo "</ul>"; } echo "</li>"; } echo "<ul class='sitemap'>"; sitemapListPage($pages->get("/")); echo "</ul>"; include("./foot.inc"); -
I'm both embarrassed to say that I didn't even realize this was here (despite it being front-and-center in the UI) and elated to discover it today thanks to this sentence. ♥ PW has so many (amazing) things included, it's hard to keep track. Even though you've built it all, I'm surprised you're able to keep track of them all too!!
-
Hi @snck! Although teppo might have a different answer, I suspect it'll be similar to this. The SearchEngine module simply makes it dead simple to add standard search functionality into ProcessWire without handling it all manually yourself (i.e.: properly parsing/escaping fields, extrapolating searchable text from files [with the SearchEngine FileIndexer add-on module], and figuring out how to generate a search result list). Beyond that, it still uses ProcessWire's own search functionality; it doesn't expand upon it. ProcessWire can do some pretty significant things in search, but overall it still relies on MySQL's fulltext search to handle everything. MySQL can offer some level of relevancy (depending on the PW selector search you choose), but it can't, as far as I know, order by number of matches found. Relevancy is not (necessasrily/typically) the same as number of matches (per matched database record). For anything outside of MySQL's default capabilities, something external would likely need to be integrated, such as Apache Lucene or ElasticSearch.
-
From a cursory search on the feasibility of this request: AVIF support does appear to be possible, but there would be more checks required to verify the server configuration meets the minimum requirements... ImageMagick supports AVIF as of v7.0.25 or later. PHP's GD library - as of PHP version 8.1 - supports AVIF when compiled with AVIF support, and also requires support via the libavif module. The libavif module must be version 0.8.2 or greater. At this point there might need to be a decision to determine how to handle image processing: Does a PNG get uploaded and processed and converted to both AVIF and WEBP, and then the smallest of the three options is what is served - or does the site admin decide one or the other (despite gains or losses)? Add in any variations and that's a lot of processing just for a single image.
-
Yup. When I was experiencing issues on a simple form (unrelated to ProcessWire) that people were spending an inordinate amount of time on, I ended up using JavaScript to send simple, periodic requests to the server to determine authenticated status. If the session timed out, it alerted them of that fact, and urged them to copy/paste their data to be safe (even though it was saving to a draft field regardless). It helped cut down on complaints tremendously; the only ones remaining were, "It should never log me out if..." and that took more explaining than solving. ? Thankfully PW already has some good solutions in place for these scenarios. Anything in addition to what already exists would always be welcome. It's never fun to deal with clients/coworkers in a panic. Thanks, Ryan!
-
I'm getting off-topic, but you are 100% correct now that I've searched. Now my curiosity is piqued. I want to find, from the source, what his personal CMS history was! ? Either way, looking forward to future videos!
-
I figured that was what you were thinking of too while you were giving that answer; in the spur-of-the-moment I would've probably answered the same way. The dependencies are included in the project though and don't (currently?) require a composer install, so you're not entirely wrong either (depending on perspective). Not that it matters, but I think Ryan came from previously using MODx, not Drupal. I don't want to cheat my memory recall, so I'm not going to look it up! I could very well be wrong there too. ? Considering the last-minute changes for setup with your recording, I'd say the end result was spectacular! ...and yes, if you plan to record, using a placeholder where you expect your overlay video will be is what I didn't put into words, but was hoping you'd get out of what I said (somehow?). Thank you for all of the work you put into that. It was well-thought out and well-presented. I wouldn't have thought to use Git to jump around to speed things up during a live coding session; that was a great trick.
-
During the showcase of Latte, you mentioned VSCode doesn't support Latte colorization. It might now. ? https://marketplace.visualstudio.com/items?itemName=Kasik96.latte I don't use Latte so I couldn't test it, but the star rating looks good. Out of the entirety of the video, the only tiny issue was the one slide where your live video overlay was covering up the demonstration of accessing fields via code (page | template | fields). It was shown later so it was still covered - I'm being very critical here, which means overall it was very well done for a live-code recording! Thank you for sharing!
-
Thanks for all of the work, Ryan! I hope you enjoy your travels!
-
I just started thinking about OEmbeds (PW example 1, example 2) and how best to style them so that they appear responsively. Unfortunately, since there are so many various types of embeds, I can't really think of how best to responsively style them in a generalized way, if it's even possible at all. At the moment I'm only using Neue Rituale's fieldtype, if it matters, and thus far only embedding YouTube videos. By default, their embed/render size is quite small. I was able to successfully make them responsive using a little CSS trickery so that it retains its original proportional ratio and fills whatever container space is available to it. I'll likely add in a max-width at some point. However, using a similar technique on an embed that is intended to be tall/thin-width would be unlikely to work out quite as well. Has anyone attempted this feat successfully? For sharing purposes, here is the solution I'm currently using to make the oembed responsive: PW Template: <div class="oembed" style="--aspect-ratio: <?= $page->oembed->width ?>/<?= $page->oembed->height ?>;"> <?= $page->oembed ?> </div> Vanilla CSS (framework agnostic): /* https://css-tricks.com/responsive-iframes/ */ .oembed[style*="--aspect-ratio"] > :first-child { width: 100%; } .oembed[style*="--aspect-ratio"] > img { height: auto; } .oembed[style*="--aspect-ratio"] { position: relative; } .oembed[style*="--aspect-ratio"]::before { content: ""; display: block; padding-bottom: calc(100% / (var(--aspect-ratio))); } .oembed[style*="--aspect-ratio"] > :first-child { position: absolute; top: 0; left: 0; height: 100%; }
- 1 reply
-
- 2
-
-
Since bernhard didn't clarify, I think he's referring to ProcessWire logs, not system or server logs. My host handles rotation of server log files, but not log files generated by scripts installed by me; does yours (that'd be both neat and scary!)? So, I believe the maintenance being discussed here are the log files found in site/assets/logs/*...? Thus far: deploy and forget, but now I'm going to have to look!!! I'd personally be fine with keeping logs to a maximum number of days old. If I wasn't around or didn't check on something more than 30 days prior it's unlikely I'd be interested in it - though that's just me.
-
Hi @gebeer! I'm currently using RepeaterMatrix with SearchEngine successfully, though I'm not using any non-native PW FieldTypes. I did run into an issue where RepeaterMatrix-based fields, if customized by a template to not include one of it's available fields would cause an error and not complete the index. I have a pull request pending for the repository which, in my testing, seems to have fixed the problem. Although I suspect this might not be your issue, I wanted to share on the small chance that it does help.
-
@Ivan Gretsky Oh... Are you a new maintainer of the original repo, or is there a new repository? Just want to make sure I'm putting it in the correct place. Thanks!