Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by da²

  1. What do you need to understand? $page->author is a Page Reference field that can list multiple authors pages, so authors are stored in a PageArray, a kind of array dedicated in listing ProcessWire pages. So in your loop, $item is a Page instance using the template "author", and the Page class has a property "title" that corresponds to the title filled in this author's page admin.
  2. It's particular to call a function by a string. 99.99 % of the time you have better to do.
  3. In PW admin, create 2 fields of text (simple text or HTML, with appropriate formatter and editor), "my_page_header_1" and "my_page_header_2", go to the template of this page and add the 2 fields, and finally edit the page and fill the texts.
  4. Maybe with URL rewriting? Like a web server rule to transform URL like /concepts/My_Test_File4$$$.pdf/ to /concepts/?fileName=My_Test_File4$$$.pdf So old links are still working.
  5. Hello, Reading the documentation this is the expected behavior: But you can use get parameter: /concepts/?fileName=My_Test_File4$$$.pdf wire()->input->get->text('fileName'); It's maybe better to use an url encoded PDF name with php urlencode(): /concepts/?fileName=My_Test_File4%24%24%24.pdf urldecode(wire()->input->get->text('fileName'));
  6. Hi, This is called Markup Regions, it's targeted to ease templating (like Twig would do but only in PHP): https://processwire.com/docs/front-end/output/markup-regions/ If you use this, prefer to do it with the pw-region tag as it is better optimized (check the documentation). EDIT: I forgot to mention you can disable Markup Regions in site/config.php with $config->useMarkupRegions = false; Then you may also want to disable $config->prependTemplateFile if this file is no longer necessary. But if you want to use regions, you'll find in documentation that you can prepend/append/replace the _main.php tags with tags in templates, to solve the problem you are facing.
  7. Hi, I'm using the same as you, and already reported it to @ryan, you can see his answer here, it looks like he can do something:
  8. An issue fixed, just need to accept this small pull request. 🙂 https://github.com/processwire/processwire/pull/274
  9. That looks good if online documentation has a note on it. 🙂 Thanks for your commitment. 🙂
  10. OK, thanks for the explanations, I understand better your point of view. Yes this project is 3.0.200 using processInput(), here is the class I used, it's basically just a wrapper over InputfieldForm. Since then, I updated this class, because I saw you updated it in the same way (to make InputfieldForm API easier). abstract class TemplateFormManager { /** @var Inputfield $form */ private $form; private string $submitFieldName; function __construct( array $defaultValues = null, string $formAction = "./", string $method = FormMethod::POST, bool $showSubmit = true, string $submitFieldName = "submit_form" ) { $this->submitFieldName = $submitFieldName; $this->form = modules('InputfieldForm'); $this->buildForm($this->form); $this->applyDefaultValues($defaultValues); if ($showSubmit) $this->addSubmit(); $this->form->action = $formAction; $this->form->method = $method; } function render(): string { return $this->form->render(); } function isSubmitted(): bool { $submitName = $this->form->method == FormMethod::POST ? wire()->input->post($this->submitFieldName) : wire()->input->get($this->submitFieldName); return $submitName != null; } function processInput() { $this->form->processInput( $this->form->method == FormMethod::POST ? wire()->input->post : wire()->input->get ); } function getErrorCount(): int { return count($this->form->getErrors()); } function setError(string $fieldName, string $error) { $field = $this->form->get($fieldName); if (!$field) { throw new InvalidArgumentException("Field '$fieldName' doesn't exist!"); } $field->error($error); } /** * Get value of a Inputfield. */ function __get($fieldName) { $field = $this->form->get($fieldName); if (!$field) { throw new InvalidArgumentException("Field '$fieldName' doesn't exist!"); } return $field->attr('value'); } function getField(string $fieldName): Inputfield { $field = $this->form->get($fieldName); if (!$field) { throw new InvalidArgumentException("Field '$fieldName' doesn't exist!"); } return $field; } protected abstract function buildForm(Inputfield $form); private function applyDefaultValues(?array $values) { if ($values) { foreach ($values as $fieldName => $value) { $field = $this->form->get($fieldName); if (is_a($field, "ProcessWire\InputfieldCheckbox", true)) $field->checked($value); else $field->attr('value', $value); } } } private function addSubmit() { $submit = modules('InputfieldSubmit'); $submit->attr('name', $this->submitFieldName); $submit->value = "Valider"; $this->form->add($submit); } } Next one is my current version (PW 3.0.210), you can look at the execute() method, this is where I use the callback method onValidate() to do extra validation in template file. In the previous version above it was coded in a function executeForm() outside of abstract form class. On getErrorCount() method, I'm smiling at my comment "Strange method that gave me strange bugs, I just understand nothing..." 😆 abstract class AbstractForm { protected readonly InputfieldForm $form; protected readonly string $submitFieldName; public function __construct( array $defaultValues = null, string $formAction = "./", string $method = FormMethod::POST, bool $showSubmit = true, string $submitFieldName = "submit_form" ) { $this->submitFieldName = $submitFieldName; /** @var InputfieldForm $form */ $form = modules('InputfieldForm'); $this->form = $form; $this->buildForm($this->form); if ($showSubmit) $this->addSubmit(); $this->form->populateValues($defaultValues); $this->form->action = $formAction; $this->form->method = $method; } public function render(): string { return $this->form->render(); } public function execute( callable $successCallback = null, callable $validateCallback = null, ): int { if ($this->isSubmitted()) { $this->form->process(); // Check errors managed by form. $errorCount = $this->getErrorCount(); if ($errorCount > 0) return $errorCount; // Do extra validation. if ($validateCallback) $validateCallback($this); // Check errors after our extra validation. $errorCount = $this->getErrorCount(); if ($errorCount > 0) return $errorCount; if ($successCallback) $successCallback($this); } return 0; } /** * Strange method that gave me strange bugs, I just understand nothing... */ public function getErrorCount(): int { return count($this->form->getErrorInputfields()); } public function setError(string $fieldName, string $error): void { $field = $this->form->getChildByName($fieldName); if (!$field) { throw new InvalidArgumentException("Field '$fieldName' doesn't exist!"); } $field->error($error); } /** * Get value of an Inputfield. */ public function __get(string $fieldName): mixed { $value = $this->form->getValueByName($fieldName); if ($value === null) throw new InvalidArgumentException("Field '$fieldName' doesn't exist!"); return $value; } public function setValue(string $fieldName, string $value): void { /** @noinspection PhpUnhandledExceptionInspection */ $field = $this->form->get($fieldName); if (!$field) throw new Error("Field $fieldName it not in form."); $field->attr('value', $value); } protected abstract function buildForm(InputfieldForm $form): void; protected function isSubmitted(): bool { /** @noinspection PhpUnhandledExceptionInspection */ return $this->form->isSubmitted($this->submitFieldName); } private function addSubmit(): void { try { /** @var InputfieldSubmit $submit */ $submit = wire()->modules->get('InputfieldSubmit'); $submit->attr('name', $this->submitFieldName); $submit->value = __("Valider", COMMON_TRANSLATION_DOMAIN); // Traduire dans _commonTranslations.php $this->form->add($submit); } catch (WirePermissionException $e) { throw new Error($e->getMessage()); } } } I use it like that in a template: $onValidate = function (AbstractForm $form): void { // Calling a remote API to valid some data // We got an error $form->setError('fieldName', "Don't do that please"); }; $onSuccess = function (AbstractForm $form): void { // Saving user and redirecting to another page }; // Form default values $currentValues = [ 'foo' => $bar ]; $form = new AccountEditionForm($currentValues); $formErrorCount = $form->execute($onSuccess, $onValidate); Twig::render('account-edition', [ 'form' => $form, 'formErrorCount' => $formErrorCount ]); Thank you. Yes this is often necessary. I'm checking errors that are outside of pure form context. Another user had this same issue since 3.0.210, I'm not alone doing this. 🙂 Sometimes I add the namespace, but just to get cleaner imports. I didn't know there is a relation with template compilation, could you explain what's the problem of having my template compiled by PW? I'm gonna add it in PHPStorm template file, so I don't forget it. EDIT: in fact $config->templateCompile was already false by default.
  11. OK, I don't know if this is possible in PW. I searched in source code for "ORDER BY FIELD" but found nothing. Maybe that could be a PW feature request to add selector for ORDER BY FIELD. You can also do the MySQL request using $database API variable, but then you must do yourself values sanitization, and resolving pages references if any. SELECT * FROM table ORDER BY FIELD(id, 5,3,6,1,4,2);
  12. Could you explain the conditions that justify this sorting? Is it static or dynamic? If static maybe you can solve this by manual sorting in PW admin. Then you use "sort=sort" in your selector. If dynamic the only solution I see actually would be like: $sortedIds = [5872, 5869, 5870, 5871]; // List created dynamically $results = $pages->find('id=' . implode('|', $sortedIds)); $sortedResults = []; foreach ($results as $result) { // echo $result->id . "\n"; $nextId = array_shift($sortedIds); if(!$nextId) break; $sortedResults[] = $results->getPageByID($nextId); } var_dump($sortedResults);
  13. So, except if there's a magic trick I'm not aware of, you have to get the pages in correct order from the resulting PageArray, with your own code.
  14. Sorting is managed with "sort" selector. If you want to sort by reverse id: $pages->find('id=4|2|1', sort='-id');
  15. Yes I'll open it if no answer from Ryan. 😉
  16. Hello, Probably a mistake when configuring host. Edit C:\Windows\System32\drivers\etc\hosts and add line: my-project.local.fr Edit xampp\apache\conf\extra\httpd-vhosts.conf and add: <VirtualHost *:80> # Directory that contains index.php DocumentRoot "E:\src-processwire" ServerName my-project.local.fr <Directory "E:\src-processwire"> Options FollowSymLinks Indexes Order allow,deny Allow from all AllowOverride All Require all granted </Directory> </VirtualHost> Restart XAMPP Apache server and go to http://my-project.local.fr/
  17. Is it possible that your provider changed the network configuration? It happened to me few months ago, provider migrated my server to another server rack and then I wasn't able to reach external URLs, a single file_get_contents() to a remote URL wasn't working anymore. Reason was: new network config used IPv6 but it wasn't available. Dunno if your symptoms are compatible with this scenario, but something must have been modified. 🤔
  18. I don't know if that can help you, but on my project, backend side, I hide all pages that a user can't edit, with this hook: /** * In PW admin, hide pages that user can't edit. */ $wire->addHookAfter('Page::listable', function (HookEvent $event) { /* @var Page $page */ $page = $event->object; if ($page->path == "/") $event->return = true; else $event->return = wire()->user->hasPermission("page-edit", $page); }); There is no impact on the frontend side.
  19. Hello, Documentation of this module is here: https://processwire.com/api/ref/textformatter-markdown-extra/ You can do something like: modules('TextformatterMarkdownExtra')->format($text);
  20. Hi, There's not enough information to talk about the issue. It seems the provider changed its API, asking for a cookie that you don't provide. You should check if the API works outside of the form and ProcessWire.
  21. I also can't login in Developer Directory too. Red popup too.
  22. Hi, I'm using PHP 8.2 and 8.1. No issue with Processwire 3.0.210 but you may find issues with third-party modules. For example I recently installed Twig module and it has this minor issue easy to fix.
  23. Hello, I suppose this is due to text domain. You are asking for a translation that has been defined in another file, so to get it you need to specify the text domain of this file. echo __($string, '/site/templates/file_containing_translation.php'); If you want to automatically export translations, I think you should put all translations in a single file, let say it's named _commonTranslations.php: __('translation 1'); __('translation 2'); // And so on... Then when you insert this translations in the template that needs it, you need to specify text domain (you can put it in a constant or create a global function that inserts it automatically): __('translation 1', '/site/templates/_commonTranslations.php'); Note that in PW, you translate this sentences ONLY in _commonTranslations.php. Finally your function looks like that: function echoSnippet($string, $lang) { // Echo the string in english wire('user')->setLanguage(wire('languages')->get('name=en')); echo __($string, '/site/templates/_commonTranslations.php'); // Echo the string in german wire('user')->setLanguage($lang); echo __($string, '/site/templates/_commonTranslations.php'); }
  • Create New...