Jump to content

Robin S

Members
  • Posts

    5,008
  • Joined

  • Days Won

    333

Everything posted by Robin S

  1. Hi Adrian, If in an action I try and get a page using the short $pages($id) form of selector then I get a compile error: My demo action: protected function executeAction($options) { $p = $this->pages(1); } If I use get() then it works okay: protected function executeAction($options) { $p = $this->pages->get(1); } Any ideas why the error is happening?
  2. I think you should create a module and share it in the modules directory. ? It sounds like it would be very useful for a number of different languages. If you only want to set the page name once when the page is first created you would hook after Pages::added() and pass the page title to Utf8Slugger::slugify() to get a name. Or if you want the page name to update whenever the title changes you would hook after Pages::saveReady(). For more advanced usages relating to the latter you might like to take a look at the code in @adrian's Page Rename Options module.
  3. On such a large site I reckon it would be worth investing in some professional advice. https://processwire.com/api/modules/profiler-pro/ Besides the tool itself there is the valuable benefit of VIP support from Ryan:
  4. Related issue: https://github.com/processwire/processwire-issues/issues/561 Ryan said: Probably not useful in your case seeing as you have an existing installation but there is the option to choose utf8mb4 from the installer: https://processwire.com/blog/posts/pw-3.0.15/#support-for-utf8mb4-and-innodb Also related:
  5. Maybe you are logged into admin in Safari and not the other browsers? In which case the issue probably relates to something that is accessible to a logged in user (or superuser) but not to guest.
  6. I agree with Adrian - in the future you might get too busy or just want to take a break from developing AOS and then users wouldn't be able to get new features or bug fixes that Ryan applies to the core admin theme. I also think it might turn out to be quite a hassle for you to apply core admin theme changes to your custom theme, because once the methods have been modified you won't be able to see changes easily via a simple diff. You'd have to monitor the core diffs instead and then manually hunt through your custom methods to find the equivalent locations. But once AdminThemeUikit has been the default admin theme for some period of time then I think it would be quite reasonable to say that AOS requires AdminThemeUikit and doesn't support the older themes.
  7. Hi @horst, Not sure if you have already solved this now, but below is a quick demo module. A couple of notes: The Children tab is supposed to AJAX-load automatically when visible, but it's buggy: https://github.com/processwire/processwire-issues/issues/618 I can't remember the details but I seem to recall there might be an issue if the name field is not present in the ProcessPageEdit form. So if you strike problems you may need to move the name field to the Children tab and then hide it. Maybe @adrian knows about the name field issue? <?php namespace ProcessWire; class HideTabs extends WireData implements Module { /** * Module information */ public static function getModuleInfo() { return array( 'title' => "Hide Tabs", 'version' => 1, 'autoload' => 'template=admin', ); } /* @var ProcessPageEdit $ppe */ protected $ppe; /* @var InputfieldForm $form */ protected $form; /** * Ready */ public function ready() { $this->addHookAfter('ProcessPageEdit::buildForm', $this, 'afterBuildForm'); } /** * After ProcessPageEdit::buildForm * * @param HookEvent $event */ protected function afterBuildForm(HookEvent $event) { // Only for ProcessPageEdit (not ProcessUser) if($this->process != 'ProcessPageEdit') return; $this->ppe = $event->object; $this->form = $event->return; $page = $this->ppe->getPage(); // Only for one template (adjust as needed) if($page->template != 'my-template') return; // Remove the unwanted tabs $remove_tabs = [ 'ProcessPageEditContent', 'ProcessPageEditSettings', 'ProcessPageEditDelete', ]; foreach($remove_tabs as $tab_id) $this->removeTabFromForm($tab_id); // Trigger loading of Children tab // Hacky workaround for bug: https://github.com/processwire/processwire-issues/issues/618 $this->form->appendMarkup = " <script> $(window).load(function () { $('#_ProcessPageEditChildren').trigger('click'); }); </script> "; } /** * Remove tab from ProcessPageEdit form */ protected function removeTabFromForm($tab_id) { $tab = $this->form->find("id=$tab_id")->first(); if(!$tab) return; $this->form->remove($tab); $this->ppe->removeTab($tab_id); } }
  8. @pwFoo, here is demonstration module you can use as a starting point. Just install the module and then view "My Page". MyModule.module <?php namespace ProcessWire; class MyModule extends WireData implements Module { /** * Module information */ public static function getModuleInfo() { return array( 'title' => "My Module", 'version' => 1, 'autoload' => true, ); } /** * Init */ public function init() { $t = $this->templates->get('my-template'); if(!$t) return; $t->filename = $this->config->paths->MyModule . 'my-template.php'; } /** * Install */ public function ___install() { $this->createTemplate('my-template', 'My Template'); $this->createPage('My Page', 'my-template'); } /** * Create template */ protected function createTemplate($template_name, $template_label) { if($this->templates->get($template_name)) { $this->warning("Template '$template_name' already exists."); return; } $fg = new Fieldgroup(); $fg->name = $template_name; $fg->add($this->fields->get('title')); $fg->save(); $t = new Template(); $t->name = $template_name; $t->label = $template_label; $t->fieldgroup = $fg; $t->compile = 0; $t->noPrependTemplateFile = true; $t->noAppendTemplateFile = true; $t->save(); $this->message("Created template '$template_name'."); } /** * Create page */ protected function createPage($page_title, $template_name) { $page_name = $this->sanitizer->pageName($page_title, true); if($this->pages->get("parent=/, name=$page_name")->id) { $this->warning("Page '$page_name' already exists."); return; } $p = new Page(); $p->template = $template_name; $p->parent = '/'; $p->name = $page_name; $p->title = $page_title; $p->save(); $this->message("Created page '$page_name'."); } } my-template.php <?php namespace ProcessWire; echo "This is the template file for my-template"; MyModule.zip
  9. The module readme mentions a relevant option: You would set that to false if you don't want entities encoded.
  10. You're missing parentheses. // Save $word->save();
  11. Don't do this part... $p = $word; ...just work with $word directly to change its parent. If it still not working in all cases then focus on the step where you get the parent page: $parent = wire('pages')->get("parent=$page, template=exercise, name=exercise-$number"); There is no guarantee this will always return a valid page, so you might want to check that $parent has an id > 0 and if not log/dump $word->id or something so you can find where the problem is.
  12. It's FileCompiler getting confused by strings containing the name of API variables next to parentheses. GitHub issue: https://github.com/processwire/processwire-issues/issues/98 A moment ago I was seeing the same issue as you for "File (for FormBuilder)", although after making a small edit to the module file (which triggered a recompile) the issue resolved and now I can't reproduce it again even after reverting to the original module file. I also can't reproduce the issue with "TemplateEngineTwig" so not sure what's going on exactly.
  13. I reckon it's a bug. I opened a GitHub issue with a possible fix: https://github.com/processwire/processwire-issues/issues/627
  14. I think you may need a semicolon inside the quotes. config.extraAllowedContent = 'p(tip);'; The CKEditor docs are not 100% clear about when semicolons are needed but you can see them included in some sample code here: https://docs.ckeditor.com/ckeditor4/latest/guide/dev_advanced_content_filter.html#custom-mode
  15. Nothing is required outside of your module - make your module autoload and use the init() method in your module. The filename is not a property that is saved to the database - it is generated at runtime from the template name, so if you want to set a custom filename then this must be done at runtime. The comment in the Template class is clear about this: @property string $filename Template filename, including path (this is auto-generated from the name, though you may modify it at runtime if it suits your need). #pw-group-files
  16. It is possible. I added example code to your GitHub request: https://github.com/processwire/processwire-requests/issues/204#issuecomment-400535558
  17. I haven't needed to use pagefileSecure before, but it sounds to me like a permissions bug relating to the fact that non-superusers have limited access to repeater pages. There have been a few such issues in the past. Unless someone chimes in with a solution I suggest raising a issue in the GitHub repo: https://github.com/processwire/processwire-issues/issues
  18. I use the following in /site/modules/InputfieldCKEditor/config.js to disallow inline styles. CKEDITOR.editorConfig = function( config ) { config.disallowedContent = '*{*}'; // All styles disallowed };
  19. Yes, the handling of form errors is great now, thanks.
  20. Thanks for the info. Hooking ProcessPageView::execute and calling getPage() seems to have negligible effect on response times. The method only executes once per page view, and getting the page object with getPage() method took an average of 0.0015 seconds in my tests. So I'm not too worried about that aspect. I'm not sure what you mean here - it might return the page object for a different page? Or some aspect of the page can be different? This gave me the same ID each time: $wire->addHookBefore('ProcessPageView::execute', function(HookEvent $event) { /* @var ProcessPageView $ppv */ $ppv = $event->object; for($i = 0; $i < 50; $i++) { $page = $ppv->_callMethod('getPage', []); bd($page->id, 'page->id'); } });
  21. @pwFoo, if your page/template/file exists only to give some AJAX response then another approach you could consider is to hook ProcessPageView::pageNotFound. Then you don't need the page/template/file. In /site/init.php: $wire->addHookBefore('ProcessPageView::pageNotFound', function(HookEvent $event) { $url = $event->arguments(1); if($url === '/your-special-url/') { $event->replace = true; $event->return = 'your response'; } });
  22. @pwFoo, note that you will also need to disable FileCompiler for the template. That's because FileCompiler forces the $config->paths->templates path at the start of the filename you set for the template, resulting in an invalid path if you used a full path outside of the templates folder for the filename. See here, here and here. You could open a GitHub issue for this - Ryan may or may not agree that it constitutes a bug.
  23. I'm wondering about the intended or correct use of Wire::_callMethod(). I was tying out a hook to ProcessPageView::execute(), and I wanted to get the Page object that execute() was being called for. ProcessPageView has a getPage() method for that purpose, but it's a protected method so this doesn't work: $wire->addHookBefore('ProcessPageView::execute', function(HookEvent $event) { /* @var ProcessPageView $ppv */ $ppv = $event->object; $page = $ppv->getPage(); // ... }); But then I found Wire::_callMethod(), and this does work: $wire->addHookBefore('ProcessPageView::execute', function(HookEvent $event) { /* @var ProcessPageView $ppv */ $ppv = $event->object; $page = $ppv->_callMethod('getPage', []); // ... }); Is this a correct use of _callMethod()? Is this what _callMethod() exists for? The code comment for _callMethod() is... /** * Call a method in this object, for use by WireHooks * * #pw-internal * ...so the "for use by WireHooks" part sounds like my usage is okay, but the "#pw-internal" and the underscore prefix made me wonder if this method is only intended for use by the core. I couldn't find any mentions in the forum of anyone using it in their own code.
  24. Is this custom login page for front-end users or for users who need to access the PW back-end? If it's for front-end users then I think you don't want them knowing about the core login page at all. You get a bit of extra security if you use a login page name that is not easily guessable (e.g. not "admin" or "processwire") and do not provide links to the core login page from the front-end. Then you only reveal the core login page to users who need to access the back-end. If the login page is for back-end users then I'm not sure why you would not want to use the admin-styled form given that the user is about to be working in the rest of the admin, but you could redirect away from it to your custom login page with a hook in /site/ready.php $wire->addHookBefore('ProcessLogin::execute', function(HookEvent $event) { $this->session->redirect('/your-login-page/'); });
  25. The same code will work in a hook to Pages::delete. Adapted to keep it DRY: // Prevent the trashing/deleting of pages referenced by other pages $pages->addHookBefore('trash', null, 'protectReferencedPages'); $pages->addHookBefore('delete', null, 'protectReferencedPages'); function protectReferencedPages(HookEvent $event) { $page = $event->arguments(0); // Find non-system Page Reference fields $pr_fields = wire('fields')->find("type=FieldtypePage, flags=0"); // Implode for selector string $pr_fields_str = $pr_fields->implode('|', 'name'); // Find any referencing pages $referenced_on = wire('pages')->find("$pr_fields_str=$page->id, include=all"); if($referenced_on->count) { // Replace the trash/delete method $event->replace = true; // Link markup for referencing pages $referenced_on_str = $referenced_on->implode(', ', "<a href='{editUrl}'>{name}</a>"); $plural = $referenced_on->count > 1 ? 's' : ''; // Trigger an error message (using $session in case a superuser is trashing/deleting from ProcessPageList) wire('session')->error("You cannot $event->method page $page->name because it is referenced in a Page Reference field on page$plural $referenced_on_str.", Notice::allowMarkup); // Don't allow the trashing/deleting of this page $event->return = false; } }
×
×
  • Create New...