-
Posts
78 -
Joined
-
Last visited
-
Days Won
1
Everything posted by Inxentas
-
Module Development: Inline Frontend Applications?
Inxentas replied to Inxentas's topic in General Support
Thanks for your replies, dear people! I am going to take a look at the suggested JS libraries / frameworks and see what's most suitable for the application. Your descriptions of Alpine and htmx's features were very helpful. It sounds like Alpine would be something I could learn quite easily, but htmx's SEO advantage might be something I end up liking very much. One last question though: do module developers usually supply the JS code with the module, or do module devs tend to lean on a CDN? Performance and footprint is less important to me, but I like the idea of having the module work "out of the box" without requiring code from a CDN, and offering alternate solutions for client who want custom designs for everything. -
Admin/Login Page 500 Internal Error - Can't login :(
Inxentas replied to orchardheightsdental's topic in General Support
I get this error all the time on my development server. 9 out of 10 times I had simply forgotten to change config.php, and my site would try to access the database using my local config! Could it be that you've accidentally overwritten that file with your local version? I ended up implementing a switch in config.php that checks what domain we're on, and sets the config variables according to the current domain. Should it be an upgrade issue, you can get into some trouble when upgrading through the ProcessUpdate module because the JS files for AdminThemeUikit are missing! I had this issue a while back with a bunch of sites that were suddenly running on PHP8 due to a decision of the hosting provider, and some friendly people on this forum helped me update ProcessWire manually to get around this issue. You can find the topic here. -
I have a pretty broad question about module development. At the moment I have a module (a webshop) which contains some template and class files, which the module will move into the relevant folders (site/templates and site/classes) on install. It will also create a few pages to create the initial page structure, as well as a Process that I place beneath the Admin page. Now imagine that a page with the "product" template contains a form that posts the product ID and a quantity to itself, or another page which then redirects the request. So far so good, that would work. I would like to make it so the module works "out of the box" with some bare-bones templates the developer can modify / style after install. What I am not so sure about is how I'd typically create inline interaction that works "out of the box". On most webshops, a user might click the "add to cart" button and then some Javascript fires, adding the product to the cart through an AJAX call. Now, I could make it so some file (let's call it _webshop.php) is prefixed to a template instead of _main.php, that ensures any Javascript I supply gets loaded on pages that have such interactions. But I am unsure what kind of Javascript to use for AJAX related stuff in the frontend. I would have no issues having the module copy a .JS file into the /template/scripts folder, but I'm unsure on how to structure the JS itself. I've developed apps with Vue3 and (in the olden days) AngularJS or jQuery, but I also see some AJAX interaction in ProcessWire's page tree. Whenever you click on a page that has children, I can see an URL gets called in the Network tab of Chrome's inspector. That means there must already be a methodology the backend uses. Looking at the <head> section of a backend page, I suspect this was done using JQuery. Here is an example url I plucked from the inspector. It's clearly a GET, whereas I would be using POST, but that's just a detail. /page/list/?id=1110&render=JSON&start=0&lang=0&open=undefined&mode=actions Now I am hesitant to use JQuery (as anyone used to Vue would, I reckon). I was wondering if anyone else has ideas on how to best implement frontend AJAX interactions for inline actions, when working in the context of a module? I've considered to write a Vue3 app and simpy have _webshop.php load Vue3 from a CDN, but this feels "messy" to me and not very self-contained. I would also want to prevent introducing a whole Javascript framework, especially when the existing codebase already includes a methodology for AJAX calls. I know this "question" is pretty vague, but I had hoped the community could push me in the right direction. Thank you for reading my post.
-
Yes! Well, not immediately. When I do this to the Process it still gave me an error, but when I used the argument in the lines that delete pages by their template (orders and order pages are deleted first) then it works. I still explicitly delete the individual orders by template before I delete their parent, but I'll experiment a bit with this technique. Again PW surprises me with it's simplicity. One last question: notifications are going to ask me to mark your post as the best solution. But I don't see any options for that. How can I do this?
-
I've tried adding the hooks to the init method. I also used my own module name. This works. public function init() { $this->addHookBefore('Webshop::uninstall', function($event){ $this->deleteProcessChildren(); }); $this->addHookAfter('Webshop::uninstall', function($event){ $this->deleteProcesses(); }); } But alas, even when I explicitly set a BEFORE hook to delete all children... and an AFTER hook to delete the process itself... I still get the same message. Because I get that error, the module isn't truly uninstalled, but it DOES delete the children of the Process page. If I then attempt to uninstall it again, it suddenly works because the previous attempt deleted all children already. But whenever I try to do this in the same request, I get the message that the Process Page still has children, so somehow it's being called too early or something. I've added a $message to the loop that runs through the Process Pages children. As you can see it deletes the "orders" page (second line) before it tries to delete the Process page (last line). Webshop: deleteProcessChildren Webshop: process child deleted: orders Webshop: Deleted 0 Pages. Webshop: Deleted 3 Templates. Webshop: Deleted 5 Fields. Webshop: Permission 'shop-owner' deleted. Webshop: deleteProcesses
-
I've tried this, and put a $this->message() call in the hooked methods for now. They are not called at all. The pages are also not "installed" but created in the API like this: $admin = $this->wire()->pages->get("title=Admin"); $webshop = new ProcessWire\Page(); $webshop->template = "admin"; $webshop->title = "Webshop"; $webshop->icon = "cogs"; $webshop->parent = $admin; $webshop->process = $this; $webshop->save(); $orders = new ProcessWire\Page(); $orders->template = "page-orders"; $orders->name = "orders"; $orders->title = "Orders"; $orders->parent = $webshop; $orders->save();
-
I'm developing a module that installs a couple of nested pages beneat the Admin page (and assigns the module as a Process to them). In the install method, I create these pages from top to bottom. In the uninstall method, I do the reverse and delete all children before deleting their parent page. However, I get the following error message: ProcessWire: ProcessModule: Can't delete Page 1563 because it has one or more children. This is strange as the script makes sure that isn't the case, as these are all deleted. Afterwards, their children are indeed nicely deleted. I've done a couple of checks. When I first delete all children, and use $message to print out $p->children()->count that returns zero, as expected. Yet $p cannot be deleted after confirming it's zero, because "it has children". Does anyone have any idea why? Extra information: Beneath the Admin page I create a new page called "Webshop" and assign my module as a Process to this page. This creates a button in the menu that leads to the primary admin interface of the webshop, for which I use a view. This all works nicely. The module installs a template named "orders" beneath this page, as I was planning to collect webshop orders beneath that one. In the uninstall method, I make sure to first delete all pages of the template "order" and "orders" before I attempt to delete the Webshop Process page. On an unintall attempt, I get above error message, but when I check whether the page it references (1563) indeed has children, these are indeed deleted in accordance with my code. Only the Webshop page remains, and it's Process is (logically) empty.
-
Thank you, that worked flawlessly! I was a bit scared of manually updating 4 production sites this way, but I managed to complete the task without any real issues.
-
Hi guys, I have a few really old sites that never received their updates. ProcessWire version 3.0.62. Now I can install the ProcessWireUpgrade module and run it, but I get some errors: Method AdminThemeDefault::getClass does not exist or is not callable in this context And that's logical considering how old these sites are. At the time we created them, Reno was the default Admin Theme. I have tried installing AdminUIKit by coping a (recent) module into /wire, which gave me another error. I've tried putting the module in /sites, same error. Error installing module - AdminThemeUikit Failed to construct module: ProcessWire\AdminThemeUikit - Method AdminThemeUikit::setClasses does not exist or is not callable in this context --- I have a feeling PW is trying to run a method on the current admin theme, which doesn't exist because it's only in the new admin theme. Can I somehow fix this and update the websites?
-
Moving the vendor folder outside of public_html folders?
Inxentas replied to Inxentas's topic in General Support
For me the SMTP thing is not really negotiable, sometimes companies use some mail setup that requires it. I've used both PHPMailer and the module, and sometimes the module even wins out. Thanks for the "post-install-cmd" tip, that might work well for my situation... being that moving the vendor folder outside of the webroot isn't mission critical. I'm in that situation where I can do whatever I want, but I do have to work with 101 different mail clients and shared hosts so I prefer to add my most used packages to a new project by default. Thanks everyone! -
Moving the vendor folder outside of public_html folders?
Inxentas replied to Inxentas's topic in General Support
I took a look at the WireMail class and what I miss is SMTP support (although I might be wrong here, I simply didn't see anything in the docs that implies SMTP is supported out of the box). I could also use the module named WireMailSMTP for example, but no matter how you cut it that would involve installing the module manually for each website. It's preferable to me to manage dependencies with Composer and reuse our existing mail scripts, then installing PW modules manually for each project. -
Moving the vendor folder outside of public_html folders?
Inxentas replied to Inxentas's topic in General Support
Thank you, I found that article already though, and I found it to be a little messy of a process as well. On top of that I would like to use autoloaded stuff in my modules so that approach isn't super suitable for me. I have decided that for now, I'll just modify the existing index.php as that file won't change too often. -
Hello guys, I've started to implement Composer in my workflow more seriously and I'm looking for the best way to include more then just ProcessWire. We often use a few extra bits and bobs (such as PHPMailer) and I'm not sure how to best treat PW as a Composer package and how to get the vendor folder outside of the public folder. Now whether I do composer require or composer create project, I get PW as a full project including it's own composer.json and .lock files with it's vendor folder sitting next to the wire and site folders. Now I've done some experiments, such as moving the folder manually and changing the require statement in index.php, but that feels messy to me. I've also created a new empty project with my own folder structure, and then copied vendor/processwire/processwire into the public folder for installation, but I still need to faff around with PW's actual code. Is there a neat way to create a Composer project (or inherit the existing one) and use Composer commands to somehow get the vendor folder to sit once directory up from it's default directory?
-
Yes, and that worked perfectly! Thank you @BitPoet. I was hesitant to change the .htaccess file but truth be told, this is kind of a legacy project, so in the end I did not do much research on what that would affect. Are there any PW related issues I should take into account? PS. I received a mail asking me to click a "mark as solution" button. I wanted to mark your reply as the solution but I'm not seeing that button. I fear I'm going blind.
-
Hello there. I have an issue with a PW installation on some crappy shared host. A few days ago the site stopped working. So I checked the error logs, which said: Option FollowSymlinks not allowed here And logically, PW's .htaccess file says: Options +FollowSymLinks So it appears that FollowSymlinks is suddenly no longer allowed on this server. I rarely have to deal with server settings, but is the impression that PW simply needs FollowSymlinks to be allowed. Is this the case? Would it be valid to state that this server isn't suitable for a PW installation anymore, because the host no longer allows SymLinks? Would that statement be correct? I've never had the pleasure of a shared host suddenly no longer allowing SymLinks out of the blue, to be fair I am not entirely sure how those work. I can run the site on my local and test servers just fine: it's just this shared host that's been giving me grief for the last few days. The homepage could be reached but every child page just gave me a serverside 404 (not the 404 you'd expect from PW itself).
-
I have a strange occurence which I have a hard time explaining/debugging. I have a module that contains a .JS file. I load this JS file using a hook, that is called when the template != admin... meaning it will only be called on the frontend. This works on my LIVE environment, but my DEV environment seems to decide to load the file somewhere. Since it contains a script that prevents scrolling, I cannot scroll in the admin. Is there a circumstance in which modules load JS files placed in their folder? Perhaps when it has the same name of the module under certain PHP versions?
-
How to configure InputfieldTextarea properly in a module.
Inxentas replied to Inxentas's topic in Module/Plugin Development
Ah, thanks a lot! I was trying to configure an InputfieldTextarea as one would do in the CMS itself and couldn't get it to render. Using the right class worked very well. -
Hello everyone, Is it possible to use a Repeater in module configuration? I can add one to getInputFields(), like so: // Source Repeater $field = wire('modules')->get("InputfieldRepeater"); $field->columnWidth = 100; $field->attr("id+name", "source_repeater"); $field->label = "Source Text"; $field->icon = "fa-align-left"; But I am at a loss as how to configure the Repeater further. For instance, I've tried making an instance of another fieldtype (FieldtypeText) and adding it to the repeater through code. I want to allow the user to add new entries in this repeater, but want to configure the Repeater field itself entirely through code. I want the admin to be able to add new Repeater items and fill them in. The module should decide what fields to use in the Repeater. When I add the Repeater code above to a wrapper it throws an error, I guess because it needs some fields or further configuration in order to be rendered. Is it absolutely required that I create fields, for instance in the install method of the module, or can I create them on the fly in getInputFields() somehow? How and where should I define the fields of this repeater? Thank you for your time!
-
Hello everyone, I'm trying to write a module configuration by extending ModuleConfig. So far so good. I have a nice wrapper going with some inputfields. One of them is a TextArea that I've added as a field to my config class: $field = wire('modules')->get("InputfieldTextarea"); $field->columnWidth = 100; $field->attr("id+name", "source_text"); $field->label = "Source Text"; $field->icon = "fa-align-left"; I'm trying to make this a field that accepts HTML instead of plain text, so I want it to use CKEditor and set some options. I couldn't find how to configure that so I made myself a custom field through the CMS so I could take a look at how it's constructed. I figured out I could change it's attributes, but this doesn't seem to work: $field->attr("inputfieldClass", "InputfieldCKEditor"); $field->attr("contentType", 1); I'm a bit at a loss as to how I configure this field, since it's part of a module. I've also tried calling getExportData() on the field I made manually, which works and shows the relevant data, but I can't call setImportData() on the $field variable above: this causes an error. I guess because that field isn't saved in the database the way a normal field is. Can I configure module fields to support HTML?
-
How to allow certain Roles to view Processes?
Inxentas replied to Inxentas's topic in General Support
Super, thank you! I couldn't find it in the Process module documentation, but that makes a lot of sense. I'm almost embarrased ? -
My goal is to add a tab at the top of the admin named "tools" under which I want to install a few custom modules. For the Tools tab, I used a page with a ProcessList (so it visually looks like the Templates page). This works perfectly for superusers, but I cannot for the life of me find out how to allow other roles then the superuser to access these pages. I've tried allowing the "admin" templates to be viewed by these Roles, but that doesn't seem to work. Is this actually possible?
-
$config->usePageClasses = true fails on Staging
Inxentas replied to Inxentas's topic in General Support
Ha ha yes, I feel so silly because this isn't the first time this exact issue has caused me to look for the culprit for about an hour, to finally post on a forum in desperation... only to find the bloody typo just 5 minutes later! I'm alwats torn between blaming Windows / MacOS for not being case sensitive and exact enough, or myself for sticking with CamelCase. Thanks for understanding ? -
$config->usePageClasses = true fails on Staging
Inxentas replied to Inxentas's topic in General Support
Typical. Just as I submit the topic, I find the solution. Turns out I just made a CamelCase boo boo with the filename: Defaultpage.php had to be DefaultPage.php. Sorry to waste your time. -
I seem to have some issues with the use of $config->usePageClasses introduced in ProcessWire 3.0.167. I've set it to true so I can use Page Classes. Works perfectly on my own machine, but not on my Staging server. I get the following error: Look out… Error: Exception: Method Page::renderHeading does not exist or is not callable in this context (in wire/core/Wire.php line 544) The method renderHeading() is part of the DefaultPage class. It seems the staging server ignores the classes entirely, as a var_dump() turns out the page is not of the DefaultPage class but the standard Page class. I have no real idea where to look for the issue, does anyone have an idea on how to debug this? The only difference between my Local machine and the Staging server is that it uses a different MySQL database to connect to. Here is the class in full: <?php namespace ProcessWire; class DefaultPage extends Page { /** * Renders a heading based on any title and an optional blurb. * * @param type $title * @param type $blurb * @return string */ public function renderHeading($title, $blurb = null) { $html = ''; $html .= '<div class="content"><div class="layout"><div class="intro"><div class="narrow">'; if ($title != null) { $html .= '<div class="big"><h2>'.$title.'</h2></div>'; } $html .= '<div class="divider"><div class="inner"></div></div>'; if ($blurb != null) { $html .= '<div class="blurb">'.$blurb.'</div>'; } $html .= '</div></div></div></div>'; return $html; } /** * Renders a Project page for the Collection Page grid. * * @param type $col * @param type $row * @param type $project * @return string */ public function renderProject($col, $row, $project) { $html = ''; $html .= '<div class="project project_'.$col.'_'.$row.'">'; $html .= '<a class="inner" href="'.$project->url.'">'; if ($project->image_header) { $html .= '<span class="background" style="background-image:url(\'' . $project->image_header->width(600)->url . '\')"></span>'; } $html .= '<span class="background" style="background-color:rgba(0,0,0,0.2);"></span>'; $html .= '<span class="inner">'; $html .= '<h2>' . $project->title . '</h2>'; $html .= '<div>' . $project->meta_description . '</div>'; $html .= '</span>'; $html .= '<a class="link" href="' . $project->url . '">View</a>'; $html .= '</a>'; $html .= '</div>'; return $html; } } When I add a specific class for the homepage and let it extend DefaultPage... <?php namespace ProcessWire; class PageHomePage extends DefaultPage { } I get the following error: Well well… Fatal Error: Class 'DefaultPage' not found (line 3 of site/classes/PageHomePage.php) It seems the DefaultPage class cannot be found/loaded.
-
No, I simply moved them to a local directory, hoping that would be sufficient. Uploading them via the admin seemed to work, thank you! I'm still curious as to what is the difference (what uploading them via the admin actually does apart from storing the file). I could not find a "translation" system template, did you perhaps mean the language_files_site system Field? That one seems to have an option to allow for overwriting files.