-
Posts
301 -
Joined
-
Last visited
-
Days Won
4
Everything posted by Kiwi Chris
-
Using Config Migrations with an existing project
Kiwi Chris replied to Kiwi Chris's topic in RockMigrations
It turned out the generated RockMigrations code in the UI didn't use IDs, but it did get confused by me defining fields without prefixes in the UI. I found by deleting the duplicate fields that were not editable via the UI, and renaming the ones I wanted to use in a module to include the prefix, that seems to have got things working as expected. I just need to remember that the file name for the field/template for config migrations needs to be without the prefix, otherwise I'd end up with it double prefixed, and the problem would return. eg. Module called mymodule -> field name in UI = mymodule_myfield but file name with definition in mymodule/RockMigrations/fields needs to be just myfield.php The fields need to be renamed before they're added to a module migration. Template definitions in the migration need to use the full prefixed field names, as the template definition doesn't know or care whether the fields are included in the module migration or are in the site migration. After experimenting a bit more, I've found that having some fields/templates just in the site config migrations is a good compromise. It's better than using a site profile, as you can just copy and paste the fields and templates into an existing project even after initial setup. It's not quite as powerful as having the fields and templates in a module, as that provides dependency checking before installing a module that requires them to exist, but that's unlikely to be an issue in my own projects although it could be if I'm distributing modules that depend on certain fields existing. -
Using Config Migrations with an existing project
Kiwi Chris replied to Kiwi Chris's topic in RockMigrations
This would be the ultimate development tool. I understand how it could be difficult to implement, as I found out the hard way with repeaters that if you save all field properties into a migration file it deletes data when applied. So far I haven't experienced anything so catastrophic with any other field types. I wonder if in a migration for a module at least, that's using config migrations, whether it would be possible to define a watch list of fields and templates so that any time these are changed via the GUI, their individual migration file will be updated? They probably would still need some manual editing to remove unnecessary properties, but a good diff tool can do this quickly. I hadn't spotted that before. Very nice feature to avoid having to remember lots of stuff. I think I can remember 'rmf'. 🙂 What happened here is I defined the fields via the UI as normal fields without any prefix, then copied the definitions from the UI into config migration files. When I installed the module, the fields got created, but with prefixes. I will experiment with renaming the fields and templates in the GUI before I add them to config migrations, and see if this gives me just a single copy of each field and template. Do I still need to follow the convention of site/RockMigrations/templates, site/RockMigrations/fields etc? I made the files in a module because I thought config migrations require a module, but if they work at the site level as well, that might be more appropriate. My migrations probably don't need to be part of a module however I started thinking about a website itself like an object. Even the most basic website will probably have certain fields and templates to be functional. Depending on what else it does, it will need additional fields and templates that extend that base. If I decide I want to refine that base, I can do it in one place and apply it to all sites that use it without having to copy and paste any code if I have it defined in a module. -
I love the concept of config migrations with each field and template having its own file, as it's much more in line with what I'm used to with ASP.Net Core and Visual Studio where you can build some things visually, but still end up with code, and it's also tidier with version control, as fields or templates that don't change are kept separate. Another benefit I see of using config migrations, is that due to module dependencies, unlike site profiles that are all or nothing, it's possible to define a basic set of fields for a site in a module, even if the module doesn't do much other than install fields and templates, and then you have a working site with some base functionality. If you want additional functionality on some sites but not others, but require certain fields or templates to exist before you add the additional functionality, the module dependency can take care of this. eg, I might start off wanting just a basic site, then want to add a blog, but a blog template will use some of the same fields as the basic site, but I don't want to have to redefine them, just be sure they already exist before I install the blog upgrade. The issue I've struck is an existing project that I've defined fields and templates with using the ProcessWire UI, but now I want to bundle some of them up into a module. The scenario is I've started building what I think is a one-off site, then I realise that different components have the potential to be reused on multiple sites, but exporting a site profile is too inflexible. Here's a screenshot of templates after copying and pasting template data from existing templates into config migrations for two new modules and installing them. As you can see there are duplicate templates, the originals with no prefix, and new ones prefixed with the module name. I want to avoid this, but still like using the ProcessWire UI to design fields and templates, because I'm forgetful and can't remember all the properties and what they do, and I find the UI reminds me, but once I've created or updated a field or template, I want to add it to a migration file so that it's easy to update across multiple sites. Would renaming the templates (same thing applies to fields) to the naming convention of config migrations avoid this doubling up? Also, if I edit one of these apparent duplicate fields, I get this: If I edit the actual "animal" template I get all the usual field editing options, with the normal warning that RockMigrations is installed, although in my config file I've got: $config->noMigrate = true; to prevent rockMigrations overriding changes I make via the ProcessWire UI on my development site, although installing the modules still appears to have triggered the config migrations. Ideally I'd like to avoid what looks like two definitions of the same thing, and still have the UI based editing available. What's the best way to achieve this?
-
What I can see using Chrome Devtools, is immediately after the subpage is loaded, there's a jquery call to the execute method. What I think is happening is ProcessPageLister is trying to call it's own execute method to load the list, but instead is loading the execute method of the page it's on, resulting in loading the content from the execute() parent page underneath the lister headers. I've set the code to the same as the example that apparently works but it's still resulting in the same issue.
-
That's weird. I simplified it down to the bare minimum as per the example, and still not working. I wonder if it's some strange third party module interaction? I don't a lot of modules beyond the core loaded, just these: I've tried disabling all autoload modules (other than core) via Tracy debugger, and the problem persists.
-
As per my own use and the linked forum topic, it's possible to render a lister in an execute() method of a Process module without any problem. However, once I try to render it in a sub page of the Process module, eg executePage1() it doesn't render correctly, with only the header of the lister rendering, and then the content of the execute() (not executePage1()) method rendering underneath it. I think there might be some conflict between url segments used by Process modules to identify subpages and lister. It seems like calling the execute() method of the lister is partially working, but then calling the execute() method of the module it's called from after it's rendered its header. I'm using the latest build of ProcessWire. Is it possible to have a lister render in a subpage of a Process module? If not, are there any alternatives to display a lister predefined in module code?
-
New blog: FormBuilder v57 released (5 September 2025)
Kiwi Chris replied to ryan's topic in News & Announcements
Really pleased the documentation is included with the main documentation. It would be great to have the documentation for all the pro modules that allow API access included in the same way. ListerPro sort of is, as it extends lister. Although all Pro modules are mentioned on the site, they're not necessarily in the API reference even if they can be accessed via the API. Also there's not a single page that lists all built in fieldtypes and pro fields that can offer additional functionality. I'd really like there to be a page like this: https://docs.umbraco.com/umbraco-cms/fundamentals/data/data-types/default-data-types (In addition to PHP, I also work with .Net and Umbraco is the closest thing to ProcessWire I've found in that space.) Thinking as a developer, one of the first things I want to know when I'm evaluating a platform is 'What can it do out of the box?'. If I've got to jump around amongst multiple webpages to find out then I immediately start losing interest. I'm happy to contribute to ProcessWire by helping with documentation if that would be useful. -
The issue I have is pages that are not publicly viewable, but are viewable only to people with a specific role. AdminRestrictBranch works fine with regard to restricting editing access, but as you mention, it doesn't work for frontend access. Because the criteria I want to use to restrict view access are the same as what I want to restrict edit access, I figured extending the module functionality with my own custom code for view access would be a practical way to meet my needs, but I haven't figured out how to apply the code so that it doesn't block view access to admin pages as well. It's probably a selector thing. I'm not even sure if this is the right thread to ask, but seeing as the functionality I want extends what the module already does, I thought it would be a good place to start, case anyone else needed to do similar.
-
I'm not sure whether this comes under the scope of this module or not, but I want to be able to not just restrict viewing/editing of branches of the page tree, but actual page views as well. I discovered that if you use the search box: Even if a page is within a branch that is restricted from a user in the page tree, they can still view it. I tried adding another hook: $this->wire()->addHookAfter('Page::viewable', $this, 'hookPageViewable'); and this: protected function hookPageViewable($event) { // in case there is already a defined exclusion for this user's role for this page if (!$event->return) return; if ($this->wire('user')->hasPermission('page-view')) { $event->return = $this->onAllowedBranches($event->object); } else { $event->return = false; } } But the end result is that admin menus that the user could previously view are hidden, so it's now working TOO well. What I want is for pages that aren't viewable or editable from the page tree aren't viewable from search either.
-
ProcessWire can never be WordPress with its famous fast install, precisely because of ProcessWire's flexibility. The appeal has to be to developers, or designers who know a little code, but don't want to have to get stuck into learning a lot of code. I think with more site profiles, using popular CSS frameworks to enable easy customisation, ProcessWire could maybe grab some of those WordPress users, as the installation process is quick and easy, it's just the customisation that takes time, and if there's a profile that meets your needs, it's as quick to get a site up as WordPress. It's when you need anything else WordPress is horrible. Maybe there needs to be an option for paid site profiles? One of the issues with profiles is that they're applicable at install time only, but via something like RockMigrations it would be possible to have a profile like a blog profile, but then multiple migration files that can theme the same data differently. I wonder whether rather than calling things site profiles, calling them ProcessWire apps might better convey what they are - or not? I think the key message I'd be wanting conveyed to other developers and potential clients is 'build anything - fast'. Much as I dislike Wordpress, it's claim to fame, 'build a blog - fast' it actually can deliver on pretty well. It's when you try to build anything else with it that it starts getting horrible. Incidentally, I just took a look at wordpress.org, and if I didn't know any better, visually comparing that to ProcessWire, I'd choose WordPress. It starts off quickly summarising what it does, then with a bit of scrolling gives a bunch of screenshots of the diversity of things people have build with it. The only call to action on the ProccessWire site is 'download', and mostly impersonal, whereas wordpress.org is full of personal calls to action: 'Get', 'Meet', 'Discover', 'Explore' ... The site uses some similar large fonts and a lot of visuals, but the above the fold content gets to the point quickly. The big stuff comes after scrolling. Since I'm being critical, I'm happy to write something and send it through for evaluation, as I have benefited from the ProcessWire community. I'm not a designer, or probably even really a marketer, but I I do have a bit of interest in language, and I think the text could be significantly improved to be more compelling. Here are a couple of examples of how I'd rewrite things: Save time and work your way with ProcessWire, a free content management system (CMS) and framework (CMF). Enjoy all custom fields, a secure foundation, proven scalability and performance. Take control over the design You can define and edit all fields in ProcessWire easily in the admin. You can create as many of them as you want, and of any type. You can even bundle them in repeatable groups called Repeater fields. You control all of the markup, not ProcessWire. If I want to sell end users on ProcessWire I want to show them it can be as pretty as WordPress and more capable. Luckily here in NZ I can just refer them to the portfolio site of @Robin S as he's done a number of high profile sites that are well known nationwide, and I can say 'built using the same system', and also reassure them that I'm not the only ProcessWire developer out there. (It helps that I'm a regular visitor to several of the sites he's built too.)
-
Is there any way to adjust the font size to personal preferences? I'm finding headings way too big on my screen resulting in unnecessary scrolling to read anything. The animated heading at the top bring back not particularly fond memories of the <blink></blink> tag. I suspect it may be mobile first, but if I'm accessing the site it's for documentation, and I'm not going to do that on a phone. One of the things I've loved about ProcessWire is it's fairly well documented, but if I have to do extra scrolling every time I want to reference docs because everything is so much bigger, that's not helpful. I realise other people may like the new design, and I don't want to impose my preferences on others, but honestly I can't say I'm comfortable with the new presentation. Sorry, I know lots of work has gone into this. It's why I'm asking, following the ProcessWire philosophy of allowing total flexibility, whether actual site visitors themselves can have some option to select default font sizing, so those who like it big can keep it that way, but those who'd like it smaller can have something more to their liking.
-
With regard to the documentation, it would be quite good to have newer features that have been mentioned in this weekly update or blog posts incorporated in the main documentation. Possibly also some of the pro modules stuff, as at the moment documentation is scattered around either in the forum or on the shop pages to purchase the pro modules. While it makes sense for discussion to be in the forum for people with up to date subscriptions, having documentation in one place might be a help, and might even convince people to buy pro modules if documentation for how they can use them is available. I notice with Lister Pro, there is some documentation in the API reference under Lister with core lister methods and properties and Lister Pro methods listed together but pro methods and properties identified.
-
Further to what @wbmnfktr said, I think ProcessWire can be described as a low code data designer. You still need a front end developer to build public facing pages, but potentially someone with no backend development skills can build a complex range of templates for different data. In more complex scenarios, yes, it might be necessary to write some modules or hooks, but a huge amount can be done without writing a single line of code, but later, if people want to package up and subject to source control, there are third party modules like RockMigrations that allow taking all the field and template definitions and storing them as migrations files. In a sense, ProcessWire in this respect is like a headless CMS of which there are a few out there that allow custom data design without coding. But wait there's more. ProcessWire can be used as a no code/low code headless CMS, but it also assumes that you'll want to output the data somehow, and give you all the tools to do it, without being opinionated. If you just want to output fields directly into HTML template files with some simple PHP codes, fine, you can do it. If you want to output as API calls and use a javascript frontend framework, you can do it. (Not a core feature, but there is a third party module to enable it) If you want to use a templating language, you can do it. (also via third party modules, or use your own)
-
Software for quickly estimating project cost/duration?
Kiwi Chris replied to bernhard's topic in Pub
Sounds like a new module coming. RockEstimator. 😁 -
What options are there to autosave individual page fields both in normal pages and repeaters? I see there's a page Auto Save in pro dev tools, but I'm not sure if this is what I need? There's also a commercial module by Kongondo - dynamic selects, but that requires creating a new field of type dynamic select, rather than existing fields, and I'm not sure whether it allows autocomplete rather than dropdowns, so it's not ideal. Mainly my use case is to handle dependent page fields, where one page field depends on the value of another one. I'm aware of the ability to create selectors that refer to other fields on a page, but this doesn't work as required in all scenarios. I know the API allows saving individual fields and can do so silently if necessary. Having the ability to specify individual page fields that should autosave via ajax when they're updated would be extremely helpful. Where this would be particularly useful would be with page Autocomplete input fields, as I've worked out how to hook input to pass the calling page to the hook, for custom selectors, but this only works with current values already saved to the page, so being able to combine this with the ability to autosave specified page fields would help with complex dependencies. For some fields this functionality might be unnecessary or undesirable, so being able to configure it on a per field with per template override as with other field properties would be ideal. Has anyone implemented anything like this, or does the pro page Autosave module do this?
-
As someone who writes about as much C# as PHP, ? to indicate nullable parameters is familiar, although if they'd put the ? after the parameter type, it would have meant not having to remember a different position depending on language. At least we don't have to put another upside down question mark at the end of the parameter, for probably the majority of us who don't have Spanish keyboards. 🙂
-
Thanks, that seemed to be the issue. I had included other criteria that I overrode in the hook. For the record, this seemed to do the trick: id!=page.id, template=stockItem One of the annoyances with findReady is it doesn't give you the page that called it, but including id!=page.id is pretty broad and covers anything other than the calling page, which isn't usually going to reference itself. With this selector, I can pretty much do everything I could otherwise with getSelectablePages, so I can filter on any page criteria without needing to include them in the selector string. I was trying to have some parameters both in the selector string and override them.
-
Not sure whether it's a bug, an inherent limitation of hooking findReady, or that I need to hook some other code as well, but I've found that while hooking findReady can allow me to modify the list of selectable pages for page Autocomplete inputfield for page fields without problem, on save, the data is not saved, and editing the page or reloading always comes up with blank data. This is a scenario where I've provided a selector string in the input tab of the admin UI to configure the field, and then use the findReady hook to read data from this string and modify it to return the correct page list. Not sure if anyone else has experienced this, or come up with a solution?
-
Welcome to the 50s. And nice to know that @Robin S is so prolific. I sometimes get asked by clients what happens if I have a collision with a proverbial bus, and it's a really good selling point to be able to say there's another Kiwi (what we New Zealanders call ourselves after our national bird - not a fruit) who's a major contributor to the system I use for most of my sites, and who's also developed some quite high profile national sites with it. I suppose I should get a move on and write some modules, but I guess it's testimony to the ProcessWire ecosystem that I haven't needed to as yet (well I have, but they're for specific client business processes, so not something I can release publicly.) Speaking of broadening horizons and geography, even though Robin is on the same island as me, we're at opposite ends, and he's at least a 12 hour drive away. I know I shocked my mother-in-law when she came here, because her idea of an island was that there'd be sea all around, and I took her on a trip that involved very full days with 3 or 4 days without ever seeing the coast.
-
Thanks for this. It probably shouldn't be too hard to adapt Ryan's InputfiledFormBuilderRecaptcha to use Cloudflare as well. I just read an article today stating that bots can now defeat pretty much all of those visual captchas that ask to identify what squares contain a given object, so this is quite timely.
-
I've been having a bit of a struggle converting a page reference field from Select to Autocomplete, as with Select, it's possible to hook getSelectablePages, and the actual page the inputfield is on is available to the hook, but with autocomplete, you have to hook findReady, and the page the field is on is not passed to the hook, only the name of the field, which then looks up the selector string from the field definition. None of the hook arguments include the calling page, however $event->argument(0) gives the selector string, and in the field definition it is possible to include some page fields in the selector string in the field definition. eg: The problem is, typically these will affect the pages returned, but I realised that if I added at the START of the selector string in the field definition id!=page.id that will have no influence on the pages returned, as I'm not likely to want a circular reference with a page referring to itself in a page reference field, but this will provide the actual calling page id that requested the page autocomplete. Since the selector string is just a comma delimited list, it's easy enough to convert this to an array, and if I have id!=page.id as the FIRST selector parameter it's easy to get it like so: $selector = $event->arguments(0); $selectors = explode(',', $selector); $pageSelector = explode('=', $selectors[0]); $page = wire('pages')->get($pageSelector[1]); Now that I have the actual page that the autocomplete is on, I can do things beyond what is possible with the selector string in the field definition. In my case I wanted to do this: $owner = $page->parent('template=client'); //Get ancestor page with given template and retrieve a field value from it to use in selector I can then rewrite the selector string as desired. I suppose in theory it would be possible to not use the selector string in the field definition as a selector string at all, but rather as a way of passing parameters to the hook, and then just build your own selector string in the hook. I hope this helps others who've struggled with figuring out where ProcessPageSearch::findReady is being called from. It won't necessarily work for all situations but should work when called from page autocomplete. Edit: I discovered that ProcessWire adds other selectors after the last selector in the selector string in the field definition, so it's really important that id!=page.id is the FIRST parameter in the selector string in the field defintion, unless you like searching arrays. If you make it first, you just need to explode the search string, get the first array element, explode that again, and you've got the page id.
-
What I'm trying to do is restrict a list for a page reference to pages with template of moveStockItem, that are pulled in from an external API, so I don't have control over the fields in that template, as they just replicate what's in the external API. In that template productVintage is a numeric field, but that's fine, as no one ever edits it manually. That's why I need to use a selector that matches productVintage = item.vintage.title, because in the repeater, users do need to select a vintage, and providing a page reference field helps restrict them to a sensible range. Hooking ProcessPageSearch::findReady seems like an option, but it does seem to be quite messy. With a select list it's easy to hook InputfieldPage::getSelectablePages and that works ok, but switching to autocomplete for the page reference field makes things harder. with autocomplete, I've found using a selector string rather than a hook works fine if the dependency and the dependent fields are on a normal page rather than a repeater, however if both the dependent field and its dependency are in the repeater, that's where things get messy. In the example I'm trying to get working, this part: clientCode%=page.createdUser.clientCode does work, so I seem to be able to reference a field from the page with the repeater field in it ok. I double checked by adding an additional section to the selector to check that page.id refers to the id of the page the repeater field is on, and not the repeater itself, and it does refer to the parent page, not the repeater. I've done some further checking, and although in the thread I linked to previously Ryan says that item should refer to fields in the repeater, in this case it is returning the page the repeater is on. I'm not sure if this is a bug, or an inherent limitation of using find for the autocomplete option?
-
I've found this thread: Apparently I need to use item. rather than page. to refer to a field within the repeater field. Looks like the inline documentation needs some improvement. Still haven't got it working, but think I'm heading in the right direction. The problem I'm getting is in Tracey Debugger, I can see that the selector query is not getting any value for either page.vintage.title or item.vintage.title, it's just blank.
-
Does this work with autocomplete? The examples look like they're using a standard select list. I can already do this via a hook in ready.php, but I've specifically been asked to provide autocomplete rather than select lists, and the code that works for select lists does not work with InputfieldPageAutocomplete.