Jump to content

BillH

Members
  • Posts

    221
  • Joined

  • Last visited

  • Days Won

    4

Posts posted by BillH

  1. Hadn't read your original post properly 🙁

    Just another thought: do you need to use datetime fields?

    If there are a fairly limited number of possible start and end times during the day, you could set up pages for each time, and select using page reference fields. The time pages could have fields with formatted and numerical representations of the time.

    To find pages in a time range, you'd find the relevant time pages, and then use those to find the courses, something along the lines of this:

    $startTimes = $pages->find("template=times, time>=1200, time<=1400");
    $endTimes = $pages->find("template=times, time>=1500, time<=1700");
    $courses = $pages->find("template=course, start_time=$startTimes, end_time=$endTimes");

    Not tested, but I think it'd work.

  2. I think the information you need is in this post:

    So, in brief, the values in a selector should be UNIX timestamps.

    Note that, in a template, if you get a date from a field it will be formatted according to the settings for the field, but you can use $page->getUnformatted('your_date_field') if you need the timestamp.

     

     

  3. When you say you have deleted the cache, do you mean your browser cache or PW cached files?

    If you haven't cleared PW cached files, they're at Site > Assets > Cache, and it's probably just the ones in Page that might be relevant. You can simply delete everything in the folder.

    Alternatively, you can clear cached page output by going to Modules > Core > PageRender > Settings.

    I don't know if this will help, but it's worth a try.

  4. You need to check whether there's something in the end date field.

    Then, if you're going to use the value in a function, you need to give it a suitable value if there's nothing in the field. For example:

    if ($single->End_date) {
        $end = date('d. m. Y', $single->getUnformatted('End_date'));
    } else {
        $end = date('d. m. Y', 0); // This would be 01.01.1970, but you might want something in the future
    }

    I also note that you are getting the unformatted dates from the fields and then formatting them again with the date() function. As you are just comparing values (at least in the code you have posted), you could simply use the values from the fields, or the unformatted value if it's easier to work with UNIX times.

    And you have $today == $start twice in your first 'if' condition!

    • Like 1
  5. Trying to manage folders yourself would be seriously hard work and difficult, as discussed in this post:

    If a high proportion of your pages don't have images, and the total number of images is well under half the number of pages, you could take a one-image-per-page approach, with each image held in sub-page.

    A couple of modules that might help with this are:

    https://modules.processwire.com/modules/repeater-images/

    https://modules.processwire.com/modules/process-visual-page-selector/

     

  6. The idea from @Ivan Gretsky of using template tags (which are on the Advanced tab of Edit Template) seems like a really good one.

    An approach to searching for tags on templates is here:

    Another possibility would be to prefix each relevant template name (e.g. "prefix-templatename") and then find using the "starts with" operator:

    $foundPages = $pages->find("template^=prefix");

    But I think the tags approach would probably be better – more flexible, and organises things nicely on the Templates page in the admin.

    • Like 3
  7. Thanks for the suggestion @Robin S

    Seems like a nice way of doing it. There no risk (however remote) of accidentally replacing something that shouldn't be replaced, and it's more resilient to change. And I suspect there are going to be more requests to change labels and the like in future, so this could be a good approach for keeping things well organised.

  8. Hanna Code may well be a good approach.

    Another option, if there's some way to logically deduce what classes should be added based on how an image is included in CKEditor or the like, would be to use PHP in the template to add the classes.

    Or if this was applicable to multiple fields or templates, you could look into writing a textformatter module to apply the classes (not difficult if you start by copying a simple one).

    If each image will always be handled in the same way, an option might be to use image tags (https://processwire.com/docs/fields/images/) and then use PHP in the template (or a textformatter) to apply classes based on the tags.

    Note that it's probably the CKEditor Advanced Content Filter (ACF) that's stripping out the classes - you could test by turning it off on the Input tab for the field. If it is ACF, then look at Extra Allowed Content (a bit further down on the Input tab). But you probably don't want to be editing the HTML by hand anyway.

  9. Many thanks @dragan, that works fine.

    The View tab is very slightly complicated by having a dropdown menu, so in case it's useful for anyone, here's a version that deals with that (changes "View" to "Preview"):

    wire()->addHookAfter("ProcessPageEdit::execute", function($event) {
    
        $render = $event->return;
        $template_name = "basic-page"; // Change to the relevant template name
    
        if (false !== strpos($render, "template_{$template_name} ")) {
            $render = str_replace("View<span id='_ProcessPageEditViewDropdownToggle'", "Preview<span id='_ProcessPageEditViewDropdownToggle'", $render);
            $render = str_replace("Exit + View</a>", "Exit + Preview</a>", $render);
            $event->return = $render;
        }
    
    });

    Replacing just "View<span" would probably be enough, but perhaps there's a tiny risk it'd be in a rich text field as well.

  10. I'm trying to change the name of the View tab (client request) and can't work out how to get at the label property.

    The closest I've got to it is the url property.

    I've tried many things, including this:

    $this->addHookAfter('ProcessPageEdit::buildFormView', function($event) {
        
        $arguments = $event->argumentsByName();
        bd($arguments);
        // Result: only 'url'
        
        $viewTab = $event->return;
        bd($viewTab);
        // Result: null
    
    });

    And this:

    $this->addHookAfter('ProcessPageEdit::buildForm', function($event) {
        
        $form = $event->return;
        $viewTab = $form->find("id=ProcessPageEditView")->first();
        bd($viewTab);
        // Result: false
    
    });

    Does anyone know what I should be doing?

  11. Your approach seems a good one.

    I don't know how you've configured things, but in similar circumstances I have usernames based on email addresses. As ProcessWire usernames are page names (mostly this just means replacing the @ with a hyphen), the following works for me:

    $email = $this->sanitizer->email($input->post->username);
    $username = $this->sanitizer->pageName($email);

    Sanitizing the email address might be a small improvement to your approach.

     

  12. For a basic approach:

    $breadcrumbs = $page->title;
    foreach($page->parents() as $parent) {
        $breadcrumbs = "<a href='{$parent->url}'>{$parent->title}</a> / " . $breadcrumbs;
    }

     

    • Like 3
  13. 2 hours ago, Dean said:

    Notice: Undefined variable: pages
    Fatal Error: Uncaught Error: Call to a member function find() on null

    Ah, sorry, you probably want:

    $traders = $this->pages->find($selector);

    Regarding the sorting, very good points from @Jan Romero.

    I'd add that it's not necessarily the case that sorting by relevance would produce results that are particularly useful for users. It'd depend on the nature of the data and so on. If you want to read how it's done, it's described on https://dev.mysql.com/doc/internals/en/full-text-search.html, but it'd be a major project in itself figuring it all out!

    And one suggestion: if you're not anticipating too many results, it can take an acceptable amount of time to produce a results array, loop through the array adding a sort criterion (such as a relevance score), and then sorting by that criterion.

     

     

    • Like 1
  14. Some good suggestions from @Jan Romero.

    If you're still interested in exploring the ProFields Table approach, there is actually a possible way of handling the files.

    Make a template (without a file) to hold files, and load the files, one per page. Then use a Page type in the Table to hold a link to the relevant page.

    The added complexity of this approach might make it unsuitable, but you may be able to think of a good way of arranging things. And on the plus side, you can easily add extra data fields to the files (dates, source, etc) if that's useful.

     

     

  15. I've no definitive answer, but my thoughts are these.

    The data appears to have a clear hierarchy, so if there'll be no complications you haven't mentioned, using either standard pages or repeaters or tables would all be OK as data structures.

    When it comes to building templates, all three approaches are more or less as easy as each other.

    The approach you choose should thus probably be governed mainly by making things as easy as possible for users.

    For the pages on which items are displayed in tables (Netti in your example), using a repeater would get everything onto one page, thus matching the site and making navigation in the backend significantly easier.

    Using a ProFields Table would have the same benefits as a repeater, and additionally would give a really clear, neat, compact result. This might well be the nicest option (so long as there's a small amount of budget available to cover the licence).

  16. Just my personal view, but PW isn't an MVC framework, so trying to make it behave like one doesn't really sound like a good plan. My guess is that you'd end up making things very difficult for little benefit. I'd suggest going about projects in a PW-like way unless there's a particular reason not to.

    For testing, there are lots of tools out there, e.g. https://www.cypress.io/, and you might find this module useful: https://modules.processwire.com/modules/process-nette-tester/

    And I'd strongly recommend this module: https://modules.processwire.com/modules/tracy-debugger/

     

  17. I'd start in findTraders() by changing the fourth-from-last line to:

    $traders = $pages->find($selector);

    Then it'd be worth reviewing https://processwire.com/docs/selectors/#sort. In particular note the advice in the section about what happens if you don't specify a sort: "it is generally a good idea to include a sort=property when using $pages->find()". At least it'd be worth trying with sorting in all cases, which could narrow down the issue.

    Another possible place where things could go wrong is the loop that renders the results, represented by "..." in your last post. But if it's a simple foreach loop, it should be OK.

    By the way, when debugging searches I find that printing the result array, which is a PW PageArray, can help with understanding what's going on. For example:

    echo "<pre>".print_r($traders, true)."</pre>";

     

  18. Have you looked in the errors and exceptions logs? They might give you a clue about what's happening.

    And you've probably thought of this, but it might be worth turning the modules off to see what happens.

    This thread might give you some other ideas, particularly if it turns out the issue is that the sessions time out:

    Two things to note. The first is that, from memory (though I might be remembering wrongly), the issue was worse with Chrome. Second, as the last post in the thread says, I never worked out what the problem really was, but a new PW installation did the trick in the end.

×
×
  • Create New...