-
Posts
4,928 -
Joined
-
Days Won
321
Everything posted by Robin S
-
v0.3.0 released, which adds some new features such as Custom Search Builder in the datatable, a new "Error responses only" view, and the ability to exclude links from this view by defining URL prefixes, to exclude domains known to give false-positive error responses. See the updated readme for more.
-
A new page needs to be saved before you can add files or images to it. So try saving the new repeater page after you create it: // ... $contentRepeater = $page->content->getNew(); $contentRepeater->save(); // ... I suggest you install TracyDebugger because it would have shown you a error message that explains the problem when you tried to add a file to an unsaved repeater page.
-
@monollonom, the edit button sounds like a generally useful feature so I've built an option for this into v0.3.0. There is also a hookable InputfieldSelectImages::getImageButtons() method if you want to add to or replace the button markup. @mel47, the module itself doesn't impose any limit on how many selectable images you can have, but I think it would be poor usability to have more than about 100 images to wade through. I don't see anything wrong in your hook code, so if it's timing out perhaps you are returning a very large number of images. The inputfield uses the standard admin image thumbnail, so if you have added images to a page using the API rather than in Page Edit then it can take a while to generate the admin thumbnails the first time they are rendered. Probably you should work out a way to present fewer images for selection. For example, you could have a Page Reference field on the page to select a particular meeting page, and then the Select Images field would only show the images on that meeting page. $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 === 'image_selection') { if(!$page->selected_meeting->id) return; $options = []; foreach($page->selected_meeting->images as $image) { $options[$image->url] = "{$image->basename}<br>{$image->filesizeStr}"; } $event->return = $options; } });
- 18 replies
-
- 1
-
- inputfield
- images
-
(and 2 more)
Tagged with:
-
Yes, you could do that. The fieldtype just needs an array of options returned from a hook to FieldtypeDynamicOptions::getSelectableOptions() and there are no constraints on how that array is generated. The fieldtype only stores the value, but if you needed to look up the label that goes with a value you could just run the same code that generates the options array and then get the label for any value. One way you might do this is via a method for a custom Page class that returns the selectable options - that way you don't need to repeat any code. So you would add a method like getDynamicOptions() to the Page class that the Dynamic Options field is used with. Your hook would then be: $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') { /* * Get an array of options as $value => $label from the custom Page class method * * If you have more than one Dynamic Options field on the page that you need * to distinguish between then you could pass the field name as an argument to the method * e.g. $page->getDynamicOptions('your_field_name') * */ $options = $page->getDynamicOptions(); // Set that options array as the event return $event->return = $options; } }); And to look up the label for the selected option in the template file: // Get the label for the selected option $options = $page->getDynamicOptions(); $label = $options[$page->your_field_name]; This assumes your field is for single options. If it's for multiple options then you would loop over the field value and look up each label from the $options array.
-
How to solve this field value change issue while admin editing a page?
Robin S replied to PWaddict's topic in General Support
To expand on this, these two User Activity options (marked "experimental") would be useful for this case: -
You could also try Lister Selector: https://processwire.com/modules/process-lister-selector/
-
@Reeno, I've added multi-language support in v0.2.0. Please upgrade and let me know if you strike any problems.
-
Something like this: $i = 1; foreach($page->my_repeater_field as $item) { echo "<div id='slider-layer-$i'>Layer $i</div>"; $i++; }
-
I haven't tried that before, but I just tried it now and it does work. For "Default value" you have to enter the value of the dynamic option rather than the label, and the field has to be "Required" as per the default value note. P.S. I just released v0.1.8 which fixes a minor config fields bug, so you might like to upgrade.
-
I don't think it's good to automatically install modules that aren't bundled as part of the module repository. I believe PagePaths does impact some core functionality when installed (PageFinder results and possibly the $page->path/$page->url properties?) and the fact that it includes a feature to manually rebuild the paths table makes me think that it can potentially get out of sync with the page structure. So I think users need to consciously decide to install it if they want to use the Verify Links module. I've updated the readme to mention the required modules and that they are core modules.
-
v0.2.0 adds a feature allowing you to force the logout of a currently logged-in user. There's a confirmation step if you click the force logout icon.
-
New blog post: Introducing the Custom Fields Module
Robin S replied to ryan's topic in News & Announcements
@ryan, thanks for creating this cool module! A couple of questions: 1. Do the subfields have an ID of some sort separate to the name, such that a subfield can be renamed without losing the existing data stored for the subfield? 2. What happens to stored data if a subfield is removed from the defining file? Does the existing data for the subfield persist in the database, or does the fieldtype detect the removal and do some cleanup to remove the stored data? Also, I think there's a typo in the blog post. // multi-selection foreach($page->custom_field->countries as $value) { $label = $page->field->label('countries', $value); echo "<li>$value: $label</li>"; // i.e. "USA: United States" } ...should be... // multi-selection foreach($page->custom_field->countries as $value) { $label = $page->custom_field->label('countries', $value); echo "<li>$value: $label</li>"; // i.e. "USA: United States" } -
LogsJsonViewer doesn't do any truncating, and doesn't get involved in the saving of log data at all - it just formats what is already in the log. Your problem might be due to $maxLineLength in FileLog. There's a FileLog::setMaxLineLength() method, but I'm not sure how you could practically use this unless you write to your log file using FileLog::save() instead of the more convenient WireLog::save(). Instead you probably just have to try and avoid going over $maxLineLength if you are saving JSON, perhaps by doing your own truncation on individual values if they are long, before you save the data.
-
Process Render File A Process module that renders markup from files in /site/templates/ProcessRenderFile/. This provides an easy way to create simple admin screens where it might be overkill to create a dedicated Process module for the purpose. Process page When you install the module a page with the name "render-file" and the title "Render File" is created under Setup. To change the page name or title, expand Page List to Admin > Setup > Render File and open the page for editing. Tip: if you create a new text field with the name "page_icon" and add it to the core "admin" template you can set a custom menu icon for the page by entering the icon name into the field. E.g. enter "smile-o" to use a smiley icon for the page. If you want to use ProcessRenderFile for more than one Process page you can create a new page under Setup. Select "admin" for the template, enter a title for the page, and in the next step choose ProcessRenderFile in the Process dropdown. Render files for URL segments On install the module will create a "ProcessRenderFile" folder in /site/templates/. Any .php files you save to this folder will be rendered as the output of a matching URL segment for Process pages using ProcessRenderFile. For example, if you create a file foo.php containing code... echo "This is the output of foo.php"; ...then you'll see this output when you visit /processwire/setup/render-file/foo/ (assuming the default ProcessWire admin page name and the default ProcessRenderFile page name). In the render file you can use all the ProcessWire API variables like $pages, $input, etc, as you would in a template file. If you create foo.js and foo.css (or foo.scss if you have ProCache installed) then those assets will be automatically loaded when you visit /processwire/setup/render-file/foo/. When a file is rendered the filename will be converted into a capitalised format that's used as a browser title and a headline. If you want to set a custom browser title and/or headline you can do this in your render file: $this->wire('processBrowserTitle', 'Custom browser title'); $this->wire('processHeadline', 'Custom headline'); Render file for the Process page If you create a render file that has the same name as the ProcessRenderFile Process page then this file will be rendered when the Process page is viewed without any URL segment. So for the default ProcessRenderFile page name you would create render-file.php. Note that this will override the default list output described below. Configuration The module configuration screen lets you select URL segment render files to appear as menu items. The selected render files will appear in the flyout menu for the Process page, and also as a list when the Process page is viewed without any URL segment. The list is only shown if you haven't created a render file for the Process page as described above. If you've created more than one ProcessRenderFile Process page then you'll see menu options for each page in the module configuration. https://github.com/Toutouwai/ProcessRenderFile https://processwire.com/modules/process-render-file/
-
@Christophe, I can't follow what you're doing so if you have a question specifically about Custom Inputfield Dependencies rather than the core show-if features then please rephrase it and include some screenshots. For now what I can say is: Custom Inputfield Dependencies uses the $pages->find() selector syntax as described in the PW docs. This is a different syntax than the core show-if selectors, so you can't just copy/paste selectors from one to the other. Syntax like "parent.id=1314 || id=1250" and "parent.id=1314 | id=1250" is not valid for $pages->find(). If you want to match one field/value combination OR a different field/value combination then you need to use OR-group syntax: https://processwire.com/docs/selectors/#or-groups And InputfieldSelector (the inputfield used by Custom Inputfield Dependencies for "Show only if page is matched by custom find") doesn't support OR-groups so you would have to use a selector string in "Show only if page is matched by selector". (parent.id=1314), (id=1250)
-
@soyerH, calling deleteAll() on a single image field is also working for me, so something unusual is going on for you. A couple of ideas... 1. Is the page a "normal" page or is it a User page that involves the alternate template/parent for users feature? Your page path and field name made me wonder this. If it is an alternate user parent/template and you can identify the steps to reproduce the problem please create a GitHub issue for it. 2. Does it work if you set the field value to null instead of calling deleteAll()?
-
You can use Ryan's ProcessDatabaseBackups module to do this. Export: Import: Without ProcessDatabaseBackups you could use PhpMyAdmin or Adminer to do something similar. If your Hanna codes reference external files (I prefer to use files for my Hanna codes so I can edit them in my IDE) then you would need to copy those to the other site too.
-
@Christophe, glad you find it useful. Technically you don't need Custom Inputfield Dependencies if you want to show/hide a field according to the parent page ID. The PW core includes a "Parent" field in Page Edit on the "Settings" tab. This field is named "parent_id" so you can do something like this:
-
@Christophe a module that will help with this:
-
A module to work around a few shortcomings of Fieldset and FieldsetPage fields. Not submitted to the modules directory because I'm hopeful that most if not all of this will be handled in the core eventually. https://github.com/processwire/processwire-issues/issues/1953 https://github.com/processwire/processwire-requests/issues/533 https://github.com/processwire/processwire-requests/issues/534 Fieldset Helper Adds some visibility features to fields of type FieldtypeFieldsetOpen and FieldsetPage, and adds a helper method to get the child fields of a FieldtypeFieldsetOpen field. Visibility The module adds support for the following visibility settings to FieldtypeFieldsetOpen and FieldsetPage fields: Open when populated + Closed when blank Open when populated + Closed when blank + Load only when opened (AJAX) * Open when populated + Closed when blank + Locked (not editable) Open when blank + Closed when populated "Blank" in the context of a fieldset means that all the child fields within the fieldset are blank. * The AJAX part of this option doesn't currently work for FieldsetPage. Get the child fields of a fieldset If you've ever wanted to get the child fields that are within a fieldset you will have noticed that the ProcessWire API doesn't provide a direct way of doing this. Although they appear indented in Edit Template, the child fields are actually all on the same "level" as the other fields in the template. The module adds a FieldtypeFieldsetOpen::getFieldsetFields() method that you can use to get the child fields of a fieldset for a given page. Example: $field = $fields->get('my_fieldset'); $template = $templates->get('my_template'); $fieldset_fields = $field->type->getFieldsetFields($field, $template); First argument: the fieldset Field, i.e. a Field whose type is an instance of FieldtypeFieldsetOpen (this includes FieldtypeFieldsetTabOpen). Second argument: the Template that the fieldset field is part of. Return value: a FieldsArray of child fields. If there is a nested fieldset inside the fieldset then the child fields of the nested fieldset are not included in the return value, but of course you can use the method again to get the child fields of that fieldset. https://github.com/Toutouwai/FieldsetHelper
-
@ttttim, as a test you could try $page->getUnformatted('field_name') and see if that is also empty. That will tell you if the issue relates to the formatValue() method or not. It's just a guess, but the saved value might be failing the test at FieldtypeDynamicOptions::sanitizeValue(). This checks the saved value against the allowed values as defined in your hook to FieldtypeDynamicOptions::getSelectableOptions(). If you temporarily change that method so that it doesn't do any sanitizing... public function sanitizeValue(Page $page, Field $field, $value) { return $value; } ...and find that you are then able to get the field value via AppApi then it means that something about AppApi is causing your hook to not return the expected selectable options. Like, maybe $page and $field are not what you would expect them to be inside the hook. You should be able to use Tracy to debug what is going on inside your hook when AppApi is involved.
-
I've never heard of anyone using nested Hanna tags before and I don't think TextformatterHannaCode itself supports it. I tried it just now without HannaCodeDialog installed and TextformatterHannaCode didn't successfully replace the nested tags. It's too fringe for me to want to spend time on for HannaCodeDialog but seeing as your nested tags don't have any user-editable attributes you can probably use some alternative token replacement for those like wirePopulateStringTags()/WireTextTools::populatePlaceholders(). Or maybe you could play around with manually setting the dialog field value in a HannaCodeDialog::buildForm() hook. Not sure if that would work or not.
-
@Alpina, the OP is asking how to output the field values of a page in the order that the fields are positioned in the page's template. To get the fields in order you can use $page->fields, and you can then iterate over those fields to get the field values from $page via the name of each field. As developer you generally have control over both the template within the PW admin and the template file that outputs markup. So if you have a template with fields "title", "body" and "gallery" then I think the normal way to control the order of these fields is by structuring the markup you want within the template file and then getting each field value individually by name. <h1><?= $page->title ?></h1> <div class="text"> <?= $page->body ?> </div> <div class="gallery"> <?php foreach($page->images as $image): ?> <img src="<?= $image->url ?>" alt="<?= $image->description ?>"> <?php endforeach; ?> </div> If later there is a decision to place the gallery before the body text then you change the order of the markup in the template file. You might also change the order of the fields within the template in the PW admin so that it reflects the order that fields are output in the frontend, but that's a separate decision and moving the fields in the PW admin doesn't actually define the order of output. Alternatively you could have no fixed order of output within the template file and use the order of the template fields as defined in the PW admin. <?php foreach($page->fields as $field): ?> <?php $value = $page->get($field->name); ?> <?php if($field->name === 'title'): ?> <h1><?= $value ?></h1> <?php elseif($field->name === 'body'): ?> <div class="text"> <?= $value ?> </div> <?php elseif($field->name === 'images'): ?> <div class="gallery"> <?php foreach($value as $image): ?> <img src="<?= $image->url ?>" alt="<?= $image->description ?>"> <?php endforeach; ?> </div> <?php endif; ?> <?php endforeach; ?> I just think this is a less practical approach and makes the template file harder to understand.
-
foreach($page->fields as $field) { $value = $page->get($field->name); // Now output the value or process it as needed for output... } Seems rather impractical to me though, as you would no doubt need to do a lot of if() tests to output the right markup based on the field type and what wrapping markup is needed, etc. Much simpler to get your specific field values individually in your template file and control the order of markup there.