-
Posts
1,331 -
Joined
-
Last visited
-
Days Won
61
Everything posted by BitPoet
-
FieldtypeDatetimeAdvanced - subfield selectors for date/time
BitPoet replied to BitPoet's topic in Module/Plugin Development
I guess it should be doable by extending WireDT accordingly and implementing fitting getDatabaseSchema and savePageField/loadPageField methods as well as making sleepValue/wakeupValue with arrayish data instead of plain strings, a lot like the Events fieldtype but without the multiple value (EventsArray) stuff. Meanwhile reproduced and working on a solution. Should be ready in a few days at most. Meanwhile, I haven't been completely lazy: DatetimeAdvanced v1.0.3 supports custom subfields and works together with Lister's subfield selectors. -
Allowing the user to be changed in the template is still necessary when you use the API, though you might get by if you temporarily set the flag. Then assign created_users_id the id of Jesper. // set up your new page, then... $page->template->allowChangeUser = true; $page->created_users_id = (int)$input->post->creatorid; // or however the input is named in the form $page->save();
-
...with a not so little impact when building complex sites. I already know I'm going to use this a lot ? Thank you!
-
Remove items from one array to another without deleting pages
BitPoet replied to Tom.'s topic in General Support
I guess the safest approach would be to create a new PageArray Array 3, iterate over Array 1, compare with each item in Array 2 and if not matched, add the Page to Array 3. Or, in code: $array3 = new PageArray(); $array1->each(function($pg) use($array2) { if(! $array2->has($pg)) { $array3->add($pg); } }); -
If you don't have different names, then localUrls with be identical. Your select will just reload the page. What you need to do is pass some kind of indicator (e.g. a GET parameter with the language id) to the server and set the user's language before the page is rendered. So you need to output something like this in your page for the language selector: <select onchange="window.location=$(this).val();"> <?php foreach ($languages as $language) : ?> <?php $url = $page->localUrl($language) . "?lang=" . $language->id; ?> <option <?php if ($user->language->id == $language->id) : ?>selected<?php endif; ?> value="<?php echo $url; ?>"><?php echo $language->title; ?></option> <?php endforeach; ?> </select> Then, in the backend (best site/ready.php), you need to adapt the current language according to the parameter and store the selection in the session to make PW remember it (untested): <?php if($input->get->lang) { $newLang = (int)$input->get->lang; if(! $languages->get($newLang) instanceof NullPage) { $session->set("currlang", $newLang); } } $newLang = $session->get("currlang"); if($newLang) { $user->language = $languages->get($newLang); } You should think hard whether you want to do that though. Google & Co. will put a massive penalty on your site if you show differing content on identical URLs. Languages are different beasts from locations. I have, e.g., some colleagues from foreign countries who are a lot more comfortable doing their shopping in English rather than in German, but they still need to see the usual Euro prices and German VAT. So you might just use a different thing than the language, e.g. a GET variable named "country" that you store in the session just like the code above does and pass that to your conversion function.
-
Listing pages under corresponding letter
BitPoet replied to louisstephens's topic in API & Templates
The regex was just a shot in the dark. Since it's all about starting letters, you can change that line to $letter = substr($pg->title, 0, 1); -
Listing pages under corresponding letter
BitPoet replied to louisstephens's topic in API & Templates
If you don't want to go to deeply into writing your loop with comparing the previous letter, you could use the PageArray::groupBy method I posted: With it, you could write something like this (i't a bit of guesswork since I don't know if the "A" "B" "C" parts are really in the title or in a different field, but you should get the gist: <?php echo "<h2>Services</h2>"; $children = $page->children(); $children->sort("title"); // Important for grouping to work $grouped = $children->groupBy(function($pg) { // first argument ($pg) is always the page object we are examining $letter = preg_replace('/^Server "(.)".*$/', '$1', $pg->title); return array($letter); }); foreach($grouped as $letter => $letterPages) { echo "<h3>$letter</h3>"; echo "<ul>"; foreach($letterPages as $lpg) { echo "<li>{$lpg->title}</li>"; } echo "</ul>"; } -
Add custom options to InputfieldSelect via a hook
BitPoet replied to a-ok's topic in General Support
The not saving thing is actually something I encountered too a few days ago when populating select options in a hook. Unfortunately, I didn't find the time to dig deeper (and it isn't an urgent case). Come to think of it, it might be a validation issue, as when saving in ProcessPageEdit, the render hook isn't called before processInput is triggered. So running the same hook code before InputfieldSelect::processInput might solve it. -
Add custom options to InputfieldSelect via a hook
BitPoet replied to a-ok's topic in General Support
Probably nothing that complicatied. You can use getForPage() on the repater item to retrieve the page it belongs to. $repeaterPage = $event->object->hasPage; $page = $repeaterPage->getForPage(); -
Add custom options to InputfieldSelect via a hook
BitPoet replied to a-ok's topic in General Support
There's no "page" argument to Inputfield::render, but you can use the property $inputfield->hasPage to retrieve the page associated with the Inputfield. The returned page is the individual repeater item page, not the page being edited. If work_detail_images is in the same repeater, the following line should be enough to get things working: $page = $event->object->hasPage; -
I was just typing that I thought an object storage like S3 would be better geared towards replicating that kind of content, as I can say from experience that blob-heavy databases can be a real PITA. They always grow far faster than expected, and the number of queries rises what feels like exponentially. The necessary backup space and -time quadruples in the blink of an eye, and the "quick restore" suddenly takes an hour. I guess the setup for new sites could be scripted leveraging S3 and IAM apis. Create user, create access key, assign role, create bucket and assign policy are all available through the REST APIs. Then all that is left is to deploy the access key to PW's config or module settings and all replicas should know it too.
-
Making update proof copy of an edited core module
BitPoet replied to ocr_b's topic in Getting Started
Here's a little snippet for site/ready.php that lets you store your modified copy of the js file in question under site/modules/FieldtypeRepeater/ and replaces the URL in a renderReadyHook on InputfieldRepeater: <?php namespace ProcessWire; wire()->addHookAfter("InputfieldRepeater::renderReadyHook", null, "useRepeaterSiteJS"); function useRepeaterSiteJS(HookEvent $event) { $config = $event->object->config; $modules = $event->object->modules; foreach($config->scripts as $script) { if(strpos($script, $config->urls->InputfieldRepeater . "InputfieldRepeater") !== false) { $altName = "InputfieldRepeater.js"; $altPath = $config->paths->siteModules . "FieldtypeRepeater" . DIRECTORY_SEPARATOR . $altName; if(file_exists($altPath)) { $altUrl = $config->urls->siteModules . "FieldtypeRepeater/" . $altName; $info = $modules->getModuleInfo("InputfieldRepeater", array('verbose' => false)); $version = $info["version"] ?: 0; $modified = filemtime($altPath); $config->scripts->remove($script); $config->scripts->add($altUrl . "?v=$version-$modified"); break; } } } } Edit: amended the text to make it clear that this approach is only about the js file in question, differing from other suggestions that duplicate the complete module. Of course, incorporating changes in the original js file on every update has to be done anyway. -
I'm really in love with FormBuilder, but the one thing missing to match all my end users' expectations were repeatable field groups. Think repeaters, in ProcessWire terms. Our primary application of PW is our corporate intranet, so "lines" of fields are quite common in the forms I build. We have all kinds of request forms where the information for a varying number of colleagues needs to be entered (from meal order to flight booking request) and where it is simply impractical to send a form for each, and I don't want to clutter my forms with multiple instances of fields that may only get used ten percent of the time. That's why I started to build FormBuilderMultiplier (link to GitHub). What it does: Adds an option to make a regular Fieldgroup repeatable Lets you limit the number of instances of a Fieldgroup on the form Adds an "Add row" button the form that adds another instance of the Fieldgroup's fields Adds a counter suffix at the end of every affected field's label Stores the entered values just like regular fields Makes the entered values available in preview and email notifications Supports most text based fields, textareas and selects (really, I haven't had enough time to test all the available choices yet) What it doesn't do (yet): Support saving to ProcessWire pages (i.e. real Repeaters) I haven't tested all the validation stuff, Date/Time inputs etc. yet, but since I'm utterly swamped with other stuff at work, I didn't want to wait until I have it polished. Any feedback is welcome. There might also be some issues with different output frameworks that I haven't encountered yet. The forms I work with mostly use UIKit. Status: Still alpha, so test well before using it in the field. Known issues: When rows are added, the form's iframe needs to be resized, which isn't completely clean yet. How it works: The Fieldgroup settings are added through regular hooks, as is the logic that adds the necessary field copies for processing the form and displaying previews. "Multiplied" field instances are suffixed with _NUM, where NUM is an incremental integer starting from 1. So if you have add two fields named "surname" and "givenname" to a fieldgroup and check the "multiply" checkbox, the form will initially have "surname_1" and "givenname_1" field (I'm still considering changing that to make the risk to shoot oneself into the foot by having a regular "surname_1" field somewhere else in the form less likely). When a "row" is added, the first row is cloned through JS and the counter in the fields' IDs, names and "for" attributes as well as the counter in the label are incremented before appending the copies to the Fieldset container in the form. To keep backend and frontend in sync, a hidden field named [name of the fieldset]__multiplier_rows is added to the form. Both the backend and the frontend script use this to store and retrieve the number of "rows". ToDo: Naturally, add the option to store the data in real repeaters when saving to pages. Do a lot of testing (and likely fixing). Make a few things (like the "Add row" button label etc.) configurable in field(set) context. Add a smooth API to retrieve the multiplied values as WireArrays. The mandatory moving screenshot:
- 32 replies
-
- 16
-
-
That, definitely. ProcessWire blocks access to all php files under site/templates.
-
Nearly ten months later, FormBuilder is happily at work here and I am testing a home-brewed module that implements repeating fieldsets for FB forms [TM]. I have named it FormBuilderMultiplier and put it on GitHub in case anybody is interested.
-
Users in PW are also pages, so they also have a template. As that is a system template, it is normally not shown in the list of templates. However, if you go to "setup" -> "templates", there is an option when you expand the filters where you can check "Show system templates". Once you do that, you will see a new section labeled "System" with a template named "user". That is where you need to add these additional fields.
-
There's (I think) no direct method to access language specific properties yet, but you can do this: <?php $lang = $languages->get('name-of-your-language'); $langTitle = $type_material->get('title' . $lang->id); Or, if you know the language id (e.g. 1060), you could do: <?php $langTitle = $type_material->title1060;
-
InputfieldPage can be seen as a "layered" inputfield. InputfieldPage itself takes care of the basic logic (processing input, rendering contents etc.) but the ui input itself is delegated to another inputfield type (plain select, ASM select, page autocomplete etc.). Since all of the page related logic (outside specific page inputs like autocomplete or pagelistselect) is inside InputfieldPage, the "real" input modules themselves can be used to input other things besides PW pages too since all they have to deal with are options with values and labels.
-
image descriptions can't be changed in my repeaters
BitPoet replied to rushy's topic in General Support
Perhaps apache mod_security? It is (in)famous for introducing strange quirks in page editing. You could try disabling it as I wrote here: -
Since ProcessWire's default is english, it should be sufficient to delete all translation files. However, any custom programming may have strings in German, so best try this with a local copy first.
-
If other changes can be successfully saved, it may well be an issue of apache mod_security being active. I'm assuming the site is running on apache, of course. Try to add the following to your .htaccess to see if that's the culprit: <IfModule mod_security.c> SecFilterEngine Off SecFilterScanPOST Off </IfModule> If it doesn't work, or if you're unsure, best talk to the server admin / shared hosting provider.
-
It works here on PW latest. Did you override the setting in field context? You can check that by adding "$config->advanced = true;" in site/config.php, then opening the user template and clicking on the pass field. There will an additional tab "Overrides" that shows all settings that have been changed in this template context (and allows you to reset them).
-
Do you get an error message? If not, perhaps you can spot something in the network tab in Chrome's developer console.
-
Possible bug in selectors as associative arrays?
BitPoet replied to Zeka's topic in API & Templates
The problem is that anything that looks like a ctype_digit is coerced to int in Selectors::makeSelectorArrayItem, even if you use nested array syntax and pass in the name of a sanitizer method. -
Error when adding new page with non-ascii characters in a page field
BitPoet replied to Gideon So's topic in General Support
I've added a few details about the cause of the expection to the issue. In short, the pages.name table is created with an ascii charset by the installer, which should probably be changed. As a workaround, after installation, execute the following statement: ALTER TABLE pages MODIFY COLUMN `name` varchar(128) character set utf8 NOT NULL; (Change utf8 to utf8mb4 if you selected that character set in the installer)