Jump to content

Robin S

Members
  • Posts

    5,008
  • Joined

  • Days Won

    333

Everything posted by Robin S

  1. 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 ?>">
  2. 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' //...
  3. 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);
  4. 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.
  5. 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.
  6. 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?
  7. 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" ] }
  8. 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.
  9. @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/
  10. 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.
  11. 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.
  12. 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?
  13. 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.
  14. // 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>"; }
  15. 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>"; }
  16. @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.
  17. 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>"; }
  18. Thanks for the report @adrian. I have fixed this in v0.0.2. Now the Save + Add New button is not added when editing inside a modal, as I don't think it's desirable in those circumstances (another case of this is when editing a field's template context from the template editor).
  19. Does anyone know if there is a way to install a module via the "Add Module From URL" feature if the module is in a private repository? It's a GitLab repository in this case. When I try to do this it fails with: The URL is correct, but no doubt needs authentication to be accessed. Is there a way to supply username/password to allow the download?
  20. You can install the core LanguageSupport module and then "translate" the string for the Default language:
  21. The admin page always has the ID of 2 (as far as I know). So you can get the httpUrl with: $pages(2)->httpUrl()
  22. Another option for adding elements at the end of <head>: $wire->addHookAfter('AdminTheme::getExtraMarkup', function(HookEvent $event) { $parts = $event->return; $parts['head'] .= "<script src='/path/to/script.js'></script>"; $event->return = $parts; });
  23. I'll try that, thanks. Looking at that chunk of code, it's not about setting items to an uninitialised array with $paths[] = $path (which is okay) but if $iter is empty then $paths does not exist.
  24. Yeah, it's a Java app so it's not picky about OS or version.
×
×
  • Create New...