-
Posts
5,039 -
Joined
-
Days Won
340
Everything posted by Robin S
-
@alan, you might be better off using a mod_rewrite rule than using Redirect, because then you can use the [L] flag to avoid the other rewrite rules affecting the URL. So instead of... Redirect 301 /my-short-cut http://example.com/the/long/page/to/go-to/#theAnchorIwant ...try... RewriteRule ^my-short-cut$ http://example.com/the/long/page/to/go-to/#theAnchorIwant [R=301,NE,L] ...just after... RewriteEngine On
-
How do you mean? The test is if the user doesn't have the permission then the contenteditable attribute does get removed.
-
@gmclelland, turns out it is a piece of cake with str_replace. Create a custom permission "rename-images" and give that to roles that you want to allow to rename images. Then add the following to /site/ready.php $wire->addHookAfter('InputfieldImage::renderItem', function(HookEvent $event) { if(!$this->user->hasPermission('rename-images')) { $event->return = str_replace(" contenteditable='true'", "", $event->return); } });
-
Sure, but I suspect that if you look at the code that creates the inputfield markup there will be nothing hookable that lets you change that attribute in isolation. And it might be a long time before such a thing gets implemented in the core given the number of existing feature requests. Often you just have to do what you can to solve this kind of thing yourself. Edit: if there's nothing else in the inputfield with the contenteditable attribute apart from the name fields you might be able to do a string replace on the markup returned from InputfieldImage::render to strip out that attribute. Pretty hacky but no more so than the JS approach I guess.
-
An idea on how you could achieve this: Add a body class in admin according to the user's role: This has also been added to AdminOnSteroids if you are using that. Then add a custom javascript to ProcessPageEdit that selects .InputfieldImageEdit__name inside a particular body class and removes the "contenteditable" attribute from the inner <span>. You'd put this into a function and have it fire on domready and ajaxcomplete events.
-
@gmclelland, I just figured it out by clicking around as you replied. Cool, I had no idea that was possible!
-
How do you rename images through the admin UI? I wasn't aware that was possible.
-
The login details for your superuser account must be coming from somewhere. One place they might be coming from is your browser in the form of a saved login. Do you get the same problem if you access this page from a different browser that has never been used to login to your superuser account? In this line here... if(/* !$user->isLoggedin() && */ $input->get->confirmcode && $input->get->confirmcode == $session->get("confirmcode")){ ...I see that the check to make sure the user is not already logged in is commented out. So I wonder if you might already be logged in as superuser at this point. Does your header or footer contain a login form that might be getting auto-filled with your superuser login details?
-
I don't think WireException is involved there. What you are seeing is a fatal error message from PHP, and you can't "catch" a fatal error AFAIK.
-
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.