Jump to content

Robin S

Members
  • Posts

    4,795
  • Joined

  • Days Won

    303

Everything posted by Robin S

  1. Not sure I understand the question, but if you have a Page object (e.g. $page, $my_page) and you want to match it to a Page Reference field in a selector string the best way is to match by the page's ID. my_page_reference_field=$page->id Or you can actually just do... my_page_reference_field=$page ...because a Page object becomes an ID when it is treated as a string. Similarly a PageArray will become a pipe-separated string of IDs that can also be used directly in a selector string: my_page_reference_field=$my_page_array
  2. This assumes that the "category" field allows for selection of a single page: $results = []; foreach($user->favorite as $item) { $category = $item->category->title ?: 'Uncategorised'; $results[$category][] = $item; } foreach($results as $category => $items) { echo "<h3>$category</h3>"; echo "<ul>"; foreach($items as $item) { echo "<li><a href='$item->url'>$item->title</a></li>"; } echo "</ul>"; }
  3. Thanks @MoritzLost for the detailed post. One thing I don't understand and am hoping you might explain is how Craft handles field renaming within the project config file. Do the config files refer to fields by ID, name, or something else? It seems like IDs couldn't be used in the config because if the IDs auto-increment as fields are added then they wouldn't be consistent between installations. But if names are used instead of IDs then how is it declared in the config that, say, existing field "date" was renamed to "post_date", versus field "date" was deleted and a new field "post_date" was created? Because there's an important difference there in terms of whether data in the database for "date" is dropped or a table is renamed.
  4. The most common way to use the "Add New" feature is by defining "Allowed template(s) for children" and "Allowed template(s) for parents" on the templates in question. See the information in the screenshot below: When you have this configured then you can quickly add new pages of the child template via the "Add New" button and menu link. The "Bookmarks" feature applies when you haven't defined allowed parent/child template settings, but you want a shortcut to add a new child page under some specific parent page. So if you had some deeply nested page that you often want to add new child pages under you could set a bookmark for that parent. Clicking the bookmark would then be the same as opening the page tree to that parent and clicking "Add", but it would perhaps save you some time. It's not a feature that I've found all that useful in practice.
  5. Well, I couldn't help myself. ? Plus it wasn't as bad as I expected. @Didjee, the insert buttons and other features from Repeater Matrix v7/8 should work in the newly released Restrict Repeater Matrix v0.2.0.
  6. It's not just the new insert before / insert after features, it's also all the new options for adding items that would need attention. It looks like a lot of work to support and probably it still won't work reliably for all the options, e.g. custom. Sorry, but it's unlikely I'm going to get around to spending the time on this in the foreseeable future. It's probably not practical for a module like Restrict Repeater Matrix to exists when the base module (Repeater Matrix) can be changed at any point. Repeater Matrix is a commercial module so Ryan should be responsive to the needs of its users - I suggest submitting requests to Ryan for the features you want to see. I'll add a note at the top of the readme about the incompatibility with recent updates to Repeater Matrix.
  7. Fair enough, I've added support for more custom labels in v0.2.1.
  8. I can't reproduce that. The column configuration I used for testing: Screencast: Is pagination turned on for your Table field by any chance? Can you provide steps for a basic test case where the problem occurs?
  9. I agree that the drag cursor isn't needed here. I don't like the idea that any click on the image would delete it, but what I've done in v0.2.0 is that when the max items is set to one and an image is already selected in the inputfield then the button is labelled "Replace image..." so that the next selected image will replace the existing image with a minimum of clicks.
  10. You could use Option C: https://processwire.com/docs/front-end/front-end-editing/#option-c-html-edit-tags <edit field="title,link,text" page="4302"> ... </edit>
  11. The trick is to put all the affected images into a new Pageimages object before you start setting the field values, so you can later get each image from there even after it has been removed from a field value. A proof of concept... Image fields in Page Edit: Tempate file markup: <script src="/site/templates/js/jquery-ui.min.js"></script> <script> $(document).ready(function() { var $sortable_images = $('.sortable-images'); $sortable_images.sortable({ // When any image has been moved... update: function(event, ui) { // Add the image basenames to an array in the new order var value = []; $sortable_images.find('img').each(function() { value.push($(this).data('filename')); }); // Join to a comma separate string and set as the form field value $('#images').val(value.join(',')); } }); }); </script> <div class="sortable-images"> <img src="<?= $page->image_1->size(150,150)->url ?>" data-filename="<?= $page->image_1->basename ?>" alt=""> <img src="<?= $page->image_2->size(150,150)->url ?>" data-filename="<?= $page->image_2->basename ?>" alt=""> <img src="<?= $page->image_3->size(150,150)->url ?>" data-filename="<?= $page->image_3->basename ?>" alt=""> </div> <form id="image-order" action="./" method="post"> <textarea name="images" id="images"></textarea> <button>Submit</button> </form> Template file PHP: // Look for the comma separated value in POST $images_value = $input->post('images'); // If the value exists then the form was submitted if($images_value) { // Explode the comma separated value to an array of image basenames $image_names = explode(',', $images_value); // Create a Pageimages object using the individual image basenames $all_images = new Pageimages($page); foreach($image_names as $image_name) { $all_images->add($image_name); } // Turn off output formatting because we are about to set field values $page->of(false); // Loop over the image basenames foreach($image_names as $index => $image_name) { // Get the Pageimage from $all_images $pageimage = $all_images->get($image_name); // Create a new empty Pageimages object $pageimages = new Pageimages($page); // Add the Pageimage $pageimages->add($pageimage); // Determine the field name that will be updated $image_field_name = 'image_' . ($index + 1); // Set the field value $page->$image_field_name = $pageimages; } // Save the page $page->save(); // Redirect back to the page (Post/Redirect/Get pattern) $session->redirect($page->url); }
  12. Sounds good to me, because although the cached pages are expected when you know how PW goes to the cache first before loading pages from the DB this might not be common knowledge and the expectation is probably that the Console is a "blank slate".
  13. You nailed it! I was trying that code from the Tracy Console while viewing the page in Page Edit, and so must have been getting the cached version of the page that was already loaded. If I use the Console on a different page or preceed the code with $pages->uncacheAll() then it works as expected. Thanks!
  14. Hi @adrian, I think this probably isn't a Tracy issue as such but I thought you might have some insight on it... If I edit a field's settings (in this case the headline field) and set it to Autojoin then when I get a page whose template has that field then I can see the field value loaded on the Page object. But if I don't set Autojoin in the field settings and instead I set the field to join for a specific find() operation then I don't see the field value loaded on the Page object. (I'm using $pages->get() here but I think it is the same behind the scenes and I also tried $pages->find() and found the same issue). Or the older way: If I request the field value before I dump the Page object then it is loaded. I'm puzzled about why this is. Surely if the field value is joined during the find() then it must be stored somewhere on the Page object? Do you know if PW is storing these joined values somewhere that is invisible to Tracy? Or is this maybe a sign that there's a core bug and the joined fields are not actually being preloaded as expected?
  15. @prestoav In the newly released v0.1.3 there is a config option to prepend $config->urls->root to URLs that start with a forward slash.
  16. @ryan, thanks for this week's updates! @MoritzLost has sparked an interesting discussion about using PW with version control and he makes a comparison with Craft CMS. A couple of excerpts from his comments: Ryan, it would be great to get your voice in the discussion. We're at the beginning of the new year so what do you think about putting better compatibility with version control onto a roadmap for 2022?
  17. As a general thing to make your life as a developer easier I suggest looking into virtual hosts for local development. That way your local site will be at something like mysite.dev and you can seamlessly move from local to remote without any URL issues. You can use virtual hosts with any LAMP/WAMP/etc, and in particular Laragon will give you an automatic virtual host for every site without needing any configuration.
  18. I added a config field for this in v0.1.1. Let me know if this wasn't what you were getting at.
  19. Lister Native Date Format Allows the date format for "created", "modified" and "published" columns to be set within a Lister or Lister Pro instance. Why? Lister formats the "created", "modified" and "published" columns as relative time strings and doesn't provide an easy way to change this without writing code. Sometimes a value like "3 weeks ago" is not precise enough and you want to see an exact date/time in these columns, perhaps only temporarily before switching back to a relative date. Details An icon is added near the top right of the Lister that reveals a dropdown where you can select from a list date formats that you define in the module config. The Lister will remember your chosen date format the next time you visit the Lister. If you have Lister Pro installed then each Lister Pro instance will remember the date format previously set for that instance. Configuration In the "Date options" field in the module config, enter a list of date formats that are compatible with wireDate(), one format per line. The default date format used by Lister is "rel". You can also set a default date format for native fields which will apply to all Listers that haven't yet had a date format chosen from the dropdown. https://github.com/Toutouwai/ListerNativeDateFormat https://processwire.com/modules/lister-native-date-format/
  20. Another possible way to approach it is to find both normal and repeater pages and then convert the repeater pages into the non-repeater pages that contain them. FieldsetPage is a kind of Repeater. // Function to get the root container page when the supplied page might be a RepeaterPage function getRootContainer($page) { if($page instanceof RepeaterPage) { return getRootContainer($page->getForPage()); } else { return $page; } } // Get your Page Reference field $f = $fields->get('page_selector'); // Get the templates that contain the field (including Repeater templates) $tpls = $f->getTemplates(); // Implode to a string for use in a selector $tpls_string = $tpls->implode('|', 'name'); // Find pages (including Repeater pages) where the field is populated // The check_access=0 is so that Repeater pages are found when $user is a non-superuser $items = $pages->find("template=$tpls_string, check_access=0, $f.count>0"); // An empty PageArray that will hold the results $results = new PageArray(); foreach($items as $item) { // Convert any Repeater pages to their root container page and add to the results $results->add(getRootContainer($item)); } // Now use $results as needed
  21. Personally I would use the admin page name in the URL but not the scheme/domain. So a relative URL but relative to the site root. In your example it looks like the admin page name is "admin" so the URL would be: /admin/page/edit/?id=1016 If you want to get the admin URL dynamically from $config for some reason then you just need to use the CustomAdminMenus::getMenuChildren hook method instead of entering your URLs as plain text in the admin.
  22. Assumes "categories" is a multiple Page Reference field and that you have a hex colour defined on each category page: $wire->addHookAfter('ProcessPageListRender::getPageLabel', function(HookEvent $event) { $page = $event->arguments(0); if($page->template == 'accommodation') { $out = ''; foreach($page->categories as $category) { $out .= "<span class='uk-label' style='background-color:$category->hex_colour'>$category->title</span> "; } $out .= $page->title; $event->return = $out; } });
  23. There's no simple way because the home page is a special case in PW, but some similar topics with suggestions:
×
×
  • Create New...