-
Posts
4,928 -
Joined
-
Days Won
321
Everything posted by Robin S
-
Last night a documentary called "Steve Jobs: The Lost Interview" was broadcast on New Zealand television (on Maori Television, which is about the only free-to-air channel worth watching here). Now I am very far from being an Apple fanboy and I knew almost nothing about Steve Jobs going in. I haven't seen any of the biopics from recent years. I was tossing up whether to even turn on the TV but thought I would give it a few minutes. Well, I was glued to the screen throughout and now I completely get why this guy was exceptional. He's obviously very intelligent but you expect that. What blew me away was the clarity of his thinking and the general manner in which he communicates. Here he is answering questions off-the-cuff and the answers he gives are so concise and insightful and just go straight to the crux of the issue. And when he is asked a question about something he hasn't previously clarified his own thinking on he doesn't just blurt something out like normal people - he pauses and thinks and then answers. That is a rare quality. This is 70 minutes of unedited interview but it is fascinating stuff. There are goodies in there for people interested in computer science history, but also highly recommended for anyone with an interest in management or even general self-improvement.
-
Hi @adrian, I struck a problem trying to use bd() inside $sanitizer->pageNameUTF8(). If I add a bd() call to pageNameUTF8() like this... public function pageNameUTF8($value) { bd($value, 'value'); //... ...and then trigger the method like this... $test = $sanitizer->pageNameUTF8('foo'); ...then everything is fine so far and works as expected. But as soon as I add the following to /site/config.php $config->pageNameCharset = 'UTF8'; ...then I get an error: Any idea why this happens?
-
Length of $input->urlSegment() limited to 128 characters
Robin S replied to Johannes Weberhofer's topic in General Support
Welcome to the forums @Johannes Weberhofer It looks like it isn't possible to increase the allowed length of a URL segment. This is because when a URL segment is set, the value is passed through $sanitizer->name() or $sanitizer->pageNameUTF8() depending on if $config->pageNameCharset = 'UTF8' is set. For $sanitizer->name() at least (I had some trouble debugging $sanitizer->pageNameUTF8) the maxLength option defaults to 128, and although that method allows a custom maxLength to be used there is no option to specify this for URL segments. I can't see why a URL segment needs to be limited to 128 characters and it would be nice to have the ability to set a higher max length. Maybe you could open a feature request at GitHub? -
When you deny view access to the guest role you can enter a URL to redirect to. In this field you can use {id} in a GET variable to track which page the user was trying to access.
-
You can do it just as shown here... But instead of hooking after Page::editable you hook after Page::addable.
-
Here is an attempt to simplify things a bit: $wire->addHookAfter('ProcessPageAdd::buildForm', function(HookEvent $event) { $form = $event->return; $template_select = $form->getChildByName('template'); $options = $template_select->getOptions(); $options = array('' => '') + $options; $template_select->set('options', $options); // Set the value to something that will never match an option in the select (any string will do) $template_select->value = 'a'; $template_select->attr('required', 1); }); It's important to set the HTML required attribute (thanks to @abdus for the idea) and to make sure none of the options get the "selected" attribute (hence setting the inputfield value to something that will never match an option). Otherwise if the Add New form is submitted with no actual template selected a nasty error occurs - the core does not allow for the possibility that no valid template ID is included in POST.
-
On the fields that you have set access restrictions for, on the "Access" tab try checking the checkbox shown below:
-
Make variables in _init.php available inside functions in _func.php
Robin S replied to SamC's topic in General Support
Personally, I wouldn't bother with the function. /includes/header.php <?php $metaImage = $page->closest("postThumbnail.count>0")->postThumbnail; if(!$metaImage) $metaImage = $pages(1319)->postThumbnail; ?> <meta name="twitter:image" content="<?= $metaImage->size(1200, 1200, ['upscaling' => true, 'cropping' => 'center', 'quality' => 90])->httpUrl ?>"> -
There are a number of problems here I think. $this->pages->addHookBefore('Inputfield::render', function($event) { You only use $this->pages to add a hook if you are hooking a method of the Pages class. You are hooking a method of the Inputfield class, so you want... $wire->addHookBefore('Inputfield::render', function($event) { Also, you don't need to hook every inputfield render. You are only interested in Checkbox inputfields so just hook the render method of that inputfield class. $wire->addHookBefore('InputfieldCheckbox::render', function($event) { $page = $event->arguments(0); Inputfield::render() and InputfieldCheckbox::render() take no arguments, so $page is not the first argument and you cannot get $page this way. $field = $event->object; The event object is an Inputfield object and not a Field object. It doesn't really matter what you name your variables, but to keep things clear in your head it might help to change this to: $inputfield = $event->object; if('createevents' === $field->name ){ <opinion>Yoda conditions make code less readable and more prone to misinterpretation. The disadvantages outweigh the benefits.</opinion> I would tend to write this hook as: $wire->addHookBefore('InputfieldCheckbox::render', function(HookEvent $event) { if($this->process != 'ProcessPageEdit') return; $page = $this->process->getPage();; $inputfield = $event->object; if(in_array($page->template->name, array('event_businessvacations', 'event_specialbusinesshours', 'event_dates', 'event_events'))) { if($inputfield->name === 'createevents' && !count($page->children)) { $inputfield->attr('disabled' , 'disabled'); } } }); Another tip is that when identifying an inputfield by name, it can be better to check the name of the associated field rather than the inputfield. This is because when an inputfield is inside a repeater its name includes a repeater suffix. Checking the associated field name works in all situations so I prefer that. if($inputfield->hasField == 'createevents' //... Note also the change to the == comparison operator. Not every inputfield has an associated field, so you couldn't be sure that hasField returns an object with the name property if you did: $inputfield->hasField->name === 'createevents' //...
-
Make variables in _init.php available inside functions in _func.php
Robin S replied to SamC's topic in General Support
This is because of variable scope in PHP. Every function has its own internal scope. So this doesn't work: $vegetable = "Beetroot"; function vegetableOpinion() { // $vegetable is undefined in this function's scope return "$vegetable is delicious!"; } echo vegetableOpinion(); But you can pass in $vegetable as an argument to the function so it is available within the function's scope: function vegetableOpinion($vegetable) { return "$vegetable is delicious!"; } // Could be defined in _init.php if you like $vegetable = "Beetroot"; // Pass in $vegetable as an argument to the function echo vegetableOpinion($vegetable); -
When ImageSizerEngineIMagick is installed, the settings defined in the module config screen for quality and sharpening apply and any settings for these in $config->imageSizerOptions are overridden. See discussion here: I'm not a fan of this and would prefer to have quality and sharpening defined in $config->imageSizerOptions.
-
Nice site! I do wonder about this though... I haven't done any research on it or anything, but I have a feeling that hiding the interface while it loads is something that users dislike. As designers/developers we may think it's tidier or slicker, but for the visitor who just wants to start viewing the content it's more boring and frustrating. Similar maybe to how a few years ago designers were hiding the fallback font until the custom webfont loaded, which is now considered a real no-no.
-
Searching for numbers throws Exception: Operator '~=' is not implemented
Robin S replied to joe_ma's topic in General Support
What sort of field is authors_name? A Page Reference field? If so you should be able to match against the title of the referenced page with: authors.authors_name.title%=$q_word I'm curious about the setup of the authors field. The authors field is a Repeater, and then inside that Repeater is a Page Reference field, and the selectable pages of that field contain name fields for the author? Why so complex? Wouldn't it be possible to remove one of these levels and use either a Repeater or a Page Reference field for author? -
FieldtypeBook.info.json: { "title": "FieldtypeBook", "version": "0.0.1", "summary": "Field that stores one or more books with optional metadata.", "author": "Brendon Kozlowski", "icon": "book", "href": "", "permission": [ "" ], "autoload": false, "singular": true, "permanent": false, "requires": [ "PHP>=5.6.0", "ProcessWire>=2.5.28", "" ], "installs": [ "InputfieldBook" ] } The "permission" option here is the problem. Remove all the cases where you are setting items to "" - if you don't need to set a value for an option then simply don't include it in the JSON. { "title": "FieldtypeBook", "version": "0.0.1", "summary": "Field that stores one or more books with optional metadata.", "author": "Brendon Kozlowski", "icon": "book", "autoload": false, "singular": true, "permanent": false, "requires": [ "PHP>=5.6.0", "ProcessWire>=2.5.28" ], "installs": [ "InputfieldBook" ] }
-
Saving a sort order to a Repeater field is trickier than you might expect. This is because the sort order of items in a Repeater field is determined by their sort position under their parent page in Admin > Repeaters > [repeater field] > [container page]. So the "sort" value of each Repeater page in other words. When you do... $page->repeater_field->sort('some_property') ...you are only changing the order of items in the PageArray. This order is never saved to the "sort" value of the individual repeater items. Here is one way you can save the sort order: // Here you order the PageArray how you want it $r_items = $page->repeater_field->sort('some_property'); // BUT, the original keys (indexes) are preserved // So you need to get just the values with new keys // This step could be merged into the line above // Alternatively you could just use a counter variable in the foreach loop $r_items = $r_items->getValues(); foreach($r_items as $index => $r) { // Update the sort value of the repeater page // See: https://processwire.com/api/ref/pages/sort/ $pages->sort($r, $index); } Also, you might be interested in the Page Move and Resort module by @kixe. It has a method... $pages->resortChildren($page, $selectorValue) bool/ null resort children under specified parent based on selector value (sort=$selectorValue) ...which you could use on the parent page of the Repeater items.
-
@alxndre, I just stumbled upon this module and remembered your post - perhaps it is useful to you? https://modules.processwire.com/modules/process-page-list-multiple-sorting/
-
That's certainly doable within a template but not simple. You'd have to parse the URL to extract the video ID, convert it to lowercase, add the "video-" prefix and then match it against the image field. I've used the module within a Repeater several times and personally I prefer having a dedicated image field within the Repeater so I can see the thumbnail right alongside the URL. So much easier to identify the thumbnail that way, both visually within Page Edit and in the template file.
-
get all unique values from a page-field in all pages …
Robin S replied to ngrmm's topic in API & Templates
This isn't quite the same thing. What @ngrmm wants is unique categories (stored within a Page Reference field on each 'xy' page). Also, it is never necessary to do $pages->find($selector)->unique() because a PageArray is automatically unique. -
Maybe I'm missing something, but I don't understand how this can work. If video URLs are entered within a Repeater field then presumably there are multiple videos on the page. So how is the connection between video URL and video thumbnail going to work, given that the sort order within the Repeater and Images field can both be changed independently by the user?
-
Module Visual Page Selector (commercial page picker module for ProcessWire)
Robin S replied to kongondo's topic in Modules/Plugins
I didn't intend any insult - it's just that I've found from conversations with clients and colleagues that people differ in how much they notice design details. I've had conversations with clients where they literally cannot see the difference between typeface A and typeface B, or colour A and colour B. To them, it's just "a font" or "green", and no amount of discussion changes that. For people in our line of work perhaps it depends on what our background or "first love" is: a person who comes to development via design probably sees things differently to someone who comes to design via development. I don't think that at all. But I do think that there is some significance to crossing from free module to commercial module. There's a greater responsibility to ensure that the product is reasonably mature, tested, and fit for purpose. It's only natural that consumers will have higher expectations if they are buying a product as opposed to receiving it for free. Please don't take it that I'm bitterly disappointed in VPS or anything like that because I'm not. It's an awesome product, but one that I feel needs a bit more work in order to be production-ready. My only intention here was to give some constructive feedback. -
// Initialise artist name variable $artist = ''; // Find "work" pages that have this exhibition selected in their "work_exhibition" field // and sort them according to the title (i.e. name) of the artist // Iterate over those works... foreach($pages->find("template=work, work_exhibition=$page, sort=work_artist.title") as $work) { // If the name of this work's artist is different to $artist if($work->work_artist->title !== $artist) { // Then store the artist's name in $artist $artist = $work->work_artist->title; // And output a heading echo "<h3>$artist</h3>"; } // Output the title of the work echo "<p>$work->title</p>"; }
-
In that case: $artist = ''; foreach($pages->find("template=work, work_exhibition=$page, sort=work_artist.title") as $work) { if($work->work_artist->title !== $artist) { $artist = $work->work_artist->title; echo "<h3>$artist</h3>"; } echo "<p>$work->title</p>"; }
-
Module Visual Page Selector (commercial page picker module for ProcessWire)
Robin S replied to kongondo's topic in Modules/Plugins
@kongondo, thanks for the responses. Note how in the modal the Edit view replaces the Add Pages view, with no option to return to Add Pages. Here's what I see when doing the same thing. Chrome, Windows. This is on a clean PW 3.0.80 installation with VPS v0.0.4 and no other modules. I notice your screen capture shows admin theme Reno. You checked with the default admin theme? I would have thought that nearly all new site developments use PW3. I know I have never contemplated building a new site with the old <= v2.7. And most buyers would be using VPS for new projects rather than retrofitting it into old projects that they are not willing to upgrade, wouldn't they? As for the visual details: some people are passionate about this stuff, some people can't see what the fuss is about ("It still works, doesn't it?"). To me, VPS sort of looks and feels like a product that is at a draft stage. I don't mean disrespect by this and I know a lot of work has gone into it, I just was expecting a bit more polish seeing as VPS is presented as a professional commercial product. -
I read your post a few times but wasn't able to grasp exactly how you have this set up. In case it helps, here is how I would tend to approach this... Work template: has Page Reference field for Artist Exhibition template: has Page Reference field for Works Then in your Exhibition template file: $artist = ''; foreach($page->works->sort('artist') as $work) { if($work->artist->title !== $artist) { $artist = $work->artist->title; echo "<h3>$artist</h3>"; } echo "<p>$work->title</p>"; }