Jump to content

Robin S

Members
  • Posts

    5,007
  • Joined

  • Days Won

    333

Everything posted by Robin S

  1. I don't mind about the sort order if you guys think changing it will be an improvement. Having "Main setup" in the middle seems a bit unusual but not a big deal.
  2. Page::__construct() takes a Template object as an argument: /** * Create a new page in memory. * * @param Template $tpl Template object this page should use. * */ public function __construct(Template $tpl = null) { if(!is_null($tpl)) { $tpl->wire($this); $this->template = $tpl; } $this->useFuel(false); // prevent fuel from being in local scope $this->parentPrevious = null; $this->templatePrevious = null; $this->statusPrevious = null; } So I think the constructor in your child class should be: public function __construct(Template $tpl = null) { parent::__construct($tpl); $this->header = 'some text'; }
  3. As long as the user has edit access for the template, you can use "Additional edit permissions and overrides" at Edit Template > Access:
  4. In the "Selector string" setting for "Selectable pages" you can use "page" to refer to the current page, but only if you also specify a subfield using dot syntax. In your case you would use page.id to exclude children of a parent: template=item, parent!=page.id Unfortunately I don't think this is documented anywhere.
  5. I haven't used it, but I think that is what Croppable Image module is intended for: https://processwire.com/modules/croppable-image3/
  6. Both client-side and server-side resizing strip the EXIF data. If you are able to get the EXIF data with the server-side option then possibly you are hooking before the resize and might be able to access and save the EXIF data then. But in my opinion PW shouldn't be stripping any data from an uploaded image that is to be the "original" from which variations are derived. There's an open issue about this, with fixes for both client-side and server-side resizing (ImageMagick only): https://github.com/processwire/processwire-issues/issues/1055 Just hoping and waiting for it to be applied to the core...
  7. There's an open GitHub issue about this: https://github.com/processwire/processwire-issues/issues/956 Simplest solution for now is to create a different CKEditor field for use in the repeater.
  8. Do you mean that editors are pasting absolute internal links into the link dialog in CKEditor? If so you could try an education approach first, i.e. "Please create internal links via the fields in the link dialog". That way you won't get absolute internal links in the first place. Beyond that you could use a saveReady hook to do a string replacement in the relevant field(s): $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); // Perhaps limit by template as needed if($page->template == 'basic-page') { // Internal links: replace absolute href with relative href $page->body = str_replace('href="https://www.domain.com/', 'href="/', $page->body); } });
  9. Not a solution for you sorry, but I can't reproduce this issue or the other one with the source dialog on a clean PW installation. In such cases the first thing to check is if the issue is reproducible on a clean installation of the latest PW dev version. If it is reproducible then there's a good chance it's a bug and you can create a GitHub issue that describes the steps needed to reproduce the issue. If the issue isn't reproducible on a clean PW installation then it's probably due to a third-party module or some issue with your own code. To isolate the cause you often need to follow a process of elimination. Progressively uninstall modules and remove any customisations you have made until you find the cause. It can be a tedious process but that's just a fact of life when debugging. The Module Disabler panel in Tracy Debugger is an easy way to disable selected modules.
  10. Yes, by appending an asterisk to the field name in "Textarea Definitions".
  11. It looks like PhpStorm doesn't let you override the variable type in a PHPDoc comment when it already knows the type based on the source code. When you get a field value via $page->field_name it is accessed via the __get() magic method, so what PhpStorm is telling you in the case of $this->paymentAmount is actually more accurate than for $payment->paymentAmount, where we are sort of tricking PhpStorm through PHPDoc comments into treating overloaded properties as "real" properties of the Page object. These things aren't fixable issues for the module but are about how your specific IDE understands the code.
  12. Where are you typing "$this"? In a template file? If you have a custom Page class HomePage then in your "home.php" template file you put this line at the top: /** @var HomePage $page */ Then you access any fields or methods of the HomePage class from $page. AutoTemplateStubs gives you code assistance for the fields and the HomePage methods. In a template file $this refers to a TemplateFile object. It doesn't give you access to fields or methods of the HomePage class. If you are typing "$this" in the file for a class that extends Page (e.g. HomePage.php) then you are working in file that this module is not designed to support. But PhpStorm automatically gives you code assistance for methods in the class... ...and even though it wasn't something I had in mind when this module was developed (because custom Page classes didn't exist then) you do get assistance for field names too: If this doesn't answer your question please give me more explanation of what you're wanting to do. Maybe screenshots would help.
  13. I'm not sure I understand. This module is specifically for code hints in template files - it doesn't do anything for any other files you might have in your site. If you are using custom page classes then see the notes in the readme about that, but again this only has an effect on the template file. When you are editing any other class file, module file, etc then this module isn't going to do anything. But PhpStorm should automatically understand the $this keyword in a class context anyway.
  14. There's no built-in option for that, but nearly everything is possible in PW with hooks and some lateral thinking. ? Below is one way you could achieve the goal. In my example I'm using "country" pages under a "countries" parent but the same idea will work for your case of children under the home page. Create a "multiple pages" Page Reference field named "top_pages" and add it to the template of the parent page. The field should be limited to the selection of child pages, so in "Selectable pages" set the "Selector string" option like this: Here "page" is a special keyword that means "the page that is currently being edited". Now edit the parent page and select the child pages you want to be sorted at the top. On the Children tab I have this: So I want the children sorted by title, apart from the children selected in the top_pages field. In /site/ready.php I have the following hooks, which affect the paginated listing of child pages in ProcessPageList: // Before ProcessPageList::find $wire->addHookBefore('ProcessPageList::find', function(HookEvent $event) { $selector_string = $event->arguments(0); $parent = $event->arguments(1); // Return early if the parent page doesn't include the top_pages field, or if the field is empty if(!$parent->hasField('top_pages') || !$parent->top_pages->count) return; // Convert selector string to Selectors object to make it easier to examine and modify $selectors = new Selectors($selector_string); $start = $selectors->get('field=start'); $limit = $selectors->get('field=limit'); // Return early if Selectors object does not conform to what is expected for some reason if(!$start || !$limit) return; // Get start and limit as integers $start_value = (int) $start->value; $limit_value = (int) $limit->value; if($start_value === 0) { // This is the first pagination // Reduce the limit by the count of the top pages $limit->value = $limit_value - $parent->top_pages->count; // Set a custom property on the ProcessPageList object // to indicate that the top pages should be prepended to the children $event->object->add_top_pages = true; } else { // This is not the first pagination // Reduce the start by the count of the top pages $start->value = $start_value - $parent->top_pages->count; } // Set the selector string argument to the string value of $selectors $event->arguments(0, (string) $selectors); }); // After ProcessPageList::find $wire->addHookAfter('ProcessPageList::find', function(HookEvent $event) { $parent = $event->arguments(1); // If there are top pages to add... if($event->object->add_top_pages) { // Prepend the top pages to the children $children = $event->return; $children = $parent->top_pages->add($children); $event->return = $children; // Unset the custom property now that the job is done unset($event->object->add_top_pages); } }); Result: Note: with this approach you must not select more "top pages" than the pagination limit for ProcessPageList (the default is 50).
  15. Check the documentation: So it's an array of matched elements. But you don't need to do anything with it in your case - just return the replacement. You need to pass the variable that is holding the count by reference, as shown in my example.
  16. I think Hanna Code is not a good candidate for solving this need. For a couple of reasons: 1. The Hanna Code textformatter does not necessarily only execute once when are outputting the field value in your template. It executes whenever the formatted value of the field is accessed. In practice I think you'll find this happens (or can happen) more than once in the same request (Ryan has pointed this out somewhere, and you can test it with Tracy Debugger) and so your counter incrementation is not going to be reliable. 2. You will be using the exact same tag [[nextimage]] multiple times within the field value. The Hanna Code textformatter uses a str_replace() to replace all matching tags in the field value. So it doesn't matter how you increment a counter within the Hanna tag code - all identical tags will get the same replacement value. Instead I think you should use your own placeholder and then do your own replacement (either in a template file or in a custom textformatter module). Example... In your field value, use the text {{nextimage}} inside a paragraph by itself. So the resulting markup would be <p>{{nextimage}}</p>. In your template file you can use preg_replace_callback(): $body = $page->body; $images = $page->images; $pattern = '/<p>{{nextimage}}<\/p>/'; $count = 0; $callback = function($matches) use (&$count, $images) { $out = ''; $image = $images->eq($count); if($image) { $out = "<img src='$image->url' alt='$image->title' title='$image->title'>"; } $count++; return $out; }; $body = preg_replace_callback($pattern, $callback, $body);
  17. My comments are about styling the admin, and that's done with CSS. I think you might be talking about making changes to the admin markup - or do I have that wrong?
  18. Sure, the admin theme could make this sort of thing easier. But it's not excessively difficult to tweak the styling now if a person is motivated. When people make comments or requests about the admin theme styling (not just in recent topics but in the forum generally) I'm never sure if they realise that they don't need to wait for Ryan to do something in order to get what they want. It's CSS101 stuff.
  19. Exactly. I doubt we're going to all agree on all details of how the admin theme should look. But I hope that nobody among us is sitting there gritting their teeth because the admin isn't looking how they want it to look. Because we're all website designers/developers and we know how Cascading Style Sheets work (especially the cascading part). And it's not a difficult task to add your own CSS to the admin and override the styling of elements as you like. The admin theme markup changes very rarely and so you can spend half an hour working out your overrides for colours or whatever and then reuse those styles on all projects going forward. If you compile your overrides from SCSS/LESS then it's really easy to tweak colours for specific projects via variables.
  20. Are you doing something like adding the Justify plugin yourself? If so, you don't need to do that because it's already included in PW's InputfieldCKEditor by default. You can specify the individual justify toolbar items you want:
  21. This post might help you: Specifically the Page::editable and Page::addable hookable methods.
  22. My understanding is that there are three hookable methods that you can use if you want detailed control of which pages are viewable, editable and "listable". Viewable = user may view the page on the front-end. Example hook in /site/init.php: $wire->addHookAfter('Page::viewable', function(HookEvent $event) { $page = $event->object; // Return early if PW has determined that the page is not viewable if(!$event->return) return; // Your test here... if($page->title === 'foo') { // User may not view the page $event->return = false; } }); Editable = user may edit the page in ProcessPageEdit. Example hook in /site/init.php: $wire->addHookAfter('Page::editable', function(HookEvent $event) { $page = $event->object; // Return early if PW has determined that the page is not editable if(!$event->return) return; // Your test here... if($page->title === 'foo') { // User may not edit the page $event->return = false; } }); Listable = user can see the page in ProcessPageList. Note: superusers are not affected. Example hook in /site/init.php: $wire->addHookAfter('Page::listable', function(HookEvent $event) { $page = $event->object; // Return early if PW has determined that the page is not listable if(!$event->return) return; // Your test here... if($page->title === 'foo') { // User may not see the page in ProcessPageList // And therefore may not see its descendant pages either $event->return = false; } }); There's a catch to be aware of with this last hook. Page::listable only affects ProcessPageList and not other parts of the admin. If the existence or title of the page must remain private then you'll need to handle the following separately: Admin search (AJAX results) Admin search (results page if user hits enter) Lister (aka "Find") Maybe other places such as Page Reference fields I think @adrian has some experience with hiding pages from these places and might have some suggestions. Edit: In my opinion it would be nice if PW used Page::listable to automatically restrict the visibility of pages throughout the admin. I opened a request here: https://github.com/processwire/processwire-requests/issues/379 Besides Page::viewable, Page::editable and Page::listable there are also the following hookable methods that can be used in a similar way to the examples shown above. All of these methods are in PagePermissions.module. Page::publishable Page::deleteable (aka Page::deletable) Page::trashable Page::restorable Page::addable Page::moveable Page::sortable
  23. @Brian Scramlin, to use WireArray::sort I think the items in the WireArray need to be Wire-derived objects, e.g. WireData. Relevant API documentation: https://processwire.com/api/ref/functions/wire-data/ https://processwire.com/api/ref/functions/wire-array/ Demo:
  24. The json_decode() function has an "associative" argument that you can set to true: $meevo_response_array = json_decode($meevo_response, true); Or you can use the core wireDecodeJSON() function which does this automatically. $meevo_response_array = wireDecodeJSON($meevo_response);
  25. I think you're better off not using FieldtypeCache. See this issue for some discussion: https://github.com/ryancramerdesign/ProcessWire/issues/1577 And I remember Ryan commenting somewhere that he's thinking of removing it from the core. The simplest thing if you want to merge multiple fields into a single field for search purposes is to use the SearchEngine module. Or if you want to go more hands-on it's not difficult to populate a hidden "index" textarea field from other field values using a Pages::saveReady hook. $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); if($page->template == 'your_template') { $index = $page->title; if($page->body) $index .= ' ' . strip_tags($page->body); foreach($page->tags as $tag) $index .= ' ' . $tag->title; $page->index = $index; } });
×
×
  • Create New...