Jump to content

Jan Romero

Members
  • Posts

    645
  • Joined

  • Last visited

  • Days Won

    18

Everything posted by Jan Romero

  1. Neato 🙂 You may want to turn this into a FieldtypeMulti to let PW take care of some of the database paperwork and get selector support for free.
  2. I don’t have access to those threads, but I have bought ProFields several times and one Table-adjacent thing I’d enjoy would be docs/improvements for paginated FieldtypeMultis. I know there is some support for this in the core but I’m not sure it’s meant as a public API. AFAIK it’s currently only used by Profields Table. In particular I’m not a fan of it using the global pagination by default. I seem to remember some ugly hacks to be required to get independent pagination per field.
  3. Full ack. I’ve long appreciated and admired the tasteful restraint with which Ryan has been steering the project all these years, but even so, PW has accumulated some features/concepts that could still use some love. The custom page classes being one hotly discussed example recently. A lot of the suggestions here would make for great third-party modules. If we want more module developers and more core contributors, an official test suite may be helpful, as would better docs and more developer relations like this (also possibly someone deranged spamming memes on twitter every 10 minutes). Obviously I say this with two hearts beating in my chest, because we all know the failure modes of playing these engagement-chasing games and of large communities in general. Regarding database abstraction, to be a little flippant, if I wanted to pay for or manage that kind of hosting, I would be building on ASP.Net Core and not use an insane language where 0 == null. I’m here because PW runs on little shared hosting plans for less than a cappuccino a month, I think a lot of us are, and as much as that sort of thing is derided and reported dead, it’s an okay niche to serve. (No hate here, I love Carson Gross, .Net, PHP and everything) It’s an absolute travesty that this sort of thing isn’t a browser feature. At least give us date ranges already.
  4. This seems to work because PW contains this “abnormal request” fallback, where it looks at $_SERVER['REQUEST_URI'] directly if the ”it“ query parameter is missing: https://github.com/processwire/processwire/blob/e508cfa2a74971490d6045bd5eb6f2a198d37037/wire/core/PagesRequest.php#L537 It involves some additional processing, removing the query string and PW’s subdirectory.
  5. Omg I just got these errors last night, unrelated to the module. Guess my hoster updated Apache. Thank you for this thread 🙏 I don’t understand the security issue and can’t seem to find many details on it, but must be pretty bad for them to break such a widespread use case…
  6. I think existing pages always have precedence over path hooks, so if a page called “/folder/4545” actually exists, no path hooks will run for such a request. But in your example, the page is actually called “/folder/4545-foo-bar”, so a path hook like this would trigger: $this->wire()->addHook('(/.*)/([0-9]+)/?', function($event) { $page = $event->pages->findOne([ 'parent' => $event->arguments(1), 'my_id_field' => $event->arguments(2) ]); if($page->viewable()) $this->wire()->session->redirect($page->url); }); This should find any path whose last segment is an integer, try to find the page with that integer among the children of the preceding path, and redirect to it. Normally I would test this before posting, but I’m not on a suitable machine…
  7. I could have sworn there was a $config->advanced option in template settings to disable this, but apparently there is only one to prevent a page from being moved. Of course, you might want to do that, too, if you need stable urls. Also note Bernhard’s hook only hides the field from the edit form, but it could still be changed through code or even (I believe) with simple browser dev tools trickery on the part of an editor. To prevent it even through the API you could probably hook into Pages::savePageOrFieldReady: https://processwire.com/api/ref/pages/save-page-or-field-ready/
  8. You may want to use path hooks for this: https://processwire.com/blog/posts/pw-3.0.173/#introducing-url-path-hooks You can also hook into 404, but I don’t have a snippet handy right now. I’ll post one if no one beats me to it, but I think path hooks are probably the best way to do what you describe. Another option would be URL segments. You could define a regex to only allow a single integer URL segment.
  9. Agreed. FWIW, this is how you might do the same thing for Field configs. For example, to have users enter CSV formatted data but store it as JSON, so it’ll automatically be available in a structured form: public function ___getConfigInputfields(Field $field) { $inputfields = parent::___getConfigInputfields($field); $myTabularData = $field->get('myTabularData') ?? []; $myTabularDataCSV = implode("\n", array_map(fn($r) => "{$r['surname']}, {$r['givenname']}, {$r['shoesize']}", $myTabularData)); /** @var InputfieldTextarea $f */ $f = $this->wire()->modules->get('InputfieldTextarea'); $f->attr('name', 'myTabularData'); $f->label = $this->_('Important config data'); $f->description = $this->_('Enter some important data in CSV form with the following column order: Surname, Given Name, Shoesize'); $f->attr('value', $myTabularDataCSV); $inputfields->add($f); $this->addHookAfter('Fields::saveReady', null, function($event) use ($field) { if ($event->arguments(0) !== $field) return; $csv = trim($field->myTabularData); if (!$csv) { $field->myTabularData = []; return; } $myTabularData = []; foreach (explode("\n", $csv) as $r) { $arr = explode(',', $r, 3); $myTabularData[] = [ 'surname' => sanitizer()->text($arr[0] ?? '—'), 'givenname' => sanitizer()->text($arr[1] ?? '—'), 'shoesize' => (int)($arr[2] ?? 0), ]; } $field->myTabularData = $myTabularData; }); return $inputfields; } So… yikes. Is there a better way? Of course it would be optimal to just have a bespoke structured Inputfield.
  10. PageTable is free because a gracious Finnish company sponsored it 🙂 It’s just called "ProFields PageTable" for historical reasons. There are also modules like PageTableNext that extend it futher. I would imagine you can switch between Page Reference and PageTable pretty easily. In the database, they look just the same: two IDs and a sort number.
  11. I think you should be able to just drop your "site" directory right into the new machine’s PW installation, replace the database, adjust /site/config.php accordingly, and it just might work. Unless your production system depends on PW core modifications, in which case it would be imperative to find out what those are. But I’d see if it works before looking into that.
  12. Here’s a PR that would guarantee pages to be newly created from the create textarea (if so configured): https://github.com/processwire/processwire/pull/298
  13. Yes, I see, sorry 😄 It should only update pages that are new or don’t have a number yet. You can remove the condition “|| $floor->floor_number <= 0” to only handle new pages. I’m still not sure what you need the numbers for. Will they be read-only? My hook will generate them by counting all items in the page reference field, but there is no guarantee someone isn’t going to change a number later and end up with duplicates even within the same page reference field. ProcessWire keeps its own number in the database to sort the selected pages. In the database it looks like this (using PhpMyAdmin): This sort field has the advantage that there should never be any duplicates. However, when users manually sort the pages, they will of course change accordingly, so they’re not tied to their page. Your main problem will still be that InputfieldPage does not just create pages as it explicitly says, but will choose existing pages if their title matches an entered line. In fact I haven’t found any indication for this behaviour anywhere but in the code itself. It’s clearly an intentional feature, but it feels like a bug when the inputfield itself only says “create new” and “they will be created”… You may be able to suppress this behavious with a hook but it’ll be ugly. Have you considered some of the more powerful modules like PageTable?
  14. Have you tried migrating to the Ubuntu machine and upgrading ProcessWire there? Seems like you could skip all of this hassle with the old server? Obviously keep the old server running until everything works on the new one.
  15. Is there a specific reason you need to use this page-tree structure? It seems to me that one particular floor can only ever belong to one particular house. You could better enforce this constraint by having the floors be children of their houses or by having a single-page-reference field in the floors referencing their house. I would strongly prefer the first option, but it would change your URLs. Reasons you should change your structure to floors being children of their houses: It correctly models the 1:n relationship. Vitally, it doesn’t allow one floor to belong to multiple houses! You may not even need the custom floor number field because you can just use “sort” (sort starts at 0, so +1 accordingly). Adding pages from a separate parent through a Page Reference Field is weird and dangerous for your use case. For example, if you enter “Ground Floor” and a page called “Ground Floor” already exists (seems likely), it will silently use the existing page and not create a new one. Your URLs will be nicer in every way. Your current setup will have to create unique names for every ground floor, so you’ll eventually have /floors/ground-floor-27/ as opposed to /city-hall/ground-floor/. If you really like the /floor/ground-floor/ URLs, you can use path hook trickery to fake them. This is much less of a hassle than your approach. Here’s a hook you could use to generate numbers for pages added through Page Reference Field, but I’m telling you right now: don’t do this! $this->addHookAfter("InputfieldPage::processInputAddPages", function(HookEvent $event) { $inputfield = $event->object; $floors = $inputfield->value; $c = 0; foreach ($floors as $floor) { $c++; if ($floor->_added === true || $floor->floor_number <= 0) $floor->setAndSave('floor_number', $c, [ 'quiet' => true ]); } }); These are just my 2 cents without knowing all considerations of your project, so I may be completely off. There may also be better and more robust ways to achieve what you want than this little hook
  16. With all due respect, disparaging PW over this is entirely uncalled for. It’s not a ProcessWire concern. Whether it’s links or redirects, your issue lies in interfacing with the browser. ProcessWire’s session()->redirect() is just a thin abstraction over HTTP/1.1 301 moved permanently Location: http://example.com If a browser doesn’t want your site to open a new tab, it’s not going to open a new tab. I’m sure you’ve seen sites of questionable repute apply some trick or other to open pop-ups, pop-unders and whatever else, and you can use ProcessWire just fine to deliver those same tricks, but ProcessWire’s role in that ends at helping you manage and assemble the data for your response. Admittedly I’m still not certain what your clients’ goal is. You have a clickable link in a sidebar and want it to open in a new tab, but somehow it also involves a redirect? Sorry I can’t be of more help, but I’m sure we can get it figured out if it’s at all possible.
  17. Please explain what your client needs users to experience in more detail.
  18. What do you want to happen with the original tab? A redirect is a specific type of HTTP response that directs the browser to go somewhere else. If you want to show a response in the original tab and additionally open a new tab immediately, you can try adding some javascript to the original response, such as window.open('https://example.com', '_blank'), but generally browsers/users don’t like this very much and their popup blockers will prevent it by default. And why not handle the problem earlier, when you show the link to the user? if ($page->external_url) { echo "<a href='{$page->external_url}' target='_blank'>{$page->external_url}</a>"; } This likely won’t be blocked because it’s a direct result of a user interaction.
  19. Here’s another edge case: 0 results. So really you gotta do this, if you presume an empty pagination page to exist: (int)ceil(($this->getTotal() ?: 1) / $this->getLimit());
  20. Admittedly I’ve been meaning to read this whole thread for days and the quoted passage is about all I got so far, but there is a first party option here: https://processwire.com/store/login-register-pro/
  21. I dunno, what does the blank response look like raw? Is it a 200? Another long shot would be clearing the browser cache etc. Sorry you have to deal with this. PW’s easy upgrade process is one of the things I love most about it, lol.
  22. Did you compare the old and new .htaccess? Maybe you have some config in there that you need to carry over to the new file.
  23. May I just say… this won’t work: <?php $lastPageNum = ceil($posts->getTotal() / $limit); ?> <a href="<?=page()->url($lastPageNum)?>">Go to the last page</a> Because ceil() always returns a float. This also means you may get subtle bugs when using === to compare it. Personally I detest having to divide and ceil() and cast to int myself, so my proposal is to add this functionality to the core. It would be something like this: public function getTotalPages() { return (int)ceil($this->getTotal() / $this->getLimit()); } Or should it be called getLastPageNum()? Might make a PR later…
  24. https://www.youtube.com/@TheSegi86
×
×
  • Create New...