-
Posts
5,039 -
Joined
-
Days Won
340
Everything posted by Robin S
-
That does look strange, but I think it might be normal. It seems to apply to all modules: http://modules.processwire.com/export-json/oauth2-login/?apikey=pw300 And if the values are blank then I would expect it not to apply any restriction. I see that you have module info defined it two places - maybe that is the cause of the issue? https://github.com/outflux3/SelectizeImageTags/blob/d4160b20f40e05840b6cb5d947fb63b3a95aeb4c/SelectizeImageTags.info.php#L4-L20 https://github.com/outflux3/SelectizeImageTags/blob/d4160b20f40e05840b6cb5d947fb63b3a95aeb4c/SelectizeImageTags.module#L7-L22
-
I've never tried setting the module info conditionally like that (or the external info.php approach), but it looks like it should work. Tracy should help here to check the resulting $info array.
-
The issue won't be related to the upgrade method because the error message is different. So it must relate to the 'requires' property in the getModuleInfo() method. I note that above you say that JquerySelectize is not to be required. So you would want to remove that module from the 'requires' property if you haven't already, and perhaps check for it in the install/upgrade methods depending on the PW version.
-
This should do the job: $(window).load(function(){ var $repeater_wrap = $('#wrap_Inputfield_YOUR_REPEATER_FIELD_NAME'); if($repeater_wrap.length && !$repeater_wrap.find('.InputfieldRepeaterItem').not('.InputfieldRepeaterNewItem').length) { $repeater_wrap.find('.InputfieldRepeaterAddLink').trigger('click'); } }); It won't work for nested repeaters though - for that you'd have some more work to do, ensuring you get direct child elements of $repeater_wrap, and dealing with the fact that inputfields inside a repeater item have changed names. But it may not be such a good idea to open a new repeater item on page load. The issue is that you are actually creating a new repeater item when you do this, so that if the user saves without filling out the repeater fields you will end up with a blank item. And if any of the fields in the repeater are required the user will see error messages.
-
"Page Reference" field selections change based on template's location?
Robin S replied to Lance O.'s topic in General Support
With a bit of hooking it is possible to both dynamically control the selectable pages for a PageAutocomplete inputfield, and dynamically set the parent/template of new pages created from the inputfield. I have only played around with this and haven't used it in production, so use it at your own risk. Dynamic selectable pages for PageAutocomplete The idea is that in the field settings you define a broad selector that includes all of the pages you might want to select. It could be something really broad such as "has_parent!=2". Then you modify the selector in a hook according to the page being edited. In /site/ready.php... $wire->addHookAfter('Field::getInputfield', function(HookEvent $event) { $field = $event->object; $inputfield = $event->return; // Only for this one Page Reference field if($field->name !== 'test_page_field') return; // Only for ProcessPageEdit if($this->process != 'ProcessPageEdit') return; $page = $this->process->getPage(); // Get findPagesSelector (or findPagesSelect if you used that) $selector = $inputfield->findPagesSelector; /* Now append to or overwrite $selector however you like, depending on $page maybe. You can even define some $allowed PageArray like with the "Custom PHP code" option that is possible with other Page inputfields, and then use it in the selector as "id=$allowed". But note that there is a 500 character limit enforced on selectors. */ // Set the modified selector back to the property you got it from $inputfield->findPagesSelector = $selector; }); Dynamic parent and/or template for pages created from the inputfield The idea is that in the field settings you do not define a parent or template for allowed pages, but then set these properties in a couple of hooks according to the page being edited. In /site/ready.php... $wire->addHookBefore('InputfieldPage::renderAddable', null, 'dynamicParentandTemplate'); $wire->addHookBefore('InputfieldPage::processInputAddPages', null, 'dynamicParentandTemplate'); function dynamicParentandTemplate(HookEvent $event) { $inputfield = $event->object; // Only for this one Page Reference field if($inputfield->hasField->name !== 'test_page_field') return; // Only for ProcessPageEdit if(wire()->process != 'ProcessPageEdit') return; $page = wire()->process->getPage(); // Now set $parent_id and $template_id dynamically depending on $page $parent_id = 1234; // demo value $template_id = 56; // demo value $inputfield->parent_id = $parent_id; $inputfield->template_id = $template_id; } Have fun! -
Just some explanation because it is interesting... This isn't something that is specific to Repeaters - it applies to any selector used on a PageArray/WireArray (a Repeater field returns a PageArray). When you do $some_pagearray->find() this is different to a $pages->find() - the method name is the same but they are actually totally different methods. See find() method in the PageFinder class vs the WireArray class. When using $pages->find() the method refers back to the fieldtype for each queried field and the fieldtypes can do some special preparation to the queried value. In the case of a Datetime field the value is passed through strtotime() if it is a string. So this allows "today" to be converted to a timestamp. But when using $some_pagearray->find() this process does not happen, so the queried value must be a timestamp. Another gotcha to watch out for is using the page status as a string in a selector. With $pages->find() you can do something like "status!=hidden" but this won't work with a selector in $some_pagearray->find(). I think it would be nice if things like this did work with PageArrays - there is an open request for it.
-
Users to have access to specific pages (not templates)
Robin S replied to a-ok's topic in General Support
Most of the hookable methods in the Pages class have $page as their first argument. So you get $page in your hook like so: $page = $event->arguments(0); -
Users to have access to specific pages (not templates)
Robin S replied to a-ok's topic in General Support
Users are pages so you have all the hookable methods in the Pages class too ('added', 'publishReady', etc). So you make the code in the hook conditional on the page template being 'user'. -
Whoops, somehow overwrote my original post. I recall striking this problem too. The code below works for me on a front-end AsmSelect inside a FormBuilder form - should be the same on the backend. In this case I am adding/removing items from the AsmSelect when a grid square on a map is clicked. // Add hectare to AsmSelect $map.on('click', '.sponsorable:not(".selected")', function() { var hectare = $(this).data('hectare'); $('#Inputfield_hectares_to_sponsor').children('option[value="' + hectare + '"]').prop('selected', true).end().change(); }); // Remove hectare from AsmSelect $map.on('click', '.sponsorable.selected', function() { var hectare = $(this).data('hectare'); $('#Inputfield_hectares_to_sponsor').children('option[value="' + hectare + '"]').prop('selected', false).end().change(); });
-
I think we need something like UserVoice for PW feature requests, so Ryan and other core developers can gauge the level of support for individual requests and prioritise accordingly. It would actually be good to have the same for PW issues, so we can get an indication of which issues are particularly problematic to the largest number of users.
-
Users to have access to specific pages (not templates)
Robin S replied to a-ok's topic in General Support
Related modules... PageEditPerUser - it's not explained in the module description but there is a option to allow access to descendant pages of a page where edit access has been given. AdminRestrictBranch Edit: just realised you are talking about the front-end and not back-end. Sorry, disregard. -
In a current project I am using a Repeater field to build a kind of pseudo-table, where each Repeater item is a row. Some of the rows are headers, and some have buttons that toggle corresponding checkbox fields in a hidden FormBuilder form. The problem was that when the Repeater items were collapsed I couldn't see which rows were headers and which contained buttons. I tried including the fields in the Repeater labels but it still didn't provide enough visual difference to be quickly recognisable. So I investigated how classes could be added to selected Repeater items in admin depending on the value of fields within the Repeater items. This is what I ended up with... In /site/ready.php // Add classes to selected service row Repeater items $this->addHookAfter('InputfieldFieldset::render', function(HookEvent $event) { /* @var $fieldset InputfieldFieldset */ $fieldset = $event->object; $attr = $fieldset->wrapAttr(); // Fieldsets in a Repeater inputfield have a data-page attribute if(isset($attr['data-page'])) { // Get the Repeater item $p = $this->pages((int) $attr['data-page']); // Check field values and add classes accordingly // If item is a header if($p->row_type && $p->row_type->id == 2) { $fieldset->addClass('header-row'); } // If item has a checkbox button if($p->fb_field) { $fieldset->addClass('has-checkbox'); } } }); In admin-custom.css (via AdminCustomFiles) /* Special repeater rows */ .Inputfield_service_rows .header-row > label { background:#29a5aa !important; } .Inputfield_service_rows .has-checkbox > label .InputfieldRepeaterItemLabel:before { font-family:'FontAwesome'; color:#73cc31; content:"\f058"; display:inline-block; margin-right:6px; } Result
- 3 replies
-
- 16
-
-
Not sure if it could cause the issue, but in your copyParent() function you could try find() instead of findMany() - no need for findMany() when you have a limit of 50. Also, the selector you posted looks a bit off: $tx = wire('pages')->findMany("template=transaction-earn, start=$start, limit=$limit, sort=transactiondate, [tagreference=$tag, merchantreference=$merchant]"); What is going on with the section in the square brackets at the end? Looks a bit like a subselector but you are not matching it against a field.
-
module Recurme – Processwire Recurring Dates Field & Custom Calendar Module.
Robin S replied to joshuag's topic in Modules/Plugins
Hi @joshuag, unfortunately this update does not resolve the problem I am having with uninstallation. When I do the following steps... Remove the existing module files Add the updated module files Do a modules "Refresh" Clear compiled files ...I still get the PHP timeout when I try and uninstall, regardless of which sub-module I try and uninstall from. Sometimes timeouts like this are caused by a circular reference in the code. I'm wondering about the fact that each sub-module installs and uninstalls all the others. That seems non-standard to me: normally where there are multiple sub-modules there is one "main" module file that installs/uninstalls the others. The other modules only require the main module but do not install/uninstall them. See FieldtypeRepeater for example. Could there be some circularity where FieldtypeRecurme tries to uninstall ProcessRecurme, which tries to uninstall FieldtypeRecurme, which tries to... and so on? -
There is the Page Reference with Date Field module that might be useful for this sort of thing. I've never used it and the module page doesn't indicate that it is compatible with PW3. But the real problem with using Page Reference fields for likes or any purpose that could potentially use thousands of pages is that there is no pagination or limiting possible when getting the field value. So it's not just a matter of dealing with the inputfield in Page Edit but also the impact on memory when getting the value via the API. There's an open request about this but no sign of activity.
-
module Recurme – Processwire Recurring Dates Field & Custom Calendar Module.
Robin S replied to joshuag's topic in Modules/Plugins
@joshuag, you say in the email: I think it would be good if you do bump the version number each time you make a release even if it is for bug fixes. Otherwise it isn't clear from the PW modules listing whether that installation has been updated to the latest version, so it's harder to keep track if you have multiple sites running Recurme. Also, it will be easier for you in terms of support if you can ask what the installed version number is and know from that what release of Recurme the user has installed. -
I'm not seeing any jumping problem with scrolling/dragging/swiping in Chrome on Windows or in Safari on iPad. But from an interface design point of view I think there is a bit of an issue in that there is nothing to indicate that there are multiple items in the work section and that the user should should scoll/drag/swipe to see more.
-
You can show the field when the countries field is empty using the core inputfield dependencies feature: countries.count=0 Or you could show it when the page is unpublished (which would apply when the page is first added) with the help of my Custom Inputfield Dependencies module.
-
To me the main distinction is between the bulk importing of data (for which modules like ImportPagesCSV are great) and the occasional addition or editing of data which you do via Page Edit. But in any case it's not difficult to do what you are asking about. Add a textarea field in your template named "country_import" or something. Then use a hook to Pages::saveReady() to process the field contents and add them to the "countries" Page Reference field. In /site/ready.php: $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); // Only for the appropriate template if($page->template == 'YOUR-TEMPLATE') { // If the import field is not empty if($page->country_import) { // Get the individual country titles in an array $country_titles = explode(', ', $page->textarea_1); // Find the country pages with those titles $country_pages = $this->pages->find([ 'template' => 'country', 'title' => $country_titles, ]); // Add the country pages to the countries field $page->countries->add($country_pages); // Empty the import field $page->country_import = ''; } } }); You could use the same principle for other fields if you think there's a major benefit to it.
-
A couple more links that may be useful:
-
Who is creating the pages? You (the developer), or a client? If you are creating the pages then I think it would be better to use the API or a bulk import module (ImportPagesCSV, BatchChildEditor) to bring this data in initially rather than spend time making something special in Page Edit. API $countries_string = 'Nigeria, Kenya, Australia, Russia, France'; // Maybe you would instead create an array of country strings to process multiple pages at once // 'Page One Title' => 'Nigeria, Kenya, Australia, Russia, France', // 'Page Two Title' => 'Russia, ...' // ... $country_titles = explode(', ', $countries_string); $country_pages = $pages->find([ 'template' => 'country', 'title' => $country_titles, ]); // Set $country_pages to the Page Reference field ImportPagesCSV Use a text editor to replace instances of ', ' with '|' in your countries string. Now the country titles are in a format that can be imported to a Page Reference field by ImportPagesCSV (see the module readme). You could import all the page content via the module, or just the countries field if you prefer (create a CSV that contains two columns - the page title and the pipe-separated string of country titles).
-
I don't think you can store objects in $session. See this comment from Ryan for instance: Storing an array (without objects) seems to work: $my_array = []; $my_array['animal'] = 'cat'; $my_array['colour'] = 'orange'; $session->my_array = $my_array;
-
To solve this you need to look at the code for each method you are considering hooking and ask yourself things like: What class is the method in? Does the method fire when I need it to? Does the method have an argument or return value that I need to use in my hook? So you are considering hooking ProcessLogin::afterLogin() or Session::loginSuccess(). When you look at afterLogin() you see: It is a method of ProcessLogin, a Process module that handles the PW login form. So it is only going to fire if a user logs in via the core PW login form. Maybe that isn't what you want if you are using a custom login form or logging in users via the API as part of some script. It depends on what you are doing. The method comments in the source code say it is only intended for when a superuser logs in, which could give you a clue if it is the best method to hook or not. It has no arguments that could be useful to quickly tell you things about the user who has logged in (although you could still get the $user object in other ways). So chances are Session::loginSuccess() is going to be a better option because it is a method of Session, so more closely connected to the current user session regardless of how they logged in. And it conveniently has the $user object as an argument so you can easily check properties of the user such as name, role, etc, in your hook.
-
This is deliberate and Ryan has talked about it but I don't have a link handy. Probably because there can be situations where a field contains a lot of data in which case the user should be notified of a problem but not have all their work thrown out. See this example from @Soma where he shows how you can set a field back to its previous value when you want to reject a submission: