Jump to content

Robin S

Members
  • Posts

    4,791
  • Joined

  • Days Won

    303

Everything posted by Robin S

  1. I think you want something like this: // Get all the tags that are used in this client's videos $tags_in_use = new PageArray(); foreach($client->videos as $video) { $tags_in_use->add($video->tags); } // Sort the tags if you like $tags_in_use->sort('title'); // Output the used tags in the sidebar foreach($tags_in_use->sort('title') as $tag) { // ... }
  2. When you enable device mode in the dev tools the user agent will change and therefore the fingerprint will change. I solve this when developing locally with the following in config.php: if(in_array($_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1'])) { $config->sessionFingerprint = false; } If you're working on a remote site and don't want to change the fingerprint settings then you can use an incognito window when viewing the front-end in device mode.
  3. Not sure why that is. Seems strange considering that system fields can be added by users in the Columns tab. You can use a hook to set the columns and default sort: $wire->addHookBefore('ProcessPageLister::execute', function(HookEvent $event) { /* @var ProcessPageLister $lister */ $lister = $event->object; // Only for Users lister if($lister->parent->id !== 29) return; // Include "created" in default columns $lister->columns = [ 'name', 'email', 'roles', 'created', ]; // Set default sort $lister->defaultSort = '-created'; // Optional: allow user to change sort but reset to default sort each time Access > Users is visited if(!$event->wire()->config->ajax) $lister->sessionSet('sort', ''); });
  4. FieldsetPage fits that description and is part of the core: https://processwire.com/blog/posts/processwire-3.0.74-adds-new-fieldsetpage-field-type/
  5. An old topic but I just hit this problem too, where I want to give an example of Markdown format in the field description without that actually being converted into HTML. I solved it by setting the Inputfield textFormat property in a hook: // Avoid Markdown in description/notes being converted into HTML // Adjust as needed for your Inputfield type and field name $wire->addHookAfter('InputfieldTextarea::renderReadyHook', function(HookEvent $event) { /** @var InputfieldTextarea $inputfield */ $inputfield = $event->object; if($inputfield->name === 'my_field_name') { $inputfield->textFormat = Inputfield::textFormatNone; } });
  6. You can learn from studying the Helloworld module: https://processwire.com/modules/helloworld/ From the readme:
  7. I don't think there is any module that does exactly what you're asking about, but I expect it wouldn't be that hard to achieve without needing any module. We probably need to hear a longer explanation of what you're wanting to do. If the pages of the "book" can be grouped together in the tree in the form... Book title - Chapter ...or... Book title - Chapter -- Subsection --- etc ...then you can create your navigation links using $page->children(), $page->next(), $page->prev() etc. Or if the pages are scattered throughout the site but need to be grouped together for use in a book then you can use a Page Reference field to select all the pages that make up the book. As the book is browsed you can keep track of the fact the visitor is viewing the pages as a book by passing a URL parameter on each navigation link like ?book=my-book-title and this will let you work out the previous and next pages for use in the navigation. If you want to divide the long text into multiple pages on save then you can use a Pages::saveReady hook to parse the HTML and find the tags that you want to split on, then create new pages with the split content using the API. Or if you want to keep the long text in one piece but paginate it on the front-end then you could take a look at TextformatterPagination.
  8. I don't think FieldtypeComments will be able to support those because they require their own dedicated fieldtypes to hold the data. So you would need to create a custom form to handle those, and if the images / page reference needs to be connected with individual comments then you probably need a totally custom comments implementation where you use a page-per-comment behind the scenes. But coming back to the original issue: one way you could work around this is to list all the comments on the parent page, but if a person wants to add a comment they click a link to submit the comment on the child page. If that child page should only be used to submit a comment and not to display any other information then you could use a URL parameter (or alternatively a URL segment) in the link and if the page is loaded without that parameter it redirects back to the parent page. So in the parent page template: <?php foreach($page->children as $child): ?> <h3><?= $child->title ?></h3> <?= $child->comments->render() ?> <a href="<?= $child->url ?>?submit_a_comment=1">Submit a comment</a> <?php endforeach; ?> And in the child page template: <h3>Submit a comment</h3> <?php // Show the comment form echo $page->comments->renderForm(); // If the submit_a_comment URL parameter is not present then redirect to parent page // This must go after the form render so that comment submissions will be processed before redirecting if(!$input->get('submit_a_comment')) $session->redirect($page->parent->url); ?>
  9. @marie.mdna, I tested and can confirm the problem when there are multiple comment forms relating to different pages all rendered on the same page. I'm not sure if FieldtypeComments is intended to support that sort of use but I don't see why it shouldn't. I suggest opening a GitHub issue for this so Ryan can take a look. https://github.com/processwire/processwire-issues/issues
  10. Welcome to the PW forums @marie.mdna! I suspect that the problem is caused by the wrong page ID being set in the hidden page_id field of the comment form. You could try manually setting the hidden fields by replacing... ...with... <input type='hidden' name='page_id' value='{$post->id}' /> <input type='hidden' class='CommentFormParent' name='parent_id' value='0' />
  11. Then you'll want to get the PageArray of selectable pages as shown in the earlier hook: $selectable_pages = $page->getInputfield('your_page_reference_field')->getSelectablePages($page); Then you can use ->eq() to get any item in the PageArray by its index/position, and use a switch statement to do different things accordingly. // Get all the selectable pages that apply when "your_page_reference_field" is used on $page $selectable_pages = $page->getInputfield('your_page_reference_field')->getSelectablePages($page); // Compare the value of $page->your_page_reference_field against the pages in various positions of $selectable_pages switch($page->your_page_reference_field) { case $selectable_pages->eq(0): // The first selectable page is selected require ('assets/bookingstatus/bookingstatus_step1.inc.php'); break; case $selectable_pages->eq(1): // The second selectable page is selected require ('assets/bookingstatus/bookingstatus_step2.inc.php'); break; case $selectable_pages->eq(2): // The third selectable page is selected require ('assets/bookingstatus/bookingstatus_step3.inc.php'); break; default: // Some other page is selected so handle that scenario... }
  12. 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) { //... }
  13. 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...
  14. 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); });
  15. 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?
  16. 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>
  17. 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:
  18. Try instead: template=faq-category, parent=page.parent.parent, sort=sort
  19. @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:
  20. 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.
  21. 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; }
  22. 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)
  23. 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; } });
×
×
  • Create New...