Jump to content

Robin S

Members
  • Posts

    4,791
  • Joined

  • Days Won

    303

Posts posted by Robin S

  1. 6 hours ago, eydun said:

    Have you been able to make it work in a combo-field?

    No, this module is a fieldtype, and Combo is also a fieldtype. There isn't such a thing as one fieldtype module working inside another fieldtype module.

    But you can easily add both a Dynamic Options field and a Combo field to your template so that you can use them together. You can even have the Dynamic Options inputfield adjacent to any particular Combo subfield in Page Edit thanks to the "Custom form placement" option for Combo subfields:

    image.png.7f6395605d11cb00f39ef1cd4a2e5746.png

    • Thanks 1
  2. 11 hours ago, Stefanowitsch said:

    On the latest sites that are using this module all of a sudden the image URLs get crawled by google and they appear in the search console (they are not indexed, though).

    I can't think of any reason or way that this module could be related to what Google crawls, so I think the timing must be a coincidence and the cause is something else.

  3. 19 minutes ago, gornycreative said:

    We iterated through that list once the page loads to catch the targets that are already part of the DOM.

    We watch the page every second for the moment when the user opens an AJAX loading field and make sure those instances are started.

    We killed off the interval when the list is all loaded.

    We watch the DOM ProcessPageEdit node and it's descendant with a MutationObserver for any newcomers and instantiate them too.

    As far as I know, this is all that's needed to initialise an inputfield in all circumstances regardless of if AJAX-loaded or inside new or existing repeater items:

    function initMyCustomType($el) {
    	// Initialise whatever is needed for $el here...
    }
    
    $(document).ready(function() {
    	$('.InputfieldMyCustomType').each(function() {
    		initMyCustomType($(this));
    	});
    });
    
    $(document).on('reloaded', '.InputfieldMyCustomType', function() {
    	initMyCustomType($(this));
    });

     

    • Like 1
  4. On 1/18/2024 at 5:00 AM, MarkE said:

    I wondered whether there was a particular reason for putting it in renderReady(), as it would seem more usable in renderMarkup()?

    Inputfield::renderReady() is the correct core method for ensuring that JS and CSS dependencies for the inputfield get loaded in all circumstances - see the phpDoc comments for the method. It needs to be this method so that dependencies are loaded when the inputfield is within an AJAX-loaded repeater, for example. So I don't want to risk introducing problems by changing this for what sounds like an unusual usage of the module.

    But you could use a hook to call InputfieldRuntimeOnly::renderReady() after the method that calls FieldtypeRuntimeOnly::renderMarkup().

    $wire->addHookAfter('FieldtypeRuntimeOnly::wakeupValue', function(HookEvent $event) {
    	/** @var Page $page */
    	$page = $event->arguments(0);
    	/** @var Field $field */
    	$field = $event->arguments(1);
    	$inputfield = $field->getInputfield($page);
    	$inputfield->renderReady();
    });

     

    • Like 2
  5. 2 hours ago, lpa said:

    The problem seems to be when the database has an empty description field which is returned as an array

    Thanks for debugging this. Although I can't reproduce it here I can see a solution - please update to v0.1.2 for the fix.

    • Thanks 1
  6. 11 hours ago, lpa said:

    It might be, that the language support was added later and the old descriptions are not converted to the JSON format.

    It's good to be aware that this can happen - I've made an update in v0.1.1 to fall back to the plain text if the description value cannot be decoded as JSON. But I don't think this can be the reason for "array-0" because json_decode() returns null if the supplied value cannot be decoded as JSON.

    Of the database values you showed in the screenshot, which is the one that is displayed as "array-0" in Media Lister? Or are all descriptions displaying that way?

    It's hard for me to debug this because I can't reproduce the issue here on a two-language site. The code that formats the description from the raw database value is here: https://github.com/Toutouwai/ProcessMediaLister/blob/f744014bb402d2de25888c89e3db4bcced80ff32/ProcessMediaLister.module#L426-L452
    If you use Tracy Debugger to dump variables within this section you might find where the "array-0" is creeping in. Or maybe somebody else will have the same issue and we can find out more then.

  7. 20 hours ago, lpa said:

    The description field having some text shows not the text, but this: array-0.

    That looks like it might be the result of an array to string conversion error, but the module should handle multi-language descriptions that decode from JSON to an array.

    Maybe the database has something unexpected in the description column. I don't work with multi-language sites so I'm not very familiar with them, but when I tested by entering descriptions on a site with two languages the description column looks like this:

    image.png.5ebe247270201cede42129b183b063dd.png

    The first row has a description in the non-default language but not the default language, the second row has descriptions in both languages, the third row has a description in the default language but not the non-default language, and the fourth row has no description in either language. The module handles all of these.

    Can you locate the description in PhpMyAdmin or Adminer (included with Tracy Debugger) and let me know what the raw database value is? If your images field is named "images" it will be in the "field_images" table.

  8. 7 hours ago, MarkE said:

    Nope 😓"This private-user-images.githubusercontent.com page can’t be found"

    GitHub has recently changed something that now makes it much more difficult to host readme images at GitHub without making them a part of the repo. There has long been a gotcha for previously private repos where if you if you added images before making the repo public then those image URLs wouldn't get the public subdomain.

    But now it seems that if a public repo has ever been private then GitHub forces the "private-user-images" subdomain, even retrospectively changing image URLs that previously had the public "user-images" sudomain. I can observe this in some of my recent modules where the PW forum post has the public URLs that were copy/pasted from the readme at the time the post was created but the readme at GitHub now has the "private-user-images" subdomain, which is going to make it a real drag to update the forum post when the readme is updated.

    And GitHub tricks you into thinking the image URLs are publicly accessible (I double-checked in an incognito window to make sure after the previous attempt to fix), but as this post describes the private URLs contain an encoded token that causes the images to expire after 5 minutes, although I don't know how any mere mortal is expected to know that. Presumably GitHub checks the referrer so the expiry doesn't occur when viewing the readme on GitHub itself.

    So the only solution I can see is manually changing all image URLs from the private to the public subdomain before using them in the readme - you can no longer conveniently use the GitHub image markdown directly from the "issue". I wrote a little Tracy Console script to make the process a bit less painful - might be useful to anyone else who changes repos from private to public and likes to host readme images at GitHub.

    // Require Simple HTML Dom: https://sourceforge.net/projects/simplehtmldom/ 
    require_once $config->paths->templates . 'TracyDebugger/snippets/simple_html_dom.php';
    
    // Get HTML from issue where images are embedded
    $html = file_get_html('https://github.com/Toutouwai/ProcessMediaLister/issues/1');
    
    // Process images
    foreach($html->find('.markdown-body img') as $img) {
    	$alt = $img->alt;
    	$src = $img->src;
    	// Remove query string
    	$pos = strpos($src, '?');
    	$src = substr($src, 0, $pos);
    	// Replace private subdomain with public subdomain
    	$src = str_replace('private-user-images', 'user-images', $src);
    	// Echo image Markdown for copy/paste into readme
    	echo "![$alt]($src)<br>";
    }

     

    • Like 4
  9. Media Lister

    Lists images and files from across the site in a sortable and filterable table. For images you can choose between table, small thumbnails and large thumbnails view modes.

    The module retrieves the data using SQL queries so is able to efficiently list media information for all but the largest of sites.

    Possible use cases:

    • Check that a nice variety of banner images is used for top-level pages.
    • Find duplicate files/images by sorting by filesize or filename.
    • Find images without descriptions if this is important for use in alt tags.
    • Find large PDF files that would benefit from optimisation.
    • Check for "inappropriate" images, or images that are not "on-brand".

    Images in small thumbnails view mode

    ml-main

    Files saved as a bookmark

    ml-main-2

    Controls

    Media type: Choose between Images and Files.

    View mode: When listing images you can choose between small thumbnails, large thumbnails and table view modes. When in one of the thumbnail view modes you can see information about the image in a tooltip by clicking the "i" icon, or edit the page containing the image by clicking the pencil icon.

    ml-16

    From pages matching: This field allows you to add filters to limit the pages that the media will be listed for.

    Add bookmark: Superusers can add bookmarks for the current settings that will be available from the flyout menu for all users. See the bookmarks section below for more information.

    Column visibility: Choose the columns that appear in the table and in the information tooltip (when in thumbnails mode).

    ml-9

    Search: Quickly filters the results to show only items that have the search text in any column, whether the column is visible or not.

    ml-11

    Custom search builder: For more advanced searches where you can combine conditions for specific columns with AND/OR logic.

    ml-10

    Pagination: You can navigate through the results and set the number of results per page.

    Reset: Click the "Reset" button at the top right to return to the default settings for Media Lister (or for the current bookmark if applicable).

    Editing the page that contains the media

    For any media result click the link in the "Page" column to open the page that contains the media item in Page Edit. When in thumbnail view mode you can click the pencil icon to achieve the same thing. The field that contains the media item will be focused.

    When a media item is contained within a Repeater field this is indicated by an asterisk at the start of the page title. When opening Page Edit for a media item within a Repeater field the Repeater item will be automatically expanded, including for nested Repeaters.

    Limitations for values that are merged in the database

    The module has limited support for multi-language values and custom fields for images/files. In order to be efficient enough to handle large sets of results the module retrieves raw values from the database, and in the case of multi-language values and custom field values ProcessWire stores these in JSON format in a single database column.

    ml-raw-db

    The module improves the display of this JSON data by extracting the uploadName value into a separate column, substituting custom field labels for field IDs, adding language names where possible, and by transforming the data into a quasi-YAML format for better readability. Some limitation remain though – for example, if you use Page Reference fields in the custom fields then only the page IDs are displayed.

    ml-formatted

    Bookmarks

    Superusers are able to create a bookmark for the current Media Lister settings by expanding the "Add bookmark" field, entering a title for the bookmark, and clicking the "Add bookmark" button.

    ml-2

    Bookmarks will be visible to all users from the flyout menu.

    ml-5

    You can delete a bookmark from the module config screen.

    ml-3

    Module config

    In the module config screen you can define defaults for controls such as media type, view mode, pagination limit and column visibility. You can also delete bookmarks from the module config screen.

    ml-4

     

    https://github.com/Toutouwai/ProcessMediaLister
    https://processwire.com/modules/process-media-lister/

    • Like 14
    • Thanks 4
  10. 4 hours ago, BrendonKoz said:

    Thank you so much for your devotion to the PW Weekly project, @teppo!!!!

    Hear, hear! I love the PW Weekly - a highlight of the week! Putting out such a well-written newsletter week after week for 10 years - what an incredible contribution to the community! Hats off to @teppo!

    I like to read each new issue when it's hot off the press, which is normally on a Sunday (NZ time), but the official email from newsletter@processwire.com doesn't arrive until the following Saturday. A long while ago I asked Ryan why this is and there was a sensible reason that I've forgotten now, but I can't wait that long for my PW news 🤓. So my solution has been to set up an email alert for the RSS feed using Blogtrottr - that way I can dive into each issue when it's at maximum freshness 🎉

    • Like 11
    • Thanks 1
  11. @bernhard, thanks for the heads-up. The new tab option was working for child items but not for the top level menu items. Fixed in v0.1.5 and in this version I've also added an option to define an icon for the top-level items - these are only visible in the sidebar menu so probably not seen all that often but still good to have control over. 

    • Like 1
    • Thanks 1
  12. On 11/22/2023 at 8:27 AM, lpa said:

    And my Repeater matrix field has this:

    <div id="mainhead" pw-append>
    	<?php echo $form->styles; ?>
    	<?php echo $form->scripts; ?>
    </div>

    The matrix field is likely to be rendered inside a markup region, and so this output would end up as a nested markup region, which isn't supported.

    See this response to a similar question for how a FilenameArray or WireArray can be a solution:

     

  13. @howdytom, I think I see where the confusion comes in. In more recent PW versions the require() line in /site/templates/admin.php is...

    require($config->paths->core . "admin.php");

    ...whereas in earlier versions it is...

    require($config->paths->adminTemplates . 'controller.php');

    These both end up doing the same thing so you should only have one require() in the file.

    The functional part of my code is this bit:

    // Get the user's IP address
    $ip = $session->getIP();
    // Define the allowed IP addresses
    $allowed_ips = ['111.111.111.111', '222.222.222.222'];
    // Check user's IP is allowed
    if(!in_array($ip, $allowed_ips)) {
    	return 'Access denied';
    }

    I only include the require() line to indicate that my code needs to be inserted above the existing contents of /site/templates/admin.php

    • Thanks 1
  14. 21 minutes ago, howdytom said:

    Using the code above throws an unknown error when I login into ProcessWire. Is it still valid for ProcessWire 3.0.229?

    There isn't anything in that code that should cause an error in any version of PW.

    Just a guess, but given that the error message originates from /wire/core/admin.php make sure you have edited /site/templates/admin.php and not /wire/core/admin.php by mistake.

    • Like 1
  15. 8 hours ago, prestoav said:

    This means I can end up with a lot if image variations having been created (and still being used) but with old settings. A good example might be an image variation that was created using a quality of 50 but now the code is set to 100. A new variation is not created under these situations, only if the variation size is changed.

    That's possibly a browser cache issue, because the variation filename doesn't change when the quality option changes. This problem is the motivation behind this module: https://processwire.com/modules/unique-image-variations/

    • Like 2
  16. Following on from an earlier tutorial for using $pagefile->uploadName...

    Tip 1

    Suppose your website audience uses a non-latin alphabet and you have a file to upload with a filename like this:

    image.png.145de57844b2a9787377bb0f4308bbf2.png

    (I don't know any Chinese but Google Translate tells me that this is a translation for "my example filename")

    If this file is uploaded to a PW files field it ends up as shown below because none of the filename characters are allowed.

    image.png.d1f741958e5119aa3c3dd53d68ae21d9.png

    This makes it hard to identify what the file relates to. Since PW 3.0.212 the original filename will be saved to the uploadName property of the Pagefile but it would be nice to improve the actual filename assigned to the file.

    The hooks below in /site/ready.php make use of the SanitizerEasySlugger module to transliterate the original filename to latin characters that are allowed in a PW files field.

    // When a file is added to InputfieldFile
    $wire->addHookAfter('InputfieldFile::fileAdded', function(HookEvent $event) {
    	/** @var Pagefile $pagefile */
    	$pagefile = $event->arguments(0);
    	// The uploadName property is not available at this point so just flag that the file is new
    	$pagefile->isNewFile = true;
    });
    
    // When InputfieldFile is processed in Page Edit
    $wire->addHookAfter('InputfieldFile::processInputFile', function(HookEvent $event) {
    	/** @var Pagefile $pagefile */
    	$pagefile = $event->arguments(1);
    	// Only for newly added files
    	if(!$pagefile->isNewFile) return;
    	// Only if the uploadName property is different to the basename
    	if($pagefile->uploadName === $pagefile->basename) return;
    	// Divide the upload name into parts
    	$parts = pathinfo($pagefile->uploadName);
    	// Transliterate non-latin characters in the filename using the SanitizerEasySlugger module
    	// https://processwire.com/modules/sanitizer-easy-slugger/
    	$transliterated  = $event->wire()->sanitizer->utf8Slugger($parts['filename']);
    	// Rename the file (renamed file will be visible after the page is saved)
    	$pagefile->rename($transliterated . '.' . $pagefile->ext);
    });

    After saving the page the filename now at least has some connection to the original filename, and this is presumably more useful to a Chinese speaker:

    image.png.9fca0f6789a2b06289c3f4285183e8f6.png

     

    Tip 2

    When using CKEditor or TinyMCE to link to a file, by default you can only see the sanitized name:

    image.png.55b4152f177fbd498152614c8a47b501.png

    But it would be helpful to also see the original filename that has been saved to $pagefile->uploadName. Add the hook below to /site/ready.php:

    // When the Add Link form is created
    $wire->addHookAfter('ProcessPageEditLink::buildForm', function(HookEvent $event) {
    	/** @var InputfieldForm $form */
    	$form = $event->return;
    	// Get the "Select File" select
    	/** @var InputfieldSelect $select */
    	$select = $form->getChildByName('link_page_file');
    	// Get an instance of PagefilesManager via the Home page
    	$fm = $event->wire()->pages->get('/')->filesManager();
    	// For each of the options in the select
    	foreach($select->options as $filename => $label) {
    		if(!$filename) continue;
    		$pagefile = $fm->getFile($filename);
    		if(!$pagefile) continue;
    		// Only if the uploadName is different from the filename
    		if($pagefile->uploadName === $pagefile->basename) continue;
    		// Add the uploadName to the option label
    		$select->replaceOption($filename, $filename, $label . " ($pagefile->uploadName)");
    	}
    });

    Now the uploadName is appended to the select option label:

    image.png.70e048c7a48cc2c06e58d009045864ae.png

    • Like 1
    • Thanks 1
  17. 11 hours ago, BitPoet said:

    It does if you pass a filter function to the beforeShowDay option, though I haven't found a way to set that without modifying InputfieldDatetime.js.

    One way is to set the option when the datepicker field is focused:

    $(document).ready(function() {
    
    	// The days to disable
    	const disabledDays = ['2023-11-27', '2023-11-28'];
    
    	// When field "date_1" is focused
    	$('#Inputfield_date_1').on('focus', function() {
    		$(this).datepicker('option', 'beforeShowDay', function(date) {
    			return [!disabledDays.includes($.datepicker.formatDate('yy-mm-dd', date))];
    		});
    	});
    
    });

     

    • Like 1
  18. On 11/18/2023 at 2:13 PM, Fuzen said:

    Doesn’t PW’s image size create and save the various image sizes on the first load of the page?

    Yes, that's mentioned in the readme:

    On 11/10/2023 at 9:48 PM, Robin S said:

    Normally when you create new image variations in a template file using any of the ProcessWire image resizing methods, all the new variations that are needed on a page will be created from the original Pageimage the next time the page is loaded in a browser.

     

    On 11/18/2023 at 2:13 PM, Fuzen said:

    If so, then on smaller sites this module wouldn’t be of big benefit, am I correct?

    I'd say it's not the size of the site that matters but the number of image variations on any particular page. But in any case, if the way variations are created by default in PW is not presenting a problem then you won't need the module.

    • Like 3
×
×
  • Create New...