-
Posts
5,008 -
Joined
-
Days Won
333
Everything posted by Robin S
-
$sanitizer->text(nl2br($your_text), ['allowableTags' => '<br>']);
-
Do you have the AutoExportTemplatesAndFields module installed by any chance? There are reports in the the support topic that it can cause issues with repeater fields.
-
@Macrura, glad you got it working eventually. I intend to work on an upgrade to this module sometime soon. Hope to add a feature allowing all dialog options to be configured from within a single hook, which will make things easier (for those comfortable writing code anyway). Will also look at adding some clarification that an attribute must first be declared before adding any of the "double underscore" enhancements.
-
I discovered Swoole via a Quora answer to the (silly) question "Will PHP die in 2018?". https://www.swoole.co.uk/ https://github.com/swoole/swoole-src It's way above my skill level so I only have the vaguest grip on what it's all about, but it sounds pretty wild. Just thought folks here might be interested in checking it out.
-
Here's one way to enforce only a single featured item while still enabling featured status to be set while editing an item (as opposed to using a Page Reference field on some other page to select a single featured item). In /site/ready.php... $wire->addHookBefore('InputfieldCheckbox::render', function(HookEvent $event) { $inputfield = $event->object; if($this->process != 'ProcessPageEdit') return; $page = $this->process->getPage(); // If this isn't the existing featured item... if($inputfield->hasField == 'featured' && $page->template == 'news_item' && !$page->featured) { // Add a note about the existing featured item $existing_featured_item = $this->pages->get("template=news_item, featured=1"); $inputfield->description = "Only one item may have featured status. Featuring this item will un-feature '$existing_featured_item->title'."; } }); $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); // If the "featured" checkbox is checked... if($page->template == 'news_item' && $page->featured) { // Remove the featured status of any other items $existing_featured_item = $this->pages->get("template=news_item, featured=1"); if($existing_featured_item->id) $existing_featured_item->setAndSave('featured', 0); } });
-
@OllieMackJames, just a note about Page Reference fields: Where you have a "single" Page Reference field... ...when that field has a page selected its value is a Page object. So rather than this... /* fill in pageid of page to be used for content homepage*/ if($page->id == 1 && $page->page2use4homepage) { $p = $page->page2use4homepage->id; $page = $pages($p); } ...you can just do this... if($page->id == 1 && $page->page2use4homepage) { $page = $page->page2use4homepage; }
-
I guess I should do the same. It's just that Google is so convenient. I can see some benefits in having some introductory documentation that skips over the details. The earlier documentation was a bit like that and it's still useful. But for the v3 API Reference I think the more comprehensive the better. Having detailed and comprehensive documentation is not only useful to current users but it also boosts PW's credibility for potential users, particularly for experienced devs who I'm sure would find PW a pleasure to use and could make some valuable contributions to the community. The richness of the API is something we should show off rather than hide.
-
Thanks @kixe! Why is this method undocumented I wonder? I'd love to know the criteria by which a method makes it into the API docs or not. I'd like to see all class methods documented. If the PhpDoc comments are already there (as they are in most cases) then where's the harm in making the information viewable in the API docs? @ryan?
-
Is there a WireArray equivalent of PHP's array_search() function? In other words, if I have a value and I want to know the key of that value (if any) for a given WireArray, how can I do that? I checked the WireArray docs but didn't find any equivalent, which surprised me because array_search() is a pretty commonly used function. Would the only way be to convert the WireArray to a plain PHP array with getArray()?
-
As before, you can't easily modify ProcessPageList for this purpose. But you can use Lister (Pages > Find). So in your case you would filter according to some parent or some template, plus filter by "title starts with" some character. I have a module under development that will allow for a list/tree that dynamically changes the selector used by Lister. Not sure when it will be ready but that might end up being helpful for your scenario.
-
Yeah, that module wouldn't really be practical if you need more than one or two virtual parents. The Virtual Parents module was an experiment to answer the question "To what extent is it possible to trick ProcessPageList into showing a page structure that isn't real?" And now that I've tried it I can answer with "To only a very limited extent". ProcessPageList just isn't designed to support anything other than the real page tree and forcing it do otherwise is pretty painful. There have been several requests for a way to browse an alternative page structure. It will require a module that builds its own tree from scratch and doesn't rely on ProcessPageList. It's on my to-do list but it will be challenging and I'm not sure when I'll get to it. And bear in mind too that any module like this will come with other limitations - for instance, it wouldn't be possible to sort or move pages like ProcessPageList can because the page structure shown might have no resemblance to the real structure.
-
@adrian, I created a pull request for adding support for Repeater Matrix to the "Copy Repeater Items to Other Page" action. It only required a small modification to the field select options so I thought it best to keep this within the existing action rather than create a new action just for copying Repeater Matrix fields. I thought about allowing all fieldtypes that extend FieldtypeRepeater but decided it would be better to add fieldtypes on a case-by-case basis just in case someone has a custom fieldtype that extends FieldtypeRepeater in some weird and wonderful way that wouldn't be compatible with the action. I also added a couple of other enhancements to the action - failure conditions for if the selected repeater field doesn't exist on the source or destination pages (previously the action reported a success in those cases). And copying repeater items now also copies any files or images included in the repeater items. One last thing I added, to the module itself this time, is a link to the module config settings in the notice that advises that new actions are available. I think it would also be handy to have a link the config settings in the process page - I often want to jump there to adjust allowed roles and the "in menu" option. I didn't include this in the pull request though - just something for you to consider.
-
@Zeka, maybe you can use the filename, prependFilename or appendFilename properties of the TemplateFile to limit where your hook applies. E.g. $wire->addHookAfter('TemplateFile::render', function(HookEvent $event) { $template_file = $event->object; $proceed = false; foreach($template_file->appendFilename as $filename) { if(substr($filename, -9) === '_main.php') $proceed = true; } if(!$proceed) return; // Your code... }); I'm curious - what's your reason for hooking after TemplateFile::render? If you are targeting non-admin template files inside your /site/ why wouldn't you include whatever logic you need inside the template files rather than via a hook?
-
This module requires Repeater Matrix which is part of the Profields bundle. The Matrix module you have shown in your screenshot is something completely different.
-
@OllieMackJames, your setup makes sense to me. But you cannot clone the Home page because there can only be a single page at the top of the page hierarchy. Instead you need to move the Home page contents to another page... Add a new template with the same fields as your home template (use the "Duplicate fields used by another template" option when adding it). Create a new page using this template. Now check out @adrian's Admin Actions module which has two built-in actions that you'll find useful to move the content from the existing Home page to this new page: 1. Copy Repeater Items to Other Page 2. Copy Field Content to Other Page Another tip: If when setting up a site you know that you will later want to turn the Home page into an internal page you can make it easier by using an internal page to hold your Home page content. Let's say this internal page has the ID 1234. Don't publish this page (so it won't be accessible on the front-end). At the top of home.php (your home template file) you put... $page = $pages(1234); ...and now wherever you do $page->title etc in home.php you will get the content from page 1234. Later when you are ready to switch the Home page you can populate your home page with content (or repeat the steps above for a different unpublished internal page), remove/change the $page assignment in home.php, and publish page 1234.
-
How can I load a file and use it like page template
Robin S replied to gunter's topic in API & Templates
Also note that in PW3 wireRenderFile() and wireIncludeFile() are $files->render() and $files->include() respectively (those earlier functions now just call the $files methods internally). -
PhpStorm doesn't know what API variables PW makes available to template files. So you need to add variable types hints in a DocBlock at the top of your template files. I use... /** * @var Config $config * @var Fieldgroups $fieldgroups * @var Fields $fields * @var Languages $languages * @var Modules $modules * @var Page $page * @var Pages $pages * @var Paths $urls * @var Permissions $permissions * @var ProcessWire $wire * @var Roles $roles * @var Sanitizer $sanitizer * @var Session $session * @var Templates $templates * @var User $user * @var Users $users * @var WireCache $cache * @var WireDatabasePDO $database * @var WireDateTime $datetime * @var WireFileTools $files * @var WireInput $input * @var WireLog $log * @var WireMail $mail * @var \ProCache $procache * @var \FormBuilder $forms **/ Your field names are not a part of the PW API (field names don't exist in the file system but only in the database). But I believe you can get code completion for field names using the Template Stubs module.
- 15 replies
-
- 4
-
-
-
- ide
- code editor
-
(and 1 more)
Tagged with:
-
foreach iteration to create nested fieldset items
Robin S replied to Federico's topic in Module/Plugin Development
No, a form doesn't work that way. The way you have it set up now you have a single form with multiple submit buttons. It doesn't matter which submit button you click, the submitted form data will be the same. The thing is that the name of each post variable is determined by the name of the input element it corresponds to. Where you have multiple inputs with the same name (which you will have unless you rename them using something like what I suggested before) only the last input of each name will actually make it into post. Although you could change to having multiple forms (one for each grandchild page) I don't think the idea of multiple submit buttons is a good one. Where users see multiple fields from multiple pages in the same module interface the expectation will be that they can edit all of these fields at once. But in fact all changes they make besides those inside the form they click the submit button for will be lost. Users might not notice that which could cause problems, or they might notice it and report it to you as a bug. You don't really want either of those. A single form with a single submit button would be better, then you loop through the submitted form data and use the added page ID prefix to connect it to the relevant page. But remember you need to sanitize all the submitted data. It looks like you're sort of recreating ProcessPageEdit with your module here - have a look at ProcessPageEdit::processInput to get an idea of the kinds of things to look out for. If the action of your form points to your Process module page (which it will do by default unless you changed it) then all the post data will be accessible in the init() method of your module, as you are already trying. But as I said above, the array of data is in $this->input->post. You mentioned you have Tracy installed - so do... bd($this->input->post); ...in your init() method and you will see the post data you have available. -
foreach iteration to create nested fieldset items
Robin S replied to Federico's topic in Module/Plugin Development
$this->input->post->submit is a single post variable with the name "submit". To get all your post variables you want to use $this->input->post. But I think you will find a problem in that if two or more of your grandchildren pages share the same the same template then the inputfields on those pages will share the same names. Meaning that the post variables will be overwriting each other when the form is submitted. So you will need to find a way to rename the inputfields in your form so each inputfield has a unique name. Something like this might work, which prepends the page ID to the inputfield name: // ... foreach($inputfields as $field) { if(in_array($field->name, $ignorefields)) continue; $field->name = $grandchild->id . '_' . $field->name; // make name unique by prepending the page ID $fieldswrapper->add($field); } // ... -
foreach iteration to create nested fieldset items
Robin S replied to Federico's topic in Module/Plugin Development
The bare bones are: $form = $this->modules->InputfieldForm; $parent = $this->pages(1234); // Get the parent page foreach($parent->children as $child) { if(!$child->hasChildren) continue; $fs_level_1 = $this->modules->InputfieldFieldset; $fs_level_1->label = $child->title; $fs_level_1->collapsed = Inputfield::collapsedYes; foreach($child->children as $grandchild) { $inputfields = $grandchild->getInputfields(); $fs_level_2 = $this->modules->InputfieldFieldset; $fs_level_2->label = $grandchild->title; $fs_level_2->collapsed = Inputfield::collapsedYes; $fs_level_2->add($inputfields); $fs_level_1->add($fs_level_2); } $form->add($fs_level_1); } // Add submit button or anything else here // ... return $form->render(); -
Markup Regions are a godsend if you want to code HTML directly rather than adding it as strings to PHP variables. Alternatively you can use output buffering (which is what I preferred before Markup Regions were introduced). <?php ob_start(); // $main_content ?> <div>Your markup</div> <?php $main_content = ob_get_clean(); ?> For a project like yours I would be inclined to try building it within the PW admin as a first approach - you can do a lot with the admin (it's just an application built using the PW API) and it's pretty easy to tweak it with hooks and custom CSS. I think it would be much quicker that way. @bernhard has written a helpful blog post for getting started with Process modules, and check out his Showcase topic for the kinds of things that are possible:
-
Not totally sure what you mean - you just want to save having to click "Add Filter" to add an email address row? You can use a hook in /site/ready.php: $wire->addHookBefore('ProcessPageLister::execute', function(HookEvent $event) { if($this->config->ajax) return; $process = $event->object; // Just for the Users lister... if($this->page->name === 'users') { // Add to existing defaultSelector (or alternatively you could overwrite defaultSelector) $process->defaultSelector .= ', email%='; } });
-
Migrate Processwire with Plugin but Backend does not work as expected
Robin S replied to Maxplex's topic in General Support
Not sure what kind of plugin you used, but you don't need a plugin to do this task in any case. I'd start over and migrate using a procedure like this: Export database from local server using phpMyAdmin or similar. Make ZIP file of all local website files. Create new database and database user at 1&1. Try to use the same database name and user name as your local site if possible, but no big deal if not possible - you'll just need to edit the details in /site/config.php to match. Import database from step 1 to the new database you created at 1&1. Upload ZIP file from step 2 to public_html root. Extract ZIP file (assuming that 1&1 has a file manager that supports unzipping - otherwise you'll have to upload all the website files uncompressed which will take a lot longer). Done. -
v0.1.2 released - adds compatibility with PW < 3.0.66
-
@hezmann, if you can give me access to your dev site (send me a message) I would be happy to take a look. Otherwise I'm out of ideas sorry.