• Content count

  • Joined

  • Last visited

Community Reputation

34 Excellent

About LMD

  • Rank
    Jr. Member

Profile Information

  • Gender
    Not Telling

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. LMD

    $page->references() is a great addition - I can immediately see it being use for tagging systems. I would like to now if it is, or maybe will eventually be, possible to use 'references' within a selector. For example: // Find all the tags and sort them by the number of references to each tag. // When looping through the results, the tags are in order of the most references (ie, most used tags) first. $all_tags = $pages->find('template=tag, sort=-references.count');
  2. @Macrura - ordinarily I would do that, but this is a little freebie site for a group of very non-tech savvy people (a favour for my mother). I feel it would be much easier for them to drag-n-drop their photo gallery pics into a single field, then edit the photo info and press save once. Even a repeater would be a bit too much. I will monitor the siutation though and if I think they can deal with it, will switch to a one-page (or repeater item) per photo (thanks to the API, converting will be no problem!). @dragan - I wonder if you see a label because you are using multi-language? It is definitely not visible in my single language version, althpough it is present, just hidden with CSS ('pw-hidden' class). In fact, if somebody is happy with the default label "Description", then it would be possible to override it in a custom admin CSS file, but I want to change the text itself. However -- ta daaa! -- after digging around Captain Hook, I have found a simple solution using a hook in ready.php This is very specific to my needs -- but it could be made more generic. $pages->addHookAfter('InputfieldImage::renderItem', function (HookEvent $event){ $obj = $event->object; if ($obj->name != 'quilt_images') return; // stop if the field isn't the specific one we want $rtn = $event->return; // get the return value // The string we are looking for (regex because the unique ID part in the label's 'for' attribute) $regex = "/<label for='description_quilt_images_([^']+)' class='detail pw-hidden'>Description<\/label>/i"; // What we want to replace it with (remove the 'pw-hidden' class and change label text) $replacement = "<label for='description_quilt_images_$1' class='detail'>Give a brief description/title for the quilt.</label>"; // Do the replacement $newRtn = preg_replace($regex, $replacement, $rtn); $event->return = $newRtn; // replace return value with new string }); And the result:
  3. Well, although I am using Image Extra in my example, I'm talking about the core image description field, which has no label. I'd like to be able to add a label to it regardless of whether I'm using the Image Extra module.
  4. I'm wondering if it is possible to add a label to the description input in image fields (in the admin). I'm using the module Image Extra, which has labels for each input, but I'd like to add a label to the default 'description' input too. The image below illustrates this: If there is no way (no hook?) then, I suppose I could just not use the default description and add a new description input with the Image Extra module. But I thought I'd ask in case I (or others) ever want to do this without using the module (i.e. just the one input required). I'm using PW 3.0.98 Thanks. --- FYI: yes, that is a cat and not a quilt -- this is on my local dev server and I don't have the actual photos yet! She is on a quilt, so it counts... technically.
  5. I am doing something very similar to this and am just using pages. I use two templates: 'newsletters_parent' and 'newsletters_child'. The 'newsletters_parent' is the container and onyl has a title, but its settings on the "Family" tab are: Can have children: YES Can be used for new pages: ONE Allowed template(s) for children: newsletter_child Name format for children: Y/m/d H:i:s (the page creation date/time -- this will get overwritten at a later stage) Sort settings for children: pub_date (a field that will be added to the newsletter_child page) Reverse sort direction: CHECKED (yes) The 'newsletters_child' template has the following fields: title (default and required by all templates) pub_date (a datepicker field set to YYYY-MM-DD -- the publication date might not necessarily be the same as the date the file was uploaded!) pdf_file (file-upload field, single file only, and also set to only allow PDF files) The settings ("Family" tab) for the child template are: Can have children: NO Can be used for new pages: YES Allowed template(s) for parents: newsletter_parent Show in the add-page shortcut menu: YES To make the process of adding a new newsletter as easy as possible for users -- all they have to do is select the file to upload and the pick the pub date -- I use a couple of hooks hook in the site's ready.php file: The first hook adds dummy text to the page title field on page creation so that the user doesn't have to enter anything (if it is left blank, it will throw an error) -- the proper title, along with the page name will be created from the pub_date field when the page is saved. The second hook also creates the actual page title and the sets page name based on the supplied 'pub_date'. [NOTE: the newsletters only get published once a month, so we only use the Year/Month in page names/titles.] /** * 1. Set a dummy title on page save at creation, to prevent the required field showing an error if it is blank. * (Requires the parent template option 'Name format for children' to be set) * 2. Modify newsletter title and page name from pub_date before saving. */ $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); // Only on newsletter_child templates where the title is blank (on page creation) if ($page->template->name == 'newsletter_child' && $page->title == '') { $page->title = 'Newsletter'; // a dummy title, will be replaced at a later stage } // Only on newsletter_child templates with a pub_date if ($page->template->name == 'newsletter_child' && $page->pub_date) { $newName = wire('sanitizer')->pageName('newsletter-' . date('Y-M', $page->pub_date), true); $newTitle = date('F Y', $page->pub_date); if ($page->title != $newTitle) { $page->title = $newTitle; } if ($page->name != $newName) { $page->name = $newName; } } }); Thiis then makes it easy to search the system for whatever you want: // All newsletter files (no limit applied) $allNews = $pages->find('template=newsletter_child, sort=pub_date'); // ascending order (earliest first) $allNews = $pages->find('template=newsletter_child, sort=-pub_date'); // descending order (most recent first) // All newsletters from a particular year (e.g., 2017): $yearStart = strtotime('2017-01-01 00:00:00'); $yearEnd = strtotime('2018-01-01 00:00:00'); $yearNews = $pages->find("template=newsletter_child, pub_date>={$yearStart}, pub_date<{$yearEnd}, sort=-pub_date"); // The most recent newsletter: $mostRecent = $pages->findOne('template=newsletter_child, sort=-pub_date'); // Accessing the file itself (using $mostRecent) if ($mostRecent->pdf_file) { $file = $mostRecent->pdf_file; $downloadLink = "<a href='{$file->url}'>Download the newsletter: {$mostRecent->title}</a> ({$file->filesizeStr})"; } That's all there is, really. There is lots you can do with the system.
  6. LMD

    I've been using this field and appreciated the string of page IDs for PW pages. I'm wondering if instead of converting the ID to a URL before returning it, how about returning an object? So, Instead of $page->AssistedURL returning just a string "/mypage/" (internal) or "http://www.anothersite.com/" (external), it returns the object: // Internal PW page { 'id' => 1234, 'name' => 'mypage', 'url' => '/mypage/', 'httpUrl' => 'http://my-processwire-root.com/mypage/' } // External link { 'id' => 0, // 0 or null 'name' => '', // blank or null 'url' => 'http://www.anothersite.com/', 'httpUrl' => 'http://www.anothersite.com/' // url and httpUrl are the same for external links } // Accessing the data $page->AssistedURL->id $page->AssistedURL->name $page->AssistedURL->url $page->AssistedURL->httpUrl For backwards compatibility, could $page->AssistedURL by itself be a magic method to return the URL as it currently does? By returning relative and absolute links, the same field could be used in multiple situations (eg, on an internal menu, and in an email template).
  7. LMD

    Couldn't you just use radio selects, with two options (with whatever labels you need), make it required and have one of the radios selected by default?
  8. Adding a 'class' attribute to an element is different to adding other attributes, you add either allowed class names or a '*' wildcard within parenthesis. // Allow *any* class name img(*) // Allow only specific class names img(align_left,align_right) // In your case (assuming any class name) it would be: a(*) Here's the CK Editor docs for Allowed Content rules: https://docs.ckeditor.com/#!/guide/dev_advanced_content_filter https://docs.ckeditor.com/#!/guide/dev_allowed_content_rules
  9. LMD

    Thanks, @kongondo - the fix works perfectly.
  10. LMD

    Hi @kongondo - I'm still getting an issue with HTML in the menu item titles, where quoted attributes (e.g., class names, such as those used FontAwesome icons etc) get garbled in the title's input field. I did mention a very simple fix earlier in this topic, but it may have got overlooked. Would it be possible to apply this fix to the module: In the ProcessMenuBuilder.module file, on line #1158 (in the listMenu() menthod), surround the $title variable with the htmlentities() function: // Change line #1158 from: <input type="text" value="' . $title . '" name="item_title[' . $id . ']" class="menu_settings" id="item_title' . $id . '"> // To: <input type="text" value="' . htmlentities($title) . '" name="item_title[' . $id . ']" class="menu_settings" id="item_title' . $id . '"> It immediately fixes the HTML display issues witin the input field. Thanks.
  11. LMD

    And I've now tested it too, and it works perfectly. Thank you @Robin S
  12. LMD

    @Robin S Jonathan's concern regarding the stability of 'IDs' vs. 'text' was one of my concerns. After thinking about it, I was going to suggest if a hookable method was possible, so this makes me happy. I'll try it out today and report back!
  13. LMD

    After using this module for a while, I have a couple of suggestions for future modifications. First, would it be possible to skip the dialogue window (or auto-close it) if the Hanna code being added does not have any attributes set? It could still have the on-click behaviour after being added (with the "This tag has no editable attributes" message), to future-proof the tag should the user add attributes in the future. Obviously, one could just type the Hanna code, but it is more convenient for clients to pick it from a list. Secondly, this isn't really a suggestion, but a custom modification I made to the code for my own purposes, which might be useful to others. When using selectable option fields (selects, radios, etc), the current method to set the different options is simply: attribute__options=Option A|Option B|Option C // The option string format is the same for dyanamically generated options. With this method, the option field input 'value' and 'text/label' are the same. However, I found that this was not very user-friendly when the options are somewhat cryptic. Eg, from a returned file list: file123-xyz.pdf abc-1978.pdf xyz-blah123.pdf really-long-title-2017-05-apple-blueberry-banana.pdf So, what I did was modify the foreach loop code in the file 'iframe_form.php' at line #63, to make it possible to have a separate input value and text. /* Original code at line #63 in iframe_form.php */ foreach ($select_options as $select_option) { $f->addOption($select_option); } /* My own modification * - Searches the option value for '@@' * - Uses it to split the string into two variables: $optionValue and $optionText * - Then adds the option to the select field. */ foreach ($select_options as $select_option) { if (strpos($select_option, "@@") !== false) { list($optionValue, $optionText) = explode("@@", $select_option); $f->addOption($optionValue, $optionText); } else { $f->addOption($select_option); } } Now, when setting the options, you specify them (either directly or dynamically) by separating each option's value and text/label with '@@' (chosen because it's unlikely to be part of an option value or text): attribute__options=file123-xyz.pdf@@Annual Accounts 2016|abc-1978.pdf@@Some Meaningiful Title|xyz-blah123.pdf@@Another Meaningful Title| really-long-title-2017-05-apple-blueberry-banana.pdf@@The Price of Fruit May 2017 // Note: in reality the above options would be generated dynamically. I would make a pull request (?) via GitHub for this, but I've never used it for such a thing and don't really know how.
  14. LMD

    @Robin S Yes, it's fixed, thank you!
  15. LMD

    I've been doing something very similar -- might I suggest a small change to the page selector to eliminate the need to check for the current page in your foreach loop? // Find the pages that use the specified tag -- and ensure the current page is excluded $articles = $pages->find("template=basic-page, id!={$page->id}, tags.title=$tag, limit=8"); This way, you always get 8 results (if there are that many, of course), whereas excluding page from the loop would leave you with 7 pages.