Jump to content

Jan Romero

  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Jan Romero

  1. 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.
  2. I haven’t used it yet myself, but there appears to be a module for this exact purpose by @Robin S :
  3. 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.
  4. More generally, there is a selector for this exact thing: has_parent https://processwire.com/docs/selectors/#finding2
  5. There is a configurable limit on page numbers that you can increase from the default 999:
  6. 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.
  7. 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.
  8. 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.
  9. 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) {
  10. 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(); }
  11. 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
  12. Mh, following the 4 steps from the blog works fine for me on 3.0.172 (in fact, i believe step 2 hasn’t been necessary for a while). Can you confirm that the config takes by putting var_dump($config->pageNameCharset, $config->pageNameWhitelist); into a template somewhere? Btw, just uncommenting 16B in .htaccess won’t do. You must also disable 16A.
  13. Hi @fruid. I’m not going to get into this fully right now, just some suggestions. Most importantly: What you really want to do is just buy FieldtypeTable. It’s dope, trust me. Secondly, do yourself a favor and install Tracy. I have no idea how that error came about, but the stack trace will help you figure it out. If you can’t get it to work, I suggest starting a separate thread with specific questions and code snippets and Tracy traces. Your project is kind of out of scope for Bernhard’s tutorial here 😉 Well, you’re trying to make a Multi-Field (extend FieldtypeMulti), which is a little more of an endeavor than a single value field. Lastly, you can name a hook’s $event argument anything you want, if that is what you mean. $event is kind of a convention, but you might as well use $e or $hook or $args or whatever. You can even just leave it out if you don’t need it. Hooks work with callback functions. That is to say, it’s your own function. You name the function itself and its arguments.
  14. Nice stuff, I’m definitely going to try some of these 😁 What’s the smiley little guy who is sometimes a sofa? Maybe add a title attribute?
  15. No, the values are not imported. It only connects the Fields of the chosen Template to the current Template as well. A Field can be used by multiple Templates. For example you might have a website that showcases a lot of products and also has a blog. For this you could make a Template “product” with Fields for price, dimensions and so on, as well as of course a Field called “title” and a textarea Field called “body” for the product name and a description. Now in your “blog” Template you could use “title” and “body” as well. You can even change some Field settings depending on the Template.
  16. Hi @Marvin, you can definitely have all kinds of relationships between pages in ProcessWire. The term “Page” is slightly misleading because it can imply a close connection to a web-page in your front-end. Instead, in object-oriented terms, you can think of pages as objects and templates as classes. To model the relationships between pages you can use page fields and the hierarchy of the page tree (a page will always know its children and parents).
  17. I’m only aware of this term in the realm of UI design. If that’s what you mean, ProcessWire will not get in your way implementing such a user interface, since it’s very output agnostic. It’s not clear to me what you’re trying to do. Do you mean this? https://en.wikipedia.org/wiki/Single_Table_Inheritance ProcessWire’s data model doesn’t involve inheritance, if that’s what you mean? You can get a pretty good idea of PW’s database strategy by looking at the tables of an existing PW installation.
  18. Jan Romero


    this is why I for one only make websites that no one is ever going to look at anyway.
  19. yeah, the module LanguageSupportPageNames offers this in the module settings.
  20. Ticket vendors often temporarily reserve the space as soon as it’s added to the cart. You could use that to count towards the occupied spaces and remove the reservation if the transaction isn’t finalized in time. For example you could store the time of the reservation and to calculate availabilty subtract completed bookings as well as reservations younger than 15 minutes or so.
  21. Store the bookings themselves, then subtract the amount of bookings from the available spaces on the fly. Don’t store a single constantly decremented/incremented number!
  22. Yeah, the documentation is kind of buried: https://processwire.com/api/ref/page-render/render-page/. I don’t even know how to get there, really. The PageRender class doesn’t show up on the API frontpage at all…
  23. If you use $myPage->render() you can use the options array: echo $myPage->render(['lol' => 'dongs']); /////// then on $myPage’s template ///////// echo $options['lol']; Or you could just add the property to the Page object: $myPage->set('lol', 'dongs'); echo $myPage->render(); /////// then on $myPage’s template ///////// echo $page->lol;
  24. You can do that with hasChildren() just like you proposed, but you have to get the grandchild first. If you want to get the first child of $page and then the first child of that, and then check if that has children, you can do $page->child()->child()->hasChildren(). You can also put selector strings between each of the parentheses to only get specific children. Yeah, I’m pretty sure this should work: $pages->count("has_parent=$child, template=tops|tops2, projekt_top_vermietet=1") If you already know there aren’t any other templates under $child, you can just remove the template selector entirely.
  • Create New...