Jump to content


  • Content Count

  • Joined

Everything posted by LMD

  1. Thanks. I will look more closely at CroppableImage.
  2. @Robin SThank you for a perfectly timed module! I have a wishlist suggestion - as well as the fixed ratios, would it be feasible/possible to also include a minimum size for the crop area? For example, a banner image (used in your own screencast demo) might have a minimum width requirement. It is easy to shrink a larger cropped area, but obviously, a smaller area can not be "embiggened" without pixelation. Maybe it could be specified along with the ratio (e.g., using a comma): Banner Image=2:1,800:400 Technically, you'd only need to specify the length of the longest side.
  3. Oh, sorry, I don't have a RepeaterMatrix field in operation anywhere at the current time.
  4. Works like a charm for me, both outside and inside repeaters. Thank you, @gebeer!
  5. No, it's in my dev environment and I'm the only user (superuser). While I think of it, I also ensured the pages were 'published' and not 'hidden', in case that was the problem (it wasn't).
  6. Hi @gebeer, I tested the update this morning and oops... I don't know what happened this time, but it no longer works at all either inside or outside of a repeater. it just loads a clone of the page currently being edited. It's hard to explain, so this GIF should illustrate what's happening (this is a test outside of a repeater): The above demonstrates the "choose an image from page" and "choose any page" options. The field settings are correct - they are same ones that worked (outside of a repeater) previously. There are images available! I tried the other options (from a folder etc) and exactly the same thing happens. I uninstalled all other modules in case there was a JS conflict and still the same thing happens. In case it helps, here is the console log: I'm using ProcessWire version 3.0.147 and PHP 7.2. Happy New Year! (?)
  7. Hi @gebeer - thanks for this module. I'm having an issue when using it with repeaters, though. Previously I used the "FieldtypeImageFromPage" module which worked perfectly in repeaters, but swapped to this more flexible module and now get the following errors which prevents the field working (no image picker section available -- see screenshot after): Notice: Trying to get property 'data' of non-object in \site\modules\FieldtypeImageReference\InputfieldImageReference.module on line 58 Warning: Invalid argument supplied for foreach() in \site\modules\FieldtypeImageReference\InputfieldImageReference.module on line 58 As you can see, there is no way to pick an image (clicking on the blank area does nothing) -- the field is set-up correctly, because it works outside of a repeater without problems! I think the problem is that the module is getting the field settings data by fieldname, but of course, in a repeater the fieldname is changed to "fieldname_repeater####", causing the issue. It appears to be this line (58) : foreach($this->wire('fields')->get($this->name)->data as $key => $value) { In a repeater, $this->name is looking for "fieldname_repeater####" which returns a non-object, making the foreach bork.
  8. Not quite, that would return pages where only ONE of the search terms is present in any of the fields ("foo" OR "bar"). FIND EITHER "foo" OR "bar" IN title OR FIND EITHER "foo" OR "bar" IN field_a OR FIND EITHER "foo" OR "bar" IN field_b So it would match a page where only "foo" is contained in any (or all) of the fields -- but "bar" must also be present somewhere. Likewise, this would not work either: $selector = "title~=foo|bar, field_a~=foo|bar, field_b~=foo|bar"; FIND EITHER "foo" OR "bar" IN title AND FIND EITHER "foo" OR "bar" IN field_a AND FIND EITHER "foo" OR "bar" IN field_b In this case, "foo" or "bar" must be present in all the fields, which is also not what we want
  9. I don't know if this is the right place, it's not really a tutorial, just a tip based on notes I wrote myself in a recent project to get it straight in my own head. I thought it might be useful for others in a similar situation. Scenario: Create a search function that will search for keywords "foo" and "bar" in multiple fields, but the keywords do not have to be adjacent, in order, or even all in the same field. For eample, the selector must match if "foo" is in "field_a" and "bar" is in "field_b" -- so long as both keywords are present somewhere, the page match is valid. It is possible to just split the terms and do multiple queries on each field separately and then combine the results into a single PageArray for pagination (I believe there is a module that helps with this). However, I wanted to see if it was possible to do a basic version with a single query. Not The Solution: The following selector does not work when keywords appear separately in different fields (operator '~=' - contains all the words): $selector = "title|field_a|field_b~=foo bar"; What the selector is saying: FIND BOTH "foo" AND "bar" IN title OR FIND BOTH "foo" AND "bar" IN field_a OR FIND BOTH "foo" AND "bar" IN field_b In this case, both "foo" and "bar" have to be in the same field (but not adjacent or in order) to match. The Actual Solution What we need to use is "named selectors" to let us match each individual keyword separately while still using one selector. Using the same example as before: $selector = "selector1=(title|field_a|field_b~=foo), selector2=(title|field_a|field_b~=bar)"; What the selector is saying at its most basic level: FIND BOTH selector1 AND selector2 Or, to expand on this, it is saying: (FIND "foo" IN title OR field_a OR field_b) AND (FIND "bar" IN title OR field_a OR field_b) Crucially, "foo" and "bar" do not have to be in the same field to match. Practical Method In this example code, I am actually allowing the search for phrases (using "quoted text") as well as individual terms, so a person could enter... "foo bar" baz ... and it will keep "foo bar" together aa one term and "baz" as a separate term and match them as an exact phrase. // Keywords obtained from $input->get and cleaned (multiple spaces removed)/sanitized etc. $keywords = '"foo bar" baz'; // Split into individual search terms by space (preserve spaces in quoted text) $terms = str_getcsv($keywords, " "); // array("foo bar", "baz") // Build up named selectors $ns = ""; // named selectors string $i=1; // named selector count foreach ($terms as $term) { // operator '*=' - contains the exact word or phrase $ns .= ", ns{$i}=(title|field_a|field_b*=" . trim($term) . ")"; $i++; } //$ns = ", ns1=(title|field_a|field_b*=foo bar), ns2=(title|field_a|field_b*=baz)" // Construct the whole selector (modify/add other general selectors as needed) $selector = "template=my-template, limit=20, sort=-date" . $ns; // Find pages based on selector $results = $pages->find($selector); DISCLAIMER I haven't done any tests to see if this method is more efficient than running queries on each field separately and combining the results, I just wanted to see if it was possible!
  10. $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');
  11. @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:
  12. 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.
  13. 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.
  14. 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.
  15. 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).
  16. 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?
  17. 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
  18. LMD

    Menu Builder

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

    Menu Builder

    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.
  20. And I've now tested it too, and it works perfectly. Thank you @Robin S
  21. @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!
  22. 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.
  23. @Robin S Yes, it's fixed, thank you!
  24. 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.
  25. This module is just what I was looking for! I'm using it to create links to a file download page, instead of to the file itself, with the 'dynamic options' method. However, although it works perfectly, I'm getting a strange error in the Hanna dialogue modal window (see screenshot): I have tried deleting the file compiler cache, but it did not resolve the issue. Set-up Info: Hanna Code: ver. 0.2.0 HannaCode Dialogue: ver. 0.0.3 ProcessWire: ver. 3.0.58 PHP: ver. 5.6.21
  • Create New...