Jump to content

Jan Romero

  • Posts

  • Joined

  • Last visited

  • Days Won


Jan Romero last won the day on August 26

Jan Romero had the most liked content!

Profile Information

  • Gender
    Not Telling
  • Location

Recent Profile Visitors

14,136 profile views

Jan Romero's Achievements

Sr. Member

Sr. Member (5/6)




Community Answers

  1. Usually when you use a page reference or URL field, you do so to model a specific relationship. That way it is often sufficient to have a fixed link text describing that relationship, or to generate it based on the target page. For example, links might always just say “more info” or “related: <?=$page_reference->title?>”, or the domain name extracted from a URL field. If you want arbitrary link text that is editable by users, your solution seems perfectly fine.
  2. Try adding status>=hidden to your selector. I haven’t tested this with many pages, nor with an additional field selector, but it gives a much better index utilization than the query without. 17 examined rows vs. 2000 (this is on MariaDB 10.5.11). Clearly only values over 1024 (hidden) can contain the 1024-bit, so the result set should be the same.
  3. So are you looking for hidden pages or unpublished pages? Because for pages that have never been published, this may be faster: $pages->find('published=, include=all'); The selector status=unpublished will turn into SQL as where pages.status & 2048. Now I don’t know what optimizations MySQL can do there, but it I suppose it will still have to look at a bunch of values and see if they match, whereas published=, include=all turns into pages.published IS NULL, so it should be a matter of returning a continuous range of rows from that index. Even better if you only want the ID, then it should never even touch the actual table.
  4. A good feeling to have! Thank you for your tireless improvements to PW!
  5. Hi. Have you tried replacing the wire-directory again? The error is highly unusual and I can almost guarantee that it isn’t a ProcessWire bug. Likely just a problem with transferring the files, or maybe a permission thing.
  6. I haven’t used it yet myself, but there appears to be a module for this exact purpose by @Robin S :
  7. Well, you’re going to have to fight ProcessWire at least a little bit to do something like this. PW makes it easy for you to make the pages accessible at example.com/building-1 by using UrlSegments or the new PathHooks, but the page will still have the path /buildings/building-1 internally, and every time you use $page->url or $page->httpUrl, you’ll get the “real” path (according to the page tree). So it depends on how far you want to go. If you just want buildings to be accessible as though they were somewhere else in the page tree, while also being accessible at their “real” path, you just use one of the two techniques I linked above and you’re done. You still have to watch out for pages whose actual path collides with the “shortcuts”, but it’s probably not going to be a problem unless you have buildings called “contact-us” or something 😉 If you want to completely hide the buildings’ real urls, it gets more complicated. You might throw Wire404Exceptions or simply have no template file associated with the building template (although that will lead to other problems, like I believe it will make $page->viewable always return false). Also may need to find a way to generate your “fake” paths and use them instead of the usual $page->url everywhere (e.g. for the canonical tag, sitemaps, every time you link to a building...). If your buildings use UrlSegments or have children themselves, more problems arise. It may be worthwhile to have all buildings be children of the home page and build a way to deal with the crowded page tree in the Admin instead.
  8. More generally, there is a selector for this exact thing: has_parent https://processwire.com/docs/selectors/#finding2
  9. There is a configurable limit on page numbers that you can increase from the default 999:
  10. Huh, I thought you could just do $img->sort = 1 and save the field, but doing this does indeed require a small hack as described by Ryan here: So you can totally just send a bunch of numbers and figure the new order out on the server: $newOrder = [2,4,1,3,5]; $page->of(false); for ($i = 0; $i < count($page->images); $i++) { $page->images->eq($newOrder[$i]-1)->sort = $i; // the sort property doesn’t exist on PageImage, we just introduce it so we can call sort on it below } $page->images->sort('sort'); // this is the key to the whole thing $page->save('images'); Obviously IRL you would have to validate the input etc.
  11. What’s the bit you’re asking about specifically? A general strategy could be to markup your frontend form the same way ProcessWire does it in the admin (i.e. the names of the inputs) and let PW do the server-side work somewhat like this: $yourImageField->processInput($input->post); /* upload errors must be handled separately, but you only want * to rearrange existing images, so you’ll probably want to * reject submissions with new images somehow. */ if (count($yourImageField->getWireUpload()->getErrors())) { $errors++; $yourImageField->error('Upload failed, tough luck.'); } if (count($yourImageField->getErrors())) { $errors++; } else { // successful form submission, so populate the page with the new values. $page->set($yourImageField->name, $yourImageField->value); } if ($errors === 0) $page->save(); You’ll notice that PW uses hashes to identify individual PageImages. It keeps track of the name of the image field and the image’s hash in the name of an input element that contains the image’s sort value: <input type='number' name='sort_<?=$yourImageField->name?>_<?=$image->hash?>' other-stuff-such-as-value /> For your use case it will likely be cleaner to just have a form with one number input per image, named after the hash, and hand rolling the sever-side processing. In fact, it may be easier to identify images by file name. Not sure how PW gets from the hash to the image. Since you’re likely using JavaScript to rearrange the images anyway, you might even get rid of the input element alltogether and just build the POST parameters from the actual order in the DOM before submitting.
  12. You're going to have to wrap the number in a tag, something like <span id='total-items'>{$matches->count}</span>, then keep a reference to that element around in your Javascript and update it as necessary. When deleting you might just take the innerText and decrement it, or actually count the list items (probably the most robust option). You might even calculate the new total on the server and put it into the responseText, but I would advise against it.
  13. Not that I have anything to add to LMD's solution, but the shortest answer to your question is this: All you're missing is a condition on the else. } else if ($pages->get('1032')->settings_aside) {
  14. That seems good because it’ll continue to work if JavaScript is unavailable. I would keep it. On the server I would keep everything the same and add the $config->ajax condition to send back different output for ajax requests. For example, for a deletion it would suffice to send back success or failure http headers. In your JavaScript you could then hijack all the delete links and open them asynchronously instead: function deleteAsync(event) { event.preventDefault(); const listItem = event.currentTarget.closest('li'); //assuming currentTarget is the clicked link and it’s inside the list item listItem.style.display = 'none'; //immediately hide the item to make the action appear instantaneous const xhttp = new XMLHttpRequest(); xhttp.onload = function() { if (this.status < 200 || this.status >= 300) this.listItem.style.display = 'initial'; //deletion failed, unhide the item and maybe show an error message else this.listItem.remove(); //only really remove the item if deletion was successful }; xhttp.listItem = listItem; //add the item to the request to be able to access it in the onload callback xhttp.open('GET', event.currentTarget.href, true); xhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); //you need this for $config->ajax to work xhttp.send(); }
  15. Are you using pagefileSecure? If you do, or otherwise use ProcessWire to send the file, you can change the config to force mp3s to always download using this incantation: $config->fileContentTypes = array_merge($config->fileContentTypes, ['mp3' => '+audio/mpeg']); The + sign in front of the mime type will tell PW to use the header “Content-Disposition: attachment” when sending the file type in question. Cf. https://github.com/processwire/processwire/blob/master/wire/config.php#L632
  • Create New...