-
Posts
5,034 -
Joined
-
Days Won
340
Everything posted by Robin S
-
This module is sort of an upgrade to my earlier ImageToMarkdown module, and might be useful to anyone working with Markdown in ProcessWire. Copy Markdown Adds icons to images and files that allow you to copy a Markdown string to the clipboard. When you click the icon a message at the top left of the screen notifies you that the copying has occurred. Screencast Note: in the screencast an EasyMDE inputfield is used to preview the Markdown. It's not required to use EasyMDE - an ordinary textarea field could be used. Usage: Images When you hover on an item in an Images field an asterisk icon appears on the thumbnail. Click the icon to copy an image Markdown string to clipboard. If the "Description" field is populated it is used as the alt text. You can also open the "Variations" modal for an image and click the asterisk icon to copy an image Markdown string for an individual variation. Usage: Files When you hover on an item in a Files field an asterisk icon appears next to the filename. Click the icon to copy a link Markdown string to the clipboard. If the "Description" field is populated it is used as the link text, otherwise the filename is used. https://github.com/Toutouwai/CopyMarkdown https://processwire.com/modules/copy-markdown/
-
Custom Notes (former List of Allergens)
Robin S replied to Cybermano's topic in Module/Plugin Development
Thanks for sharing this. ? Another possible way to approach this is to use a single Hanna tag for all allergens and then use Hanna Code Dialog to create an interface where a site editor can select allergen types by label. You could use a page per allergen type and use the (multi-language?) title field for the label and an integer field for the allergen number. Then use a hook to set the options for the dialog. $wire->addHookAfter('HannaCodeDialog::buildForm', function(HookEvent $event) { // The Hanna tag that is being opened in the dialog $tag_name = $event->arguments(0); // The form rendered in the dialog /* @var InputfieldForm $form */ $form = $event->return; if($tag_name === 'allergen') { /* @var InputfieldCheckboxes $f */ $f = $event->wire('modules')->InputfieldCheckboxes; $f->name = 'type'; $f->id = 'type'; $f->label = 'Type'; foreach($event->wire()->pages->find("parent=/references/allergens/") as $allergen) { $f->addOption($allergen->allergen_number, $allergen->title); }; $form->add($f); } }); Or maybe if you are using a Repeater for your menu items you don't need Hanna Code and could just use a Page Reference field to select allergen pages per menu item. -
@adrian, I've tried but unfortunately I haven't had any success with getting the titles of admin pages. ? I turned off a couple of $config settings while I was testing: $config->sessionFingerprint = 0; $config->sessionChallenge = false; And I used curl directly rather than WireHttp to keep it simple. The problem is that as soon as you set the "wire" cookie value... curl_setopt($ch, CURLOPT_COOKIE, "wire={$input->cookie->wire}"); ...PW just doesn't give any response and curl times out. It doesn't matter if you try and get a PW admin page or a frontend page. I thought it might have been an endless redirect situation but when I get the transfer information with curl_getinfo it looks like no redirects are occurring so it seems that's not the problem. I'd love to know why PW doesn't respond but I don't know how to debug this any further. Unless anyone can make a breakthrough with this maybe it will be a matter of manually setting titles for any links to pages that require a logged-in user. Not a great hardship. ?
-
Please don't spend a lot of time on this. I'll see if I can work it out in the weekend.
-
Thanks. The v0.3.0 update to HannaCode is actually a major refactoring of the module so there were a few things in HannaCodeDialog that needed updating for compatibility. The new v0.4.0 of HannaCodeDialog should be compatible with HannaCode v0.3.0 and it requires HannaCode >= v0.3.0.
-
Awesome, thanks for adding this! The conversion to relative URLs is working great and grabbing the HTML page title is working for external links, but it looks like there's a problem getting the titles of pages in the PW admin. Not sure if there's an easy way to solve that - is it even possible to send WireHttp requests so they appear to come from a logged in superuser rather than guest?
-
ProcessPageListActions: adding extra actions to actions
Robin S replied to Valery's topic in Module/Plugin Development
AdminOnSteroids has an option in the PageListTweaks section: "Always show extra actions" -
I don't think you're being dim - you're just running up against a necessary limitation of what the AutoTemplateStubs module does. The module is only ever going to operate on files in the AutoTemplateStubs directory that it has created itself. As a matter of safety it's not going to get into the business of modifying/overwriting/deleting files that you have created, such as your custom Page class files. When custom Page classes are not in use AutoTemplateStubs creates stubs for class names like "tpl_basic_page", which don't exist anywhere else in the codebase. They're not "real" classes that do anything - they're just a way to tell the IDE about overloaded properties when you use a PHPDoc comment to (falsely) state that $page is an instance of class tpl_basic_page. But if you are using custom Page classes then two things apply: 1. There are necessarily going to be two different class files using the same class name - the "real" class file that you create, and the "fake" class file that AutoTemplateStubs creates. Your IDE will probably warn you somewhere that there are multiple definitions for the same class name. 2. Your IDE "knows" that $this is your custom Page class, and it's likely to "prefer" what it knows about $this from the custom Page class file over anything that is contained in the AutoTemplateStubs stub file. You can manually copy over the PHPDoc comments from the AutoTemplateStubs stub file to your custom Page class file if you find that's useful, but nothing is going to be kept in sync so you won't be getting the "auto" part of AutoTemplateStubs.
-
Just checking: you know for certain that you have published, unhidden pages that use template "my-template" as descendants of $page (i.e. you can see them in the page tree) but they are not returned with either: $results = $page->find("template=my-template"); or $results = $pages->find("has_parent=$page, template=my-template"); (both of these are effectively the same thing) If that's the case it's possible that something has gotten messed up in the pages_parents database table. In PW 3.0.156 or newer you can rebuild the pages_parents table by executing the following in the Tracy console or in a template file: $pages->parents()->rebuildAll(); See method PagesParents::rebuildAll()
-
There is such a method in recent versions of PW: https://github.com/processwire/processwire/blob/d8945198f4a6a60dab23bd0462e8a6285369dcb9/wire/modules/Process/ProcessForgotPassword.module#L992-L1004 Are you maybe running an older version of PW?
-
Not all the API variables and classes are included in the API Reference menus. For example, the whole $fieldgroups API variable and methods exist in the documentation but do not appear in the menus. Ryan has said: Personally I'd rather have everything listed in the menus. In terms of modules there is also the Pro API Explorer.
-
A Fieldtype for dynamic options that are generated at runtime via a hook. Configuration Inputfield type You can choose from a range of inputfield types on the Details tab of a Dynamic Options field. Your field will return a string or an array depending on if the selected input field type is for "single item selection" or "multiple item selection". Maximum number of items You can define a maximum number of items the field is allowed to contain. The core inputfields supported by this module will become disabled once the limit is reached. This option is only applicable if you have selected an inputfield type that is for multiple item selection. Format as Pagefile/Pageimage object(s) If the field will store paths/URLs to Pagefiles/Pageimages then you can enable this option to have the formatted value be a Pagefile/Pageimage object for "single" fields or an array of Pagefile/Pageimage objects for "multiple" fields. There is a related Select Images inputfield module that allows you to visually select image thumbnails. Defining selectable options Selectable options for a Dynamic Options field should be set in a FieldtypeDynamicOptions::getSelectableOptions hook in /site/ready.php. The hook should return an array of options as 'value' => 'label'. An example hook is shown on the Details tab of a Dynamic Options field: $wire->addHookAfter('FieldtypeDynamicOptions::getSelectableOptions', function(HookEvent $event) { // The page being edited $page = $event->arguments(0); // The Dynamic Options field $field = $event->arguments(1); if($field->name === 'your_field_name') { $event->return = [ 'red' => 'Red', 'green' => 'Green', 'blue' => 'Blue', ]; } }); Formatted value If a Dynamic Options field uses a "single" input type then its formatted value is a string, and if it uses a "multiple" input type then its formatted value is an array. The unformatted value of a Dynamic Options field is always an array. Also see the Configuration section above for description of an option to have the formatted value be Pagefile/Pageimage object(s). Examples of possible uses $wire->addHookAfter('FieldtypeDynamicOptions::getSelectableOptions', function(HookEvent $event) { // The page being edited $page = $event->arguments(0); // The Dynamic Options field $field = $event->arguments(1); // Select from the "files" field on the page if($field->name === 'select_files') { $options = []; foreach($page->files as $file) { // Value is basename, label is description if one exists $options[$file->basename] = $file->get('description|basename'); } $event->return = $options; } // Select from files in a folder if($field->name === 'select_folder_files') { $options = []; $path = $event->wire()->config->paths->root . 'my-folder/'; $files = $event->wire()->files->find($path); foreach($files as $file) { // Value is full path, label is basename $options[$file] = str_replace($path, '', $file); } $event->return = $options; } // Select from non-system templates if($field->name === 'select_template') { $options = []; foreach($event->wire()->templates as $template) { if($template->flags & Template::flagSystem) continue; $options[$template->id] = $template->name; } $event->return = $options; } // Select from non-system fields if($field->name === 'select_field') { $options = []; foreach($event->wire()->fields as $field) { if($field->flags & Field::flagSystem) continue; $options[$field->id] = $field->name; } $event->return = $options; } // Select from FormBuilder forms if($field->name === 'select_formbuilder_form') { $form_names = $event->wire()->forms->getFormNames(); // Use form names as both keys and values $event->return = array_combine($form_names, $form_names); } }); https://github.com/Toutouwai/FieldtypeDynamicOptions https://processwire.com/modules/fieldtype-dynamic-options/
- 21 replies
-
- 22
-
-
@CalleRosa40 I use the AddNewChildFirst feature regularly and so can confirm that it works. Check that you have enabled it for the correct template: the template of the pages that will be added at the top, and not the template of the parent page. The configuration is different from Pagetree Add New Childs Reverse in this regard. And I assume you have uninstalled Pagetree Add New Childs Reverse - you wouldn't want to have this module and the AOS feature running at the same time. Edit: I see now you already said that you uninstalled Pagetree Add New Childs Reverse.
-
No, CKEditor isn't a supported inputfield. I expect it would create rendering issues in the tag if it contains HTML, and if you are putting anything more than a short piece of text in your "read more" it would result in a huge, cumbersome tag widget. Instead I think you should wrap the "read more" text in "open" and "close" Hanna tags. [[rm-open]] <p>Your text here.</p> [[rm-close]] Then replace the [[rm-open]] with a "Read more..." button and a div open tag, and the [[rm-close]] with a div close tag. Use JS to toggle the visibility of the div when the button is clicked. You could also look at TextformatterPagination and TextformatterAccordion for inspiration but I think the above method would be the simplest.
-
v0.2.5 released. In this release stub files will always be created in and deleted from an "AutoTemplateStubs" directory and you can choose where this directory will be created. This avoids the risk that somebody accidentally configures an existing unrelated directory as the stubs directory. Please update to this new version for safety's sake.
-
X is not supported by FieldtypeImage in selector
Robin S replied to MSP01's topic in General Support
The page name also seems to work: $pages->find('images.tags=the-page-name') And in case it's not obvious, you can also find the page(s) used in the Page Reference field in a separate step and then use that Page/PageArray in the selector because it will be converted to ID(s) when treated as a string. // Find the tags you want to search for $search_tags = $pages->find("template=tag, title=blue|green"); // Find the pages with these tags in the images field $results = $pages->find("images.tags=$search_tags"); -
Maybe there's nothing wrong with it that needs maintaining. Alternatively you could use an ordinary text field and use a hook to validate the inputfield value: $wire->addHookAfter('InputfieldText::processInput', function(HookEvent $event) { $inputfield = $event->object; $field = $inputfield->hasField; if($field && $field->name === 'text_unique') { // Look for existing page with the field value $value = $event->wire()->sanitizer->selectorValue($inputfield->value); $existing_page = $event->wire()->pages->get("text_unique=$value, template=news_item"); if($existing_page->id) { // Show an error message $inputfield->error("Value '{$inputfield->value}' already in use on page '{$existing_page->title}'."); // Clear value $inputfield->value = ''; } } });
-
$pages->has() with exclusions, or maybe a findOneID()
Robin S replied to adrian's topic in API & Templates
Oh man, I must be going blind - totally overlooked that, sorry. Just went straight to the text and thought you were saying has()/getID() wasn't useful and should be changed. Thanks for opening the request - thumbs up added ? -
$pages->has() with exclusions, or maybe a findOneID()
Robin S replied to adrian's topic in API & Templates
getID() is just an alias of has() - I requested that alias because to my way of thinking it's a clearer name for what the method does. I think what you're asking for is a new findOneID() method ?. getID() works just as it should in my opinion - getID() is to get() as findIDs() is to find(). Once upon a time we only had find() and get(), and then findOne() was introduced to save doing find("limit=1")->first(). So it would be cool to have a similar findOneID() labour-saving method, and in the meantime you could use findIDs() with a limit of 1. -
Love the new URL hooks! The post doesn't mention what happens when a hooked URL or regex matches an existing page URL, but on testing it looks like the page URL takes precedence. That makes sense. In the blog post there are examples where trailing slashes are present and absent, and tests seem to show that the hooked URLs work regardless of whether a trailing slash is present or absent in the requested URL. But what if you want to enforce a trailing slash or no trailing slash and redirect accordingly as per real page URLs?
-
The page path is in the title attribute, so you can hover on results to see the path in the browser tooltip: PW doesn't make it easy to manipulate the markup of admin search results. You could try the hook below in /site/ready.php to append the root parent title to the result title: $wire->addHookBefore('ProcessPageSearchLive::execute', function(HookEvent $event) { $event->wire()->addHookAfter('FieldtypePageTitle::wakeupValue', function(HookEvent $event) { $page = $event->arguments(0); // Limit by template or some other property of $page if($page->template == 'basic_page' && !$page->get_original_title) { $root_parent = $page->rootParent; // Set custom page property to avoid affecting root parent title $root_parent->get_original_title = true; // Append root parent title $event->return .= " (Root parent: {$root_parent->title})"; } }); });
-
The PHP timezones are stored in timezonedb, which is updated regularly: https://pecl.php.net/package/timezonedb You can check which version is used in your environment via timezone_version_get().
-
Nice, that's the quickest and easiest I've seen so far. Thanks!
-
Thanks, but I already looked at this one and it doesn't give the timezone in the PHP name format I linked to in my post. It gives a timezone like "PST" when I need "America/Los_Angeles".