-
Posts
4,928 -
Joined
-
Days Won
321
Everything posted by Robin S
-
Hook to select first option in page reference fieldtype
Robin S replied to Flashmaster82's topic in General Support
First have a look at the docs for eq(): https://processwire.com/api/ref/wire-array/eq/ This method works on a WireArray/PageArray and returns the item at the given position. So the object you call the method on needs to be a WireArray/PageArray but you are calling it on a Page object (probably your booking_status field is a "single" Page Reference field so its value when populated will be a Page). It's not clear to me what you're trying to do in that part of your code, but if you want your if() test to mean "if the booking_status field is not empty" then you would do something like this: if($bookingstatus->booking_status->id) { //... } Or if you want to check if the value of the booking_status field value equals some page then you would do something like this: // Get $some_page however you like $some_page = $pages->get('/path/to/page/'); // Check if the booking_status field value equals $some_page if($bookingstatus->booking_status === $some_page) { //... } -
Hook to select first option in page reference fieldtype
Robin S replied to Flashmaster82's topic in General Support
It doesn't make sense to put the parent path in a check against the page template, but you can check the parent path separately: if($page->template != 'booking') return; if($page->parent->path !== '/nya-bokningar/') return; // The rest of your hook code... -
Hook to select first option in page reference fieldtype
Robin S replied to Flashmaster82's topic in General Support
If you want to pre-set the third option within the selectable pages: $wire->addHookAfter('Pages::added', function(HookEvent $event) { $page = $event->arguments(0); // Only for the booking template if($page->template != 'booking') return; // Get all the selectable pages for the field $selectable_pages = $page->getInputfield('booking_searchactivator_option')->getSelectablePages($page); // Get the third selectable page (the numbering is zero-based) $third_selectable_page = $selectable_pages->eq(2); // Set the third selectable page as the field value $page->setAndSave('booking_searchactivator_option', $third_selectable_page); }); -
Wow, what an awesome list of improvements! @ryan, I have a question about the lazy-loading of fields. Do you think this change means that the previous recommendation to reuse fields, as in the "Making efficient use of fields in ProcessWire" blog post, is now no longer needed? Say I am using text fields in lots of different templates for different purposes, and if I create and name fields so they describe the use in each template I will have 50 text fields, or if named them generically and reused them I would have maybe 5 text fields. Is their any reason now to prefer the 5 fields option over the 50 fields option, given that in any one template I'll only have 5 text fields or less and so presumably only ~5 or less fields get fully loaded at a time?
-
How to find a page in process wire admin given a URL
Robin S replied to Peter Oehman's topic in General Support
In the template code for your website footer you can add something like this: <?php if($page->editable()): ?> <a target="_blank" href="<?= $page->editURL ?>">Edit this page</a> <?php endif; ?> This will give logged-in users who have permission to edit the page a link to open the page in Page Edit, and you can work out its location, template, etc, from there. Or if you have Tracy Debugger installed you can run the following in the Console panel while viewing the page on the frontend and the edit link will appear in the console output: <a target="_blank" href="<?= $page->editURL ?>">Edit this page</a> -
[SOLVED] Page Field Select From Grand Parent of Page?
Robin S replied to prestoav's topic in General Support
If you are currently using "Page List Select" as the inputfield type you'll want to change to different inputfield type because that inputfield doesn't support limiting selectable pages by anything other than parent. This is explained in the field settings: -
[SOLVED] Page Field Select From Grand Parent of Page?
Robin S replied to prestoav's topic in General Support
Try instead: template=faq-category, parent=page.parent.parent, sort=sort -
@DrQuincy, when using $this->halt() I think it has to be return $this->halt() or else you still get the subsequent template output. Template file: Output: Template file: Output:
-
I think person 2 sees page B in 2 seconds. I did a kind of test... I have two pages and two templates: page "Yellow" uses template "colour" and page "A Basic Page" uses template "basic_page". There's nothing special about the template file for basic_page but in the template file for colour I have: sleep(30); If I load page Yellow in one tab and then immediately load A Basic Page in another tab then I have to wait 30 seconds to view either page. But if I load page Yellow in one tab and then immediately load A Basic Page in an incognito window (which will have a different session) then the page loads immediately.
-
You can do a find() but with a limit of 1. This will be just as efficient as findOne(), the only thing is that it will return a PageArray so use first() to get the item as a Page. $results = $pages->find("template=template-news, sort=created, limit=1, start=1"); if($results->count) { $title = $results->first()->title; }
-
anybody could show an example of how to use $config->ajax ?
Robin S replied to adrianmak's topic in Getting Started
Should be: return $this->halt(); -
Disable selected/used options (Page references) in Admin
Robin S replied to Flashmaster82's topic in General Support
Yes, it will break. I gave the link to the blog post introducing "owner" selectors in the code, but here it is again: https://processwire.com/blog/posts/processwire-3.0.95-core-updates/ So this selector... template=colour, select_colour.owner.template=animal, select_colour.owner.id!=$page->id ...is saying... Match pages where: the page template is "colour" and the page is selected in a field named "select_colour" and the page containing the select_colour field is using the template "animal" and the page containing the select_colour field is not the page represented by the $page variable (i.e. the page that is currently open in Page Edit)- 3 replies
-
- 4
-
- select options
- hooks
-
(and 1 more)
Tagged with:
-
Disable selected/used options (Page references) in Admin
Robin S replied to Flashmaster82's topic in General Support
This would be easier to explain in your context if you had included all the relevant field and template names in your post. So here is an example that you can adapt to your scenario... I have a Page Reference field named "select_colour" and generally the selectable pages are those that have the template "colour". I add this field to the template "animal", so that on animal pages I have a field to choose the colour of the animal. But in the select_colour field I only want to show colours that have not been selected on any other animal page. So in the settings for field select_colour I only use the "Custom PHP code" option for "Selectable pages" and add the following code to /site/ready.php: $wire->addHookAfter('InputfieldPage::getSelectablePages', function($event) { $page = $event->arguments(0); // Define selectable pages for the select_colour field if($event->object->hasField == 'select_colour') { /** @var Pages $pages */ $pages = $event->wire()->pages; // Find colours that are already selected on another animal page using "owner" selector // https://processwire.com/blog/posts/processwire-3.0.95-core-updates/ $already_selected_on_another_page = $pages->find("template=colour, select_colour.owner.template=animal, select_colour.owner.id!=$page->id"); // Return colour pages that aren't already selected on another page $event->return = $event->pages->find("template=colour, id!=$already_selected_on_another_page"); } }); Another possible approach is to loop over all the colour pages and remove those that are referenced on another page, but this is less specific because it will remove colours that have been referenced in any field, not just the select_colour field. $wire->addHookAfter('InputfieldPage::getSelectablePages', function($event) { $page = $event->arguments(0); // Define selectable pages for the select_colour field if($event->object->hasField == 'select_colour') { /** @var Pages $pages */ $pages = $event->wire()->pages; // All colours $colours = $pages->find("template=colour"); foreach($colours as $colour) { // Remove colour if any other pages are referencing it if($colour->numReferences) $colours->remove($colour); } // Return the filtered colours $event->return = $colours; } });- 3 replies
-
- 2
-
- select options
- hooks
-
(and 1 more)
Tagged with:
-
Page autocomplete query is getting 403 error
Robin S replied to Frank Vèssia's topic in API & Templates
Might be mod_security false positive. -
How do I use filters to search a string with Double Quotes?
Robin S replied to GradDev's topic in General Support
The *= operator isn't the right one to use because it doesn't match partial strings at the start. If you use the %= operator I think it will work. -
ProcessPageLister and pagination in a module
Robin S replied to MSP01's topic in Module/Plugin Development
You can set the base URL for MarkupPagerNav that is used for the Lister pagination. public function ___executeBrowser() { // Before MarkupPagerNav is rendered $this->addHookBefore('MarkupPagerNav::render', function(HookEvent $event) { $pager = $event->object; // Set base URL to the current page + URL segment $pager->setBaseUrl($this->wire()->page->url . 'browser/'); }); $browser = $this->modules->get('ProcessPageLister'); return $browser->execute(); } -
Something that would be worth a try... Use a saveReady hook to put all the tags as space-separated values into a (hidden) textarea field. Then use the **= operator with the tags string of the current project. From the docs:
-
Thanks. It looks like the legacy Default and Reno themes don't call AdminThemeFramework::getPrimaryNavArray() so the hooks added by this module don't have any effect. Therefore AdminThemeUikit is a requirement - I've updated the module install requirements and readme to reflect this.
-
I think a couple of ways are possible. One is similar to what @horst suggested, but you can use the special created timestamp of 10 to more exactly identify temporary images: $page->getUnformatted('images')->find('created!=10') There are also the public Pagefile::isTemp() and Pagefiles::isTemp() methods that can be used to check if a particular Pagefile/Pageimage is temporary or not. Another way would be to set the outputFormat property of the images field to array before you get the field value so that the value is standardised for single and multiple image fields. $page->getField('image')->outputFormat = FieldtypeFile::outputFormatArray; // Now use $page->image
-
It's not different between frontend and admin - I just used that in my screenshot to show the as-yet-unsaved image. So you do have to watch out for it in template code too. Suppose you have a busy site and you're using getUnformatted() in your template code. If a website editor accidentally uploads the wrong image (you can imagine some worst-case scenarios here!) but then notices before they save the page, that temporary image might have already been displayed and viewed on the frontend via getUnformatted().
-
True, but just want to point out there can be occasional "gotchas" when doing this because PW sometimes returns things that may be unexpected in the unformatted value. For example, the unformatted value of a Page Reference field will include unpublished pages and the unformatted value of a Repeater field can include "ready" items that are not populated in Page Edit. And in the case being discussed here the unformatted value of an images field can include "temporary" images that have been uploaded in Page Edit but the page has not yet been saved. So in the example below the frog image is saved but the fish image has just been uploaded but not yet saved, and might yet be abandoned before saving because of being a mistake or unwanted. Yet it appears in the unformatted value:
-
This is great, thanks @MoritzLost for taking the time to write this up and share it with us. Although I don't agree with all the points (e.g. I think the PW emphasis on tree/hierarchy is a pro rather than a con) it's really interesting and useful to get an insight into how other CMSs solve problems and bring value to their users. I'm not sure if Ryan feels the same, but speaking as a person who enjoys developing modules and tools: eventually the limiting factor becomes ideas. That is, the will is there to keep creating useful things but the challenge is knowing what will consititute a useful thing to the audience. So getting user requests and descriptions of pain points is what's needed to keep the wheels turning. Regarding the Craft/PW comparison... You did state this clearly at the outset but I want to really emphasise this because it's such a major factor: the difference in cost between Craft CMS and ProcessWire is massive. I did a conservative estimate of the net income I would have lost as a solo developer over the last 5 years if I had have built all of my projects with Craft/plugins rather than PW/modules. It's approximately USD $43,000. For someone in my position that is just huge. Maybe I could have successfully added those Craft costs into the quotes but then maybe I would have lost many bids if I had done that. In general, if you think about the difference between something that's free and something that costs upwards of $299 it should be no surprise if there are some advantages to the thing that costs you $299. In fact it would be outrageous if you paid $299 for a thing and it was worse or no better than a free alternative. Suppose I would like a drink and I'm choosing between the free option (a bottle of tap water) and the $299 option (a bottle of Dom Pérignon champagne). The champagne should be a better experience than the tap water. That's why it costs $299. But when we bring this analogy back to PW/Craft, it's like ordering a bottle of tap water and then having the pleasant surprise that it's a very nice méthode traditionnelle. Maybe not quite as good as the Dom Pérignon, but at $0 that's extraodinary value and a lot of people would say it's the better choice for them. For the types of projects I use PW for, I have the occassional niggle but it's very minor stuff. Although I'd love to see PW match all the features of all its commercial competitors I also think it's reasonable to take the position that a free product is not going to be all things to all people. I actually wish there was more clarity about the kind of developer and kind of projects PW is targetted towards. In my opinion, narrowing the focus of PW and clearly communicating this at processwire.com would be a step in the right direction. Even if this was somehow expressed in negative terms, e.g. Don't know what a foreach loop is? Other tools will suit you better than PW. Looking for themes? Other tools will suit you better than PW. Looking for "a plugin for everything"? Other tools will suit you better than PW. Part of a large development team? Other tools will suit you better than PW. Building "enterprise" applications? Other tools will suit you better than PW. Working on projects with budgets in the mid-five-figures and higher? Don't be such a cheapskate, get out your chequebook because other tools will suit you better than PW. The way I see it, the person who will get most value and satisfaction from PW is a solo developer with at least intermediate experience (or a willingness to get there), working on projects that have demands that go beyond the basic but where the budget is somewhat limited. The main benefit that I get from PW is that I can build surprisingly powerful sites and build them fast so the hours/costs are kept down. This is the PW sweetspot and I think we should lean into it.
- 23 replies
-
- 23
-
@rick messaged me asking for advice about how to use dependent selects in a module config. That is, where the options of one select change depending on what is selected in a another select. I thought others might also find this info useful so I've put together a demonstration module: https://github.com/Toutouwai/DemoDependentSelects The general idea is that the dependent (target) select needs to include all the possible options, and then the options are hidden or shown by JavaScript depending on what is selected in the source select. See the source code for comments.
- 6 replies
-
- 15
-
As far as I can see it's working as per the documentation for the method - wireRenderFile() just calls $files->render(): https://processwire.com/api/ref/wire-file-tools/render/ If you do set an additional allowed path (which in your case you don't need to do because files within /site/modules/ are allowed by default) then the allowedPaths option needs to be an array of extra allowed paths.